The Tcl Syntax

[Sun Home | Tcl Plugin | Demos]

For a scripting language, Tcl has a very simple syntax. Here it is:

cmd arg arg arg
A Tcl command is just formed by words that are separated by white space. The first word is the name of a command, and the rest of the words are arguments to the command.
The $ is used to get the value of a variable. In this case the variable name is foo.
[clock seconds]
Square brackets are used to execute a nested command. For example, if you want to pass the result of one command as the argument to another you use this syntax. In this example, the nested command is clock seconds, which gives the current time in seconds.
"some stuff"
Double quotes are used to group words into a single argument to a command. Dollar signs and square brackets are interpreted inside double quotes.
{some stuff}
Curly braces are also used to group words into a single argument. In this case, however, no interpretation is done on the things inside the braces.
Backslash is used to quote some special characters. \n generates a newline, for example. Backslash is also used to turn off the special meaning of dolar sign, quotes, square brackets, and curly braces.

A Little Example

Below is a Tcl command that prints out the current time. It uses three Tcl commands: set, clock, and puts. The set command does variable assignment. The clock command manipuates time values. The puts command prints values.

set seconds [clock seconds] puts "The time is [clock format $seconds]"

The seconds variable isn't really needed in the example. You could do it with one command:

puts "The time is [clock format [clock seconds]]"

Grouping and Substitution

The Tcl syntax is used to guide the Tcl parser through two steps:

  1. Argument grouping. Tcl just needs to decide how the arguments to the commands are organized. In the simplest case, white space separates arguments. The quotes and braces syntax is used to group multiple words into one argument. In the previous example double quotes are used to group a single argument to the puts command.
  2. Result substitution. After the arguments are grouped, Tcl performs string substitutions. This just means it replaces $foo with the value of the variable foo, and it replaces nested comamnds with their result. The fact that substitutions are done after grouping is crucial. It means that funny values do not mess up the structure of commands.
  3. Command dispatch. After substitutions Tcl uses the command name as a key into a dispatch table. It calls the C procedure identified in the table, and the C procedure actually implements the command. You can also write command procedures in Tcl. There are simple conventions about argument passing and handling errors.

Another Example

Here is another example.

set i 0 while {$i < 10} { puts "$i sqared = [expr $i*$i]" }

Here we see curly braces used to group arguments without doing any substitutions. What's really going on is that the Tcl parser knows nothing special about the while command. It treats it like any other command. The braces group two arguments, the boolean expression that controls the loop, and the commands in the loop body. It is the implementation of the while command that knows that the first argument is an expression, and the second argument is more Tcl commands.

We also see two math expressions: the boolean comparison, and the multiplication. In Tcl you use the expr command to do math evaluation. There are other commands, like while, that treat some of their arguments as expressions, too.

Command Dispatch

The final thing Tcl does is call someone else to do all the hard work. We've seen that it uses expr to do math, puts to do output, and set to do variable assignment. These Tcl commands are all implemented by a C procedure that has registered itself with Tcl. The C command procedures take the string arguments from the Tcl command, and they return a new string as their result. It is very easy to write C command procedures, and there are lots of them that do everything from accessing databases to creating graphical user interfaces. Tcl, the language, doesn't really know what the commands do. It just groups arguments, substitutes results, and dispatches commands.

One Last Example

Here is the factorial procedure.

proc fac {x} {
    if {$x <= 0} {
        error "Invalid argument $x: must be a positive integer"
    } elseif {$x == 1} {
        return 1
    } else {
        return [expr $x * [fac [expr $x-1]]