تی‌سی‌ال کیست؟ توضیح بده.
زبان Tcl (مخفف Tool Command Language - زبان کنترل ابزار) حاصل تحقیقات John Ousterhout روی ابزارهای رایانه‌ای طراحی مدارهای الکتریکی در دانشگاه برکلی است. در این تحقیقات، Ousterhout و دانشجویانش مجبور بودند برای هریک از این ابزارها یک زبان کنترل جداگانه طراحی کنند، اما به دلیل توجه بیشتر به خود ابزار (و نه زبان)، ابزارها عموماً دارای زبان‌های کنترل ضعیفی بودند.در پاییز سال ۱۹۸۷، در آزمایشگاه شرکت DEC، این ایده به ذهن Ousterhout رسید که یک زبان فرمان قابل جاسازی(Emdeddable Command Language) طراحی کند. یک زبان مفسری (Interpreted) خوب که بتواند به عنوان یک بسته کتابخانه‌ای در برنامه‌های گوناگون استفاده شود. هدف این بود که مفسر زبان مجموعه‌ای از امکانات اولیه را (مانند متغیرها و ساختارهای کنترلی) فراهم آورد و هر یک از ابزارهای استفاده‌کننده از آن بتوانند ویژگی‌های مورد نظر خود را به آن اضافه کنند.Ousterhout در سال ۱۹۸۸ پس از بازگشت از آزمایشگاه DEC، کار بر روی Tcl را شروع کرد و نخستین نسخه آن را در یک متن پرداز (Text Editor) گرافیکی به کار گرفت. در ابتدا این کار فقط جنبه تحقیقاتی داشت و Ousterhout گمان نمی‌کرد دیگران هم به استفاده از آن علاقه‌مند باشند.فلسفه زبان.نیاز به امکان جاسازی (Embeddability) قابلیت ویژه زبان Tcl است و به گفته Ousterhout باعث می‌شود که اهداف زیر برای زبان در نظر گرفته شود:نوآوری‌ها.مهمترین نوآوریهای Tcl عبارتند از قابلیت جاسازی و آسانی تولید واسط کاربر گرافیکی.با ایجاد قابلیت جاسازی، مشکل بسیاری از افرادی که نیاز به یک زبان دارند، اما نمی‌خواهند یک زبان کامل را از ابتدا طراحی کنند حل شده است. به دلیل آسانی جاسازی Tcl در سایر برنامه‌ها، استفاده از آن در اوایل دهه ۹۰ به سرعت رشد کرد.قابلیت دیگر Tcl، مجموعه ابزار Tk است که به عنوان گسترشی بر Tcl تولید شد و امکان ایجاد واسط کاربر گرافیکی با استفاده از ادغام مؤلفه(component)ها را به وسیله Tcl فراهم آورد. این قابلیت نیز به امکان استفاده از Tcl برای تولید برنامه‌های بزرگتر و با واسط کاربر مناسب افزود و در کسترش استفاده از آن سهم به سزایی داشت.کاربردها.برخی از کاربردهای Tcl به شرح زیر است[۱]:علاوه بر کابردهای فوق، کاربردهای دیگر تحقیقاتی از Tcl نیز مشاهده شده‌است. به عنوان مثال در سیستم‌های رباتیک از زبان Tcl استفاده شده‌است[۴]. همچنین این زبان در توسعه سریع نرم‌افزار (Rapid Application Development) نیز استفاده شده‌است[۵].بررسی زبان شناختی (ساختار و نحو زبان).برنامه‌های Tcl تشکیل شده‌اند از دستورهایی که با semicolon یا با رفتن به خط جدید (newline) از هم جدا شده‌اند. هر دستور از تعدادی کلمه تشکیل شده‌است که با فاصله از هم جدا شده‌اند.همهٔ دستورهای Tcl مقدار برمی‌گردانند. اگر برگرداندن مقدار برای دستوری معنا نداشته باشد، یک رشتهٔ تهی برمی‌گرداند.متغیرها.در Tcl نیازی به تعریف متغیر نیست. هر متغیری در اولین دفعه استفاده آن، تعریف می‌شود. همچنین متغیرها در Tcl دارای نوع نیستند. هر متغیری می‌تواند هر مقداری بگیرد[۱]. البته می‌توان با استفاده از دستور variable اقدام به تعریف متغیر در یک فضای نام (علوم رایانه) کرد[۳].با استفاده از دستور set می‌توان مقادیر را در متغیرها ذخیره و از آن‌ها بازیابی نمود.برای ذخیره :set x ۳۲برای خواندن مقدار :set xبرای استفاده از مقادیر یک متغیر از روش «جایگذاری متغیر» به شکل زیر استفاده می‌شود:expr $x+3این دستور مقدار x+۳ را برمی‌گرداند.هنگامی که یک علامت دلار در عبارت ظاهر می‌شود، Tcl حروف و اعداد پس از آن را به عنوان نام متغیر تعبیر می‌کند و مقدار آن متغیر را به جای نام آن می‌گذارد[۱].جایگذاری متغیر را می‌توان برای همه کلمه‌های یک دستور Tcl، مستقل از این که آن کلمه یک نام دستور یا یک آرگومان است، به کار برد؛ مثلاً عبارات زیر معادل عبارات قبلی است:set a exprset x ۳۲$a $x+3ساختارهای کنترلی.Tcl مجموعه کاملی از دستورهای کنترلی شامل دستورهای اجرای شرطی، دستورهای حلقه و دستورهای زیربرنامه‌ای را دارد. دستورهای کنترلی Tcl دستورهایی عادی هستند که به عنوان آرگومان، اسکریپتهای Tcl می‌گیرند[۱]. به عنوان مثال دستور proc که برای تعریف زیربرنامه به کار می‌رود، سه آرگومان می‌گیرد: نام زیربرنامه، لیست نام پارامترهای آن، و بدنه زیربرنامه که یک اسکریپت Tcl است:proc power {base p} { set result 1 while {$p&gt; ۰} { set result [expr $result * $base] set p [expr $p - 1] return $resultمشابها دستور while که در بالا مشاهده می‌شود، یک دستور Tcl است که دو آرگومان می‌گیرد: یک عبارت که همان عبارت شرط است و یک بدنه که یک اسکریپت Tcl است.از این زیربرنامه می‌توان به شکل زیر استفاده کرد:power 2 6power 1.15 5دستورها و عبارت‌ها.همهی امکانات اساسی Tcl به وسیله دستورها نمایش داده می‌شوند. حتی عبارات نیز به وسیله اجرای دستورهای و به عنوان خروجی آن‌ها محاسبه می‌شوند.قالب معمول دستورهای Tcl به شکل زیر است [۲]:command arg1 arg2 arg۳ …...دستورهای Tcl به سه دسته تقسیم می‌شوند [۱]:چنان‌که گفته شد عبارات در Tcl به وسیله اجرای دستور ارزیابی می‌شوند. به عبارت دیگر مفسر Tcl خود عبارات را ارزیابی نمی‌کند، بلکه تنها عمل دسته‌بندی آرگومانها، جایگذاری مقادیر و فراخوانی دستور را انجام می‌دهد. به همین دلیل در Tcl از دستور expr برای ارزیابی عبارات ریاضی استفاده می‌شود[۲].دستور expr با آرگومانهای خود به شکل عبارت ریاضی برخورد می‌کند[۱]. این دستور با عبارات ریاضی، شامل اعداد صحیح، اعشاری و مقادیر منطقی (boolean) سر و کار دارد. قواعد حاکم بر عبارات expr همان است که بر عبارات در زبانC حاکم است[۲]. به علاوه دستور expr برخی توابع اولیه ریاضی را نیز پشتیبانی می‌کند. به عنوان مثال [۲]:set len [expr [string length foobar] ]که مقدار طول رشته foobar را (که برابر با۶ است) محاسبه می‌کند و:set pi [expr {۲*asin(1.0)}]که مقدار عدد pi را محاسبه می‌کند.زبان Tcl مقادیر درون علامت نقل قول (” ”) را ارزیابی و به جای عبارات درون آن مقادیر لازم را قرار می‌دهد. به قراردادن یک عبارت در آکولاد ({ }) می‌توان از این کار جلوگیری کرد:set name Ali”My name is $name”دستور دوم مقدار My name is Ali را برمی‌گرداند در حالی که دستور سوم مقدار My name is $name را برمی‌گرداند.رشته ها[۲].رشتهها واحد اساسی داده در Tcl هستند و به همین دلیل است که دستورهای زیادی برای کار با آن‌ها وجود دارد.دستور string مجموعه‌ای است از عملیات قابل انجام بر روی رشته‌ها. نمونه‌ای از این عمل را در مثال بالا در بحث عبارتها مشاهده می‌کنیم. اولین آرگومان این دستور نام عملی است که باید انجام گیرد. برخی از اعمال مجاز عبارتند از:bytelength, compare, equal, first, index, is, last, length, map, match, range, repeat, replace, tolower, totitle, toupper, trim, trimleft, trimright, wordend, wordstartTcl امکاناتی را برای کار با اندیسها در رشته‌ها فراهم می‌کند. کاراکترها در رشته از ۰ شمرده می‌شوند. به عنوان مثال دستور زیر کاراکترهای سوم تا آخر رشته با نام name را برمی‌گرداند؛ مثلاً اگر name حاوی مقدار ahmadi باشد:string range $name 3 endمقدار adi را برمی‌گرداند.برخی از اندیسهای قابل استفاده در این دستورهای عبارتند از:first, last, wordstart, wordendهمچنین دستور string امکاناتی را برای بررسی تطابق یک رشته با یک رشته دیگر و نیز تعلق یک رشته به یک کلاس خاص (مثلاً عدد بودن محتویات یک رشته) فراهم می‌کند.Tcl همچنین دستورهایی مانند append, scan, format, binary را برای عملیات پیشرفته روی رشته‌ها فراهم می‌کند.توضیحات (Comments).در زبان Tcl از علامت # برای مشخص کردن توضیحات برنامه استفاده می‌شود. هر توضیح یک خط را اشغال می‌کند. برای توضیحات چند خطی می‌توان از قراردادن \ در پایان هر یک از خطوط استفاده کرد[۲]. در زیر مثال‌هایی از توضیحات Tcl مشاهده می‌شود.and here is the rest of the line aboveلیست‌ها.یکی از قابلیتها در زبان Tcl، امکان کار با لیستهاست. برخی از دستورهای کار با لیستها عبارتند از[۲] :list, lindex, llength, lrange, lappend, linsert, lsearch, lreplace, …لیستها در Tcl دارای دو کاربرد عمده هستند [۳]:البته لیستها وسیله مناسبی برای ساخت دادهساختارهای پیچیده در Tcl نیستند و برای چنین کاری استفاده از آرایه‌ها مناسبتر است [۲].یک نمونه از کاربرد دستورهای لیست در Tcl در زیر آمده‌است[۳]:Bob Carol٪ set c۲ [list Ted Alice]Ted Alice٪ set Party1 [list $c۱ $c2]٪ set Party2 [concat $c۱ $c2]Bob Carol Ted Alice٪ linsert $Party1 1 Richardآرایه‌ها.آرایه یک متغیر Tcl با اندیسهای رشته‌ای است. می‌توان به اندیس به چشم کلید و به آرایه به دید مجموعه‌ای از عناصر که به وسیله کیلد قابل شناسایی هستند نگریست[۲]. از این نظر، می‌توان گفت آرایه‌های Tcl مانند Hashها در زبان Perl هستند [۳]. قابلیت انعطاف آرایه‌ها آن‌ها را به ابزاری مهم برای برنامه‌نویسی در Tcl تبدیل می‌کند. یکی از استفاده‌های مهم آرایه‌ها در Tcl ایجاد دادهساختارهای پیچیده‌است که در زبان‌هایی مثل C و Pascal به وسیله مفاهیمی مانند struct و record تعریف می‌شوند[۲].در زیر نمونهای از کاربرد آرایه‌ها در Tcl دیده می‌شود[۳]:٪ set People(friend) TomTom٪ set People(spouse) MarciaMarcia٪ set People(boss) JackJack٪ array names Peoplefriend boss spouse٪ set Person $People(friend)Tom٪ array get Peoplefriend Tom boss Jack spouse Marcia٪ set People(friend) \[concat $People(friend) Bob]Tom Bob٪ set Person $People(friend)Tom Bobزیربرنامه‌ها و محدوده‌ها.چنان‌که گفته شد زیربرنامه‌ها امکان کپسولهسازی (encapsulation) دستورهای در قالب یک دستور را فراهم می‌کنند. زیربرنامه‌ها همچنین یک محدوده(scope) محلی برای متغیرها ایجاد می‌کنند[۲].در آغاز، Tcl دارای یک محدوده سراسری (global) برای متغیرها، محدوده‌های محلی درون زیربرنامه‌ها و یک محدوده سراسری برای زیربرنامه‌ها بود. از Tcl ۸٫۰ به بعد محدوده-نام‌ها به Tcl اضافه شد که محدوده جدیدی برای زیربرنامه‌ها و متغیرهای سراسری به وجود می‌آورد. نکته دیگر آنکه زیربرنامه‌ها و متغیرها دارای محدوده-نامهای جدا هستند بنابراین می‌توان بدون ایجاد مشکل، متغیر و زیربرنامه همنام داشت[۲].متغیرهای تعریف شده در هر زیربرنامه، تنها در همان زیربرنامه قابل دسترسی و استفاده هستند. به علاوه متغیرهای سراسری در حالت عادی در برنامه‌ها قابل استفاده نیستند و برای استفاده از آن‌ها باید به شکل صریح (explicit) و با استفاده از دستور global آن‌ها را به سیستم معرفی کرد. همچنین متغیرهای تعریف شده در بلوکهای بالاتر نیز به حالت عادی در بلوک درونیتر قابل استفاده نیستند و باید به وسیله دستور upvar آن‌ها را به سیستم معرفی کرد[۳].نمونه‌هایی دیگر از تعریف زیربرنامه‌ها، به همراه شیوه استفاده از دستور upvar در زیر آمده‌است[۲]:proc RandomInit { seed } { global randomSeed set randomSeed $seedproc Random {} { global randomSeed set randomSeed [expr ($randomSeed*۹۳۰۱ + ۴۹۲۹۷) ٪ ۲۳۳۲۸۰] return [expr $randomSeed/double(233280)]proc RandomRange { range } { expr int([Random]*$range)که حاصل اجرای آن به این صورت است :RandomInit [pid]=&gt; ۵۰۴۹Random=&gt; ۰٫۵۱۷۶۸۶۸۹۹۸۶۳Random=&gt; ۰٫۲۱۷۱۷۶۷۸۳۲۶۵RandomRange ۱۰۰=&gt; ۱۷به عنوان نمونهای از استفاده از دستور upvar می‌توان به پیادهسازی پشته با استفاده از لیست اشاره کرد[۲]:proc Push { stack value } { upvar $stack list lappend list $valueproc Pop { stack } { upvar $stack list set value [lindex $list end] set list [lrange $list 0 [expr [llength $list]-2]] return $valueکه در آن stack$ حاوی نام متغیر لیست دارای اطلاعات stack است که در بیرون از محدوده زیربرنامه قرار دارد و به عنوان پارامتر به برنامه فرستاده و تبدیل به یک متغیر قابل استفاده در زیربرنامه شده‌است.سایر امکانات[۲].از جمله سایر امکاناتی که زبان Tcl فراهم می‌کند می‌توان به موارد زیر اشاره کرد:نمونه برنامه‌های کامل Tcl.در زیر نمونه‌هایی از برنامه‌های کامل Tcl آورده شده‌است. نمونه اول یک اسکریپت کنترلی برای برنامه شبیهسازی Modelsim است و دستورهای افزوده شده به Tcl توسط برنامه Modelsim در آن به خوبی مشهود است:set benchRoot $۱set testRoot $۲set testsAddr $۳set benchName $۴set testName $۵set destAddr $benchRootfile delete -force $testRoot/tsourcefile copy -force $benchRoot/$benchName $testRoot/tsourcevsim -voptargs=+acc work.tbleonadd wave sim:/tbleon/tb/p0/leon0/resetnadd wave sim:/tbleon/tb/p0/leon0/clkadd wave sim:/tbleon/tb/p0/leon0/pllrefadd wave sim:/tbleon/tb/p0/leon0/plllockadd wave sim:/tbleon/tb/p0/leon0/errornadd wave sim:/tbleon/tb/p0/leon0/addressadd wave sim:/tbleon/tb/p0/leon0/dataadd wave sim:/tbleon/tb/p0/leon0/ramsnadd wave sim:/tbleon/tb/p0/leon0/ramoenadd wave sim:/tbleon/tb/p0/leon0/rwenadd wave sim:/tbleon/tb/p0/leon0/romsnadd wave sim:/tbleon/tb/p0/leon0/iosnadd wave sim:/tbleon/tb/p0/leon0/oenadd wave sim:/tbleon/tb/p0/leon0/readadd wave sim:/tbleon/tb/p0/leon0/writenadd wave sim:/tbleon/tb/p0/leon0/brdynadd wave sim:/tbleon/tb/p0/leon0/bexcnadd wave sim:/tbleon/tb/p0/leon0/sdckeadd wave sim:/tbleon/tb/p0/leon0/sdcsnadd wave sim:/tbleon/tb/p0/leon0/sdwenadd wave sim:/tbleon/tb/p0/leon0/sdrasnadd wave sim:/tbleon/tb/p0/leon0/sdcasnadd wave sim:/tbleon/tb/p0/leon0/sddqmadd wave sim:/tbleon/tb/p0/leon0/sdclkadd wave sim:/tbleon/tb/p0/leon0/saadd wave sim:/tbleon/tb/p0/leon0/sdadd wave sim:/tbleon/tb/p0/leon0/pioadd wave sim:/tbleon/tb/p0/leon0/wdognadd wave sim:/tbleon/tb/p0/leon0/dsuenadd wave sim:/tbleon/tb/p0/leon0/dsutxadd wave sim:/tbleon/tb/p0/leon0/dsurxadd wave sim:/tbleon/tb/p0/leon0/dsubreadd wave sim:/tbleon/tb/p0/leon0/dsuactadd wave sim:/tbleon/tb/p0/leon0/testonbreak {resumerun -allonbreak ""dataset open $benchRoot/$benchName/gold.wlfecho Golden Version Opened for comparison!compare start gold simcompare add gold:/tbleon/tb/p0/leon0/resetncompare add gold:/tbleon/tb/p0/leon0/clkcompare add gold:/tbleon/tb/p0/leon0/pllrefcompare add gold:/tbleon/tb/p0/leon0/plllockcompare add gold:/tbleon/tb/p0/leon0/errorncompare add gold:/tbleon/tb/p0/leon0/addresscompare add gold:/tbleon/tb/p0/leon0/datacompare add gold:/tbleon/tb/p0/leon0/ramsncompare add gold:/tbleon/tb/p0/leon0/ramoencompare add gold:/tbleon/tb/p0/leon0/rwencompare add gold:/tbleon/tb/p0/leon0/romsncompare add gold:/tbleon/tb/p0/leon0/iosncompare add gold:/tbleon/tb/p0/leon0/oencompare add gold:/tbleon/tb/p0/leon0/readcompare add gold:/tbleon/tb/p0/leon0/writencompare add gold:/tbleon/tb/p0/leon0/brdyncompare add gold:/tbleon/tb/p0/leon0/bexcncompare add gold:/tbleon/tb/p0/leon0/sdckecompare add gold:/tbleon/tb/p0/leon0/sdcsncompare add gold:/tbleon/tb/p0/leon0/sdwencompare add gold:/tbleon/tb/p0/leon0/sdrasncompare add gold:/tbleon/tb/p0/leon0/sdcasncompare add gold:/tbleon/tb/p0/leon0/sddqmcompare add gold:/tbleon/tb/p0/leon0/sdclkcompare add gold:/tbleon/tb/p0/leon0/sacompare add gold:/tbleon/tb/p0/leon0/sdcompare add gold:/tbleon/tb/p0/leon0/piocompare add gold:/tbleon/tb/p0/leon0/wdogncompare add gold:/tbleon/tb/p0/leon0/dsuencompare add gold:/tbleon/tb/p0/leon0/dsutxcompare add gold:/tbleon/tb/p0/leon0/dsurxcompare add gold:/tbleon/tb/p0/leon0/dsubrecompare add gold:/tbleon/tb/p0/leon0/dsuactcompare add gold:/tbleon/tb/p0/leon0/testcompare runcompare saverules $destAddr/$testName-$benchName-comprules.savonerror {echo Hurray! No Differences Found!!;resumecompare savediffs $destAddr/$testName-$benchName-compdiffs.savecho Comparison complete!quit -sim;dataset close goldنمونه دوم یک برنامه ping ساده است که در محیط لینوکس اجرا می‌شود[۶]:frame .buttons -borderwidth 10pack .buttons -side top -fill xbutton .buttons.quit -text Quit -command exitbutton .buttons.ping -text Ping -command Pingpack .buttons.quit .buttons.ping -side rightframe .f ; pack .f -side toplabel .f.l -text Host:entry .f.host -width 20 -relief sunkenpack .f.l .f.host -side lefttext .log -width 60 -height 10 -bd 2 -relief raisedpack .log -side topproc Ping {} { set hostname [.f.host get] catch {exec /usr/sbin/ping $hostname} result .log insert end $result .log insert end \nبه عنوان نمونهای دیگر می‌توان برنامه تبدیل فایل‌های Dos به Unix را مشاهده کرد[۱]:proc Dos2Unix {f} { puts $f if {[file isdirectory $f]} { foreach g [glob [file join $f *]] { Dos2Unix $g } else { set in [open $f] set out [open $f.new w] fconfigure $out -translation lf puts -nonewline $out [read $in] close $out close $in file rename -force $f.new $fforeach f $argv { Dos2Unix $fمنابع./MPR/MPR02.pdf