5. Command Language

Crafter Spacecraft Design Program

Crafter is implemented in the Tcl/Tk environment. Tcl is a simple scripting language for controlling applications. Tcl ("tool command language") has generic programming constructs such as variables, loops and procedures, and may also be extended to include more commands. The Tk toolkit is an extension to Tcl that provides easy development of graphical user interfaces under the X Window System.

Crafter is written entirely in Tcl/Tk and uses the windowing shell called wish. Manipulating Crafter's user interface, such as clicking on buttons or selecting menu items, invokes Tcl commands. For instance, selecting a primitive the Create menu, causes Crafter's Create and Attach commands to be invoked.

Commands can also be invoked by typing them in directly to a Tcl shell window or sending them to Crafter through a pipe. To write commands for Crafter, you should understand the syntax of Tcl and some of the basic Tcl commands, then learn the Crafter-specific commands. You do not need to know any of the Tk commands.

5.1. Brief introduction to Tcl

5.1.1. Command syntax

Tcl is an interpreted command language that is very similar in style to a shell command language but has some characteristics of C and LISP languages as well. Like a shell command, a Tcl command consists of one or more words separated by spaces or tabs. For example, the command
	expr 10 + 1
consists of four words (the command name, "expr", plus three arguments "10", "+", and "1").

A Tcl script consists of one or more commands separated by semicolons (;) or newlines. Here is an example of a script.

	set a Hello; set b world
	expr 10 + 1
	expr 100 * cos(1.2)
	lindex {a b {c d} e} 2

Expression syntax in Tcl is modeled after that of ANSI C. Tcl also provides list processing commands similar to those in LISP. In Tcl, lists and sublists are delimited by braces ("{" and "}").

5.1.2. Variables and substitution

Tcl allows storage of information in variables similar to the way that shell does. A variable name can be any string, but usually is something starting with a letter and sometimes contains numbers. The value of a variable is also a string. The way a value is treated (as an integer, floating point, character, etc.) depends on the command that uses it.

To set the value of a variable, use the set command. Its syntax is "set varName value". To retrieve the value of a variable, you can use the dollar ($) operator before the variable name. For example, in the following script,

	set a 10
	expr $a + 1
the value of a is set to 10 in the first command. In the second command, the value of the variable a is substituted before calling the expr command. This is called variable substitution. The expr command gets the arguments "10 + 1" instead of "$a + 1". The return value of the command is 11.

Of course, commands would not be very useful unless we could use the return value somehow. That's what command substitution is for. Enclosing a command or script in brackets ("[" and "]") causes the command to be executed as a separate script and the result of the script is substituted in place of the bracketed command. In the following example,

	set a 10
	set b [expr $a + 1]
after variable and command substitution, the second command would be:
	set b 11
This is similar to command substitution in the shell using backquotes (e.g. `ls`).

5.1.3. Quotes and braces

Words enclosed in quotes or braces are treated as one word. The difference between quotes and braces is that substitution is not performed on words in braces. In the following example,
	set a 10
	set msg1 "$a squared is [expr $a*$a]."
	set msg2 {$a squared is [expr $a*$a].}
msg1 is set to the string `10 squared is 100.' and msg2 is set to the string `$a squared is [expr $a*$a].'

5.1.4. Control flow

Tcl supports common control flow operations, such as if and while. These constructs do not require any special syntax of the Tcl language, but are simply commands like any other that take advantage of the fact that arguments enclosed in braces are not evaluated. The command can then determine when or whether to evaluate the arguments. For example, the syntax of the while command is while condition script. Consider the following example,
	set i 0
	while {$i < 10} {
	    puts $i
	    set i [expr $i + 1]
The while command first evaluates the condition (the first argument) as an expression. If the result is non-zero, then the script is evaluated. When the script is done, the expression is evaluated again, and so on.

Because the control flow operations are just commands like any other, at least the opening brace of the script must be on the line with the rest of the command. In other words, the following is incorrect syntax:

	while {$i < 10}
	    puts $i
	    set i [expr $i + 1]

More examples of control flow commands follow.

	if {$i > 0} {
	    puts "$i is greater than 0."
	} else {
	    puts "$i is not greater than 0."

	for {set i 0} {$i < 10} {incr i} {
	    puts $i

	foreach color {red orange yellow green blue indigo violet} {
	    puts "My favorite color is $color."


If the first non-blank character of a command is a pound sign (#), then the pound sign and all characters following it until the end of the line are treated as a comment and discarded. If you want to put a comment on the same line as a command, you must separate the command from the comment with a semicolon, otherwise the comment will be considered part of the command.
	# This is a comment.
	set a Hello   ;# This is also a comment.
	set b world   # This is sending extra arguments to the set command.
For more information about Tcl, see Tcl and the Tk Toolkit by John Ousterhout or see the Tcl/Tk online manual pages (man pages).

5.2. Crafter-specific commands

Knowing the general syntax of Tcl commands will help you write scripts that use the Crafter-specific commands for creating, attaching and modifying primitives.

5.2.1. Conventions

Existing objects are referenced by an address, which is a unique identifier for the object. It is the value returned by the Create command when the object is first created.
When specifying properties and values to a command, name-value pairs are used. For example, {color {.5 0 0}} {length 3} specifies that the color should be ".5 0 0" and the length should be "3".

5.2.2. Manipulating objects

The main commands for manipulating objects are:
Create class prop1 [prop2...]
creates a new object of type class and returns its address.
Delete addr deletes the object specified by the address.
Attach [-p parent] addr1 [addr2...]
attaches the object(s) specified by address to the parent if specified, otherwise to the top-level model.
Detach addr1 [addr2...]
detaches the object(s) specified by address from their parents.
SetProps addr prop1 [prop2...]
sets the properties of the specified object and updates the Geomview display.

5.2.3. File manipulation

Simple commands for reading and writing files are provided.
Open filename
loads the model in filename, discarding the existing model if one exists.
Save filename
saves the current model in filename
closes the Crafter program.

5.2.4. Examples

So, to create and attach a new Box, for example, you could type the following:
	set b [Create Box {length 1} {width 4} {height 9}]
	Attach $b
To attach a small sphere to the box, you could then type
	Attach -p $b [Create Sphere {diam .5} {pos {0 .5 4.5}}]
The pos field controls the sphere's attachment point to the box.

If you now want to change the width of the box, you can do so using the SetProps command:

	SetProps $b {width 3}