Elf regels

Arjen Markus (23 december 2002) Inspired by Einfach Tcl and Einfach man Tcl by Richard Suchenwirth I decided to translate the manual page (aka Endekalogue) and Richard's overview of Tcl into Dutch.(Pascal Scheffers was kind enough to comment on my translation)


De navolgende tekst is een vertaling van de originele Tcl(n) manpage. Ik heb net als Richard mijn eigen commentaar (of de vertaling van Richards commentaar) als cursieve tekst toegevoegd. Ik heb de originele tekst naar eer en geweten vertaald, maar de oorspronkelijke bewoordingen blijven natuurlijk van kracht.

De syntax en semantiek van de scripttaal Tcl worden gedefinieerd door de volgende elf regels:

1. Een Tcl-script is een string die een of meer opdrachten bevat. Opdrachten worden van elkaar gescheiden door puntkomma's en nieuwe regels, tenzij deze zijn omgeven door aanhalingstekens of dergelijke (zie het vervolg). Vierkante haakjes "sluiten" beëindigen een opdracht tijdens de opdrachtsubsitutie, tenzij er "escape-karakters" zijn.

Een script kan staan in een scriptfile die op zijn beurt naar andere scriptfiles verwijst. Een script kan daardoor een zeer complex geheel worden, maar ook zoiets simpels als:

   puts "Hallo, John"

Een opmerkelijk aspect van Tcl is dat een script bestaat uit Unicode-karakters, en niet beperkt is tot de gewone ASCII-tekens, zonder dat je daar als gebruiker/programmeur veel van merkt. Of beter: zonder dat je daar last van hebt. Je kunt daarom betrekkelijk gemakkelijk werken met niet-westerse talen als Japans of Arabisch.

2. De interpretatie van een opdracht geschiedt in twee stappen. Eerst splitst de Tcl-interpreter de opdracht in woorden en voert daarna de substituties uit die hieronder nader zijn omschreven. Het eerste woord dient als identificatie van de aan te roepen opdrachtprocedure en alle andere woorden worden daaraan doorgegeven als "argumenten". Het is aan de opdrachtprocedure om deze argumenten te interpreteren, bijvoorbeeld als een getal, een variabelenaam of een lijst of een ander Tcl-script. Voor de verschillende procedures betekent een argument dus steeds iets anders.

Deze simpele regel heeft vergaande gevolgen. Ten eerste zorgt deze ervoor dat het aantal argumenten voor een opdrachtprocedure onafhankelijk is van de substitutiestap. (Dit is in tegenstelling tot UNIX-shells en DOS-batchfiles). Ten tweede is hiermee ook vastgelegd dat Tcl een "prefix"-notatie kent, net als LISP. Echter, omdat elke opdrachtprocedure zijn eigen betekenis kan hechten aan de argumenten, is de mogelijkheid open gehouden voor "minitalen", als reguliere expressies of formats.

3. De woorden van een opdracht zijn gescheiden door spaties of tabs, maar niet door het einde van een regel. (Het einde van een regel vormt een scheiding tussen twee opdrachten).

Tcl trekt zich er niets van aan welke karakters op een bepaald platform precies het einde van een regel vormen. Zowel de DOS-conventie als de UNIX- conventie als de MacOS-conventie worden - door elkaar - herkend. Dit geldt ook bij het inlezen van databestanden!''

4. Als het eerste karakter van een woord een aanhalingsteken is ("), dan wordt dit woord afgesloten door het eerstvolgende aanhalingsteken. Karakters als de puntkomma, de spatie, vierkante haak sluiten (]), de tab en zelfs het einde van een regel verliezen hun speciale betekenis. Opdrachtsubstitutie, variabelesubstitutie en "backslash"-substitutie worden wel onverkort uitgevoerd. De aanhalingstekens worden niet bewaard.

Aanhalingstekens worden dus gebruikt om woorden te groeperen tot een enkel woord, net als UNIX shells en DOS batchfiles/opdrachten. Echter, dit heeft geen gevolg voor de betekenis van waarden zonder spatie: "foo" en foo zijn voor wat betreft Tcl identiek.

5. Als het eerste karakter van een "woord" een accolade openen ("{") is, dan wordt het "woord" pas beëindigd met een bijpassende accolade sluiten ("}"). Accolades kunnen genest worden: voor elke nieuwe accolade openen moet er een accolade sluiten zijn (dit geldt niet voor accolades binnen een woord die met een "backslash" ("\") zijn beschermd - deze tellen niet mee voor het nesten). Er worden geen substituties uitgevoerd op de karakters binnen de accolades, behalve "backslash-nieuwe-regel" zoals hieronder beschreven. Ook puntkomma's, het einde van de regel, sluithaken of spaties en tabs hebben geen speciale betekenis binnen de accolades. Het "woord" bestaat uit exact die karakters die zich tussen de buitenste accolades bevinden, maar zonder die accolades.

Kort en krachtig: accolades zeggen - alles hoort bij elkaar, verder niets mee doen. Omdat er tussen de accolades weer allerlei opdrachten kunnen staan (die op dat moment nog niet uitgevoerd worden) kun je steeds ingewikkelder structuren opbouwen. De voorbeelden bij uitstek zij de "body" van een subroutine en de uit te voeren onderdelen van if/for/foreach/while.

6. Als een "woord" een vierkante haak openen ("[") bevat, dan voert Tcl opdrachtsubstitutie uit. Hiertoe roept het - recursief - de Tcl interpreter aan om de karakters te verwerken die volgen op de vierkante haak. Het script mag een willekeurig aantal opdrachten bevatten en moet afgesloten worden met een vierkante haak sluiten ("]"). Het resultaat van het script (dat wil zeggen, het resultaat van de laatste opdracht) wordt ingevoegd in plaats van de oorspronkelijke vierkante haken en alle karakters ertussen. Er is geen beperking aan het aantal van dergelijke substituties in een enkel "woord". Er wordt geen opdrachtsubstitutie uitgevoerd in "woorden" die door accolades worden omsloten.

De vierkante haken zijn vergelijkbaar met de achterwaartse apostrofe () in UNIX shells - prompt="pwd`:>"

7. Als een "woord" een dollar-teken ("$") bevat, wordt variabelesubstitutie toegepast. Het dollar-teken en de daarop volgende karakters worden vervangen door de waarde van een variabele. De substitutie kan de volgende vormen aannemen:

$name

name is de naam van een scalaire variabele; de naam bestaat uit een aangesloten reeks van letters, cijfers en underscores ("_").

$name(index)

name is de naam van een arrayvariabele en index is de naam van het element binnen die array. name bestaat ook hier uit een aangesloten reeks van letters, cijfers en underscores ("_"). Opdrachtsubstituties, variabelesubstituties en backslash-substituties worden overkort op index toegepast.

${name}

name is de naam van een scalaire variabele. De naam mag willekeurig welke karakters bevatten, behalve een sluithaak ("}"), omdat hij daardoor begrensd wordt.

Het aantal variabelesubstituties binnen een "woord" is onbeperkt. Variabelesubstitutie wordt niet toegepast op "woorden" die door accolades worden omsloten.

Deze regel zegt niets over de manier waarop arrays binnen Tcl gebruikt kunnen worden, namelijk als hashtables. Een kleine omissie in de bovenstaande regel is het gebruik van twee actereenvolgende dubbele punten om "namespaces" aan te duiden.

8. Wanneer er een backslash ("\") optreedt binnen een "woord", dan treedt backslash-substitutie op. In alle gevallen behalve die die hieronder worden beschreven, verliest het karakter erna zijn eventuele bijzondere betekenis. Dit stelt je in staat om aanhalingstekens, accolades en dollar-tekens letterlijk op te nemen in een "woord". De backslash wordt niet opgenomen.

De navolgende tabel geeft aan welke karakters na een backslash een bijzondere behandeling krijgen:

\a Hoorbaar alarm (piep, ASCII 0x7)

\b Backspace (0x8)

\f Volgende bladzijde (form feed, 0xc)

\n Nieuwe regel (0xa)

\r Naar beginpositie (carriage return, 0xd)

\t Horizontale tab (0x9)

\v Verticale tab (0xb)

\(einde regel)(spaties, tabs) Een enkele spatie vervangt de backslash, het einde van de regel en alle daarop volgende spaties en tabs. Merk op dat deze vorm van substituties een aparte bewerkingsslag is die wordt uitgevoerd voordat het script daadwerkelijk wordt geanalyseerd. Dit betekent dat de substitutie ook plaats vindt binnen accolades en dat de spatie wordt beschouwd als een scheidingsteken, tenzij omsloten door aanhalingstekens of accolades.

\\ Backslash

\ooo De cijfers ooo (een, twee of drie cijfers) worden beschouwd als een acht-bits octaal getal dat aangeeft welk Unicode-karakter moet worden ingevoegd. De hoogste bits worden op 0 gezet.

\xhh De hexadecimale cijfers hh worden beschouwd als een acht-bits hexadecimaal getal dat aangeeft welk Unicode-karakter moet worden ingevoegd. De hoogste bits worden op 0 gezet. Er mag een willekeurig aantal cijfers worden gegeven, maar alleen de laatste twee bepalen het uiteindelijke karakter.

\uhhhh De hexadecimale cijfers hhhh (een, twee, drie of vier cijfers) vormen een 16-bits hexadecimaal getal dat aangeeft welk Unicode-karakter moet worden ingevoegd. (Hiermee besla je de volgende range van de Unicode-karakters)

Backslash-substitutie vindt niet plaats binnen "woorden" omsloten door accolades, behalve de backslash-einde regel.

9. Als een "hekje" ("#") voorkomt op een punt waar Tcl het eerste karakter van het eerste woord van een opdracht verwacht, dan wordt het hekje plus alle karakters die erop volgen tot aan de volgende regel beschouwd als commentaar. Dit wordt verder genegeerd. Het commentaarkarakter heeft alleen betekenis wanneer het aan het begin van een opdracht voorkomt.

De precieze behandeling van commentaar zorgt nogal eens voor een onverwachte valkuil: eigenlijk is commentaar een gewone opdracht en moeten accolades openen corresponderen met accolades sluiten. Accolades en een backslash hebben op een commentaarregel dus een betekenis! (Hier kun je gebruik van maken, onder UNIX, om tclsh of wish op te laten starten alsof het gewone command shells waren. Zie de relevante Wiki-pagina's - Tcl/Tk Template Applications bijvoorbeeld)

10. Elk karakter in een script wordt door de Tcl interpreter maar een keer behandeld als onderdeel van een "woord'. Bij voorbeeld, als er variabelesubstitutie wordt uitgevoerd, dan wordt er verder geen substitutie meer toegepast op de waarde van de variabele, de waarde wordt letterlijk overgenomen. Als er opdrachtsubstitutie optreedt, dan wordt de geneste opdracht uitsluitend afgehandeld via een recursieve aanroep van de interpreter. Er worden geen substituties uitgevoerd voor of na deze aanroep.

11. Substituties beinvloeden de grenzen tussen woorden of het aantal woorden voor een opdracht niet. Bijvoorbeeld, bij de variabelesubstitutie wordt de gehele waarde van de variabele onderdeel van een woord, zelfs als die waarde een of meer spaties bevat.

De eerste en de laatste twee regels zorgen voor het zeer gelijkmatige karakter van een Tcl script: wat voor waarden je ook invult, je weet wat het aantal argumenten is voor een opdracht en je weet wat die argumenten zijn. Er zijn opdrachten, zoals eval, die de Tcl interpreter dwingen om een nieuwe analyse uit te voeren. Dan is uiteraard wel de waarde van een variabele van belang - dat is namelijk het doel van deze opdrachten.