A brief introduction to the TCL Scripting Language - Embedded.com

A brief introduction to the TCL Scripting Language

There's no getting around it. If you intend to use IBM's Full SystemSimulator (the topic of a five partseries on Embedded.com ) for nontrivial simulation, youneed to know Tcl, the Tool Command Language .

In the past,Tcl made me very uncomfortable: It's wordy like aregular high-level language, but the words have no structure—no commas,parentheses, semicolons, or equal signs.

But as I learned Tcl, I realized that its bothersome aspects werereally strengths. I've since developed a great deal of respect for thelanguage.

This article isn't going to present Tcl in full. The goal is toexplain enough of the topic so that you can read and write scripts thattake full advantage of SystemSim's capabilities.

Throughout this treatment, I'll do my best to compare Tcl to the Clanguage that we're familiar with. One application is based on the Sieve ofEratosthenes code in the five part series on Embedded.com. .But first, let's start with a simple Hello World!-typescript.

Introducing Tcl
TheAppendixE folder available on linewith the code discussed here has no subfolders, just two files: square.tcl and sieve.tcl .Change to this directory and execute the following command:

tclsh square.tcl

This script computes five squared and returns Result is 25!. ListingE.1 below presents the content of square.tcl

ListingE.1 Basic Tcl: square.tcl

This script might not look impressive, but it provides a wealth ofinformation about Tcl:

1) set assigns values to variables, expr receives expressionsand returns a value, and puts prints strings to the console.

2) Simple syntax: commands don't have to be followed bysemicolons, arguments aren't enclosed in parentheses or separated bycommas, no equals sign in assignment statements.

3) Variables are untyped, variable names can start with anumber, and string constants are enclosed in double quotes.

4) A variable's value is referenced by preceding the variablename with $, and variables can be referenced directly inside a string.

5) Tcl comments start with #.

6) The result of a command (forexample, expr 5*5 ) can be accessed like a variable if surroundedby square brackets.

7) No main function or any specifically marked startingpoint; Tcl commands are interpreted one command after the next.

This last point is important. Every line in a Tcl script isa command followed by zero or more space-separated arguments. Nearlyevery command returns a value, and all values are processed as strings.

For example, expr doesn't know or care that $num holds a numericvalue; all it knows is that 5 * 5 is a string that can be evaluated. Itperforms the evaluation and returns the result as a new string: 25.

If the code in Listing E.1 makes sense, the rest of this discussionwon't provide any difficulty. The next sections present higher-levelconstructs in Tcl: conditional statements, lists, loops, andprocedures.

Tcl control structures and aggregates operate like those in C/C++,but the syntax differs in many respects. This section presents Tclconditional statements, lists, arrays, and loops. Throughout thediscussion, keep in mind that every Tcl statement is a command and thatTcl syntax relies on curly braces rather than parentheses.

Tcl Conditional Statement: if…elseif…else
Tcl checks for conditions in much the same way that C does. The word ifis followed by an expression and statements to be executed if theexpression is valid. The optional elseif and else are followed bystatements to be executed if the expression is invalid.

An expression is valid if it produces a nonzero number or a stringequaling true or yes as opposed to false or no. These expressions relyon == to compare for equality and other operators include !=, >,<, >=, and <=.The following code presents a simple example:

set hour_of_day 1
if [expr $hour_of_day > 12] {
    puts “Evening”
} elseif [expr $hour_of_day < 12] {
    puts “Morning”
} else {
    puts “Noon”
}

It's important to see that elseif and else are not placed onseparate lines; doing so will cause an error. This is because elseifand else are not separate commands. They are part of the overall ifcommand.

<>Tcl List Processing
For example, the following statement assigns to example_list which is a list comprising four elements.The last element is a secondlist:

set example_list [list “Hi there!” abc $var [list 1 2 3]]

List elements are accessed with the lindex command. For example,

puts [lindex $example_list 1]

prints abc, the element of example_list at index 1. Table E.1 below presents lindex and other Tcl list commands.

TableE.1 Basic Tcl List Commands

The following script uses a number of these commands to manipulate alist of integers:

set num_list [list 0 1 2 3 4]

# Append {5 6 7} to the end
lappend num_list 5 6 7

# Replace the first four values with {7 6 5 4}
set num_list [lreplace $num_list 0 3 7 6 5 4]

# Insert element {3} into the middle of the list
set num_list [linsert $num_list [expr [llength $num_list]/2] 3]

# Create a list from the middle elements
set new_list [lrange $num_list 2 6]

The commands lreplace and linsert don't change the input list.Theyreturn a second list whose values are those of the input list aftermodification. Also, lreplace, linsert, and lrange operate on the valuesof the list ($num_list), whereas lappend operates on the list itself.

Tcl Arrays
Arrays are particularly important because SystemSim only allows accessto SPU statistics through Tcl arrays.A Tcl array is similar to a list,but each element of the array is a match between a string name and astring value.Arrays in Tcl serve the same role as hash maps in otherlanguages.

Tcl arrays aren't allocated in advance, but are populated as newelements are added. For example, an array arr can be set to containthree elements with the following code:

set arr(first) = “First value”
set arr(2) = “Second value”
set arr(“Third value”) = “Third value”

Array indices are always strings, and array elements are referencedby enclosing the indices in parentheses. In this example, $arr(2) willbe replaced with “Second value” whenever it appears in code. TableE.2 below lists a number of Tcl commands that operate on arrays. Ineach case, aname is the name of an array.

TableE.2 Basic Tcl Array Commands

Name/value pairs are processed as two-element lists. array setrequires that the input list contain an even number of elements. Thefollowing code shows how these commands are used in practice:

# Create and initialize array
array set nums {first 1 second 2 third 3}

# Access an element of the array (Result: 2)
puts $nums(second)

# Get size of array (Result: 3)
puts [array size nums]

# Get names in array (Result: second first third)
puts [array names nums]

The array names command doesn't return the array names in order.This is because Tcl arrays are based on hash tables, and the name ofthe string has no relation to where it's stored.

Loop Iteration: for and foreach
The for and foreach commands both create loop structures. A for loopiterates as long as an expression remains valid, and foreach iteratesacross the elements in one or more Tcl lists. The syntax of the forstatement is given by the following:

for start test next body

The Tcl interpreter executes the start command once, and then checksthe test expression. If the expression is valid, it performs thecommands in body and executes the next command. The interpretercontinues this process (check test, run body, run next) until test isinvalid.

The for command is commonly used to iterate a specific number oftimes. In this usage, the start command assigns a number to a counter,the test expression compares the counter to the final value, and thenext command increments or decrements the counter. This is shown in thefollowing example:

for {set i 0} {$i < 10} {incr i} {
    puts “Count = $i”
}

This example prints out the integers from 0 to 10.The command {incri} is short for the following:

{set i [expr $i+1]}

The foreach command is simpler than the for command, and iteratesover the elements in one or more lists. The basic foreach statement isgiven by this:

foreach var list body

When the command starts, the interpreter sets var equal to the firstelement of list and then processes the body commands. Then it sets varequal to each succeeding element in list, and processes body after eachassignment. The following code iterates through each element incolor_list:

set color_list [list red orange yellow green]
foreach color $color_list {
    puts “The current color is $color”
}

When a Tcl script is invoked with command-line parameters, theparameters are placed in a list called argv. The number of parametersis placed in a variable called argc. The following code iteratesthrough each of the parameters to see whether the script was calledwith the -v option.

foreach param $argv {
    if {$param == “-v”} {
        puts “The -v option was used.”
    }
}

If the interpreter encounters continue in a for or foreach construct, it skips the rest of the body commands and proceeds to thenext iteration. If it encounters a break command,the interpreter stops processing the for/foreach command and interpretsthe next statement in the script.

Procedure Declarations
Every high-level language provides a way to encapsulate functionalitywithin subroutines, and Tcl is no exception. Tcl procedures are definedwith the proc command and each procedure must have a unique name.Thisname can be used outside the procedure like a regular Tcl command.

A basic procedure declaration consists of proc, the procedure name,and zero or more arguments in braces. For example, the followingdeclaration states that example_proc accepts three parameters that willbe accessed as first, second, and third:

proc example_proc {first second third}

These parameters are untyped, so a call to this procedure might looklike this:

example_proc xyz “10 9 8” forty-two

It's up to the procedure to make sure the parameter values makesense.

A function can accept a variable number of arguments by using aspecial argument: args. This serves as a list containing all theprocedure's parameters. For example, the following procedure prints anerror message if it wasn't called with two arguments:

<>proc two_arg {args} {
    if {[llength $args] != 2} {
        puts “This procedure must havetwo arguments.”
        return “failed”
    }
puts “The procedure was called correctly”
}

The procedure's return statement is bolded to emphasize itsimportance. A procedure doesn't have to have a return, and if doesn't,it will return the result of the last executed command.

But in the preceding example, the procedure returns failed in theevent of a miscall. Then it finishes immediately. If two_arg is invokedwith a command like

set ret [two_arg a b c]

ret will be set to failed because two_arg was called with threearguments. The final puts statement won't be executed.

Just as in C functions, variables declared within a procedure arelocal to that procedure. A global variable can be accessed if twoconditions are met:

1. The variable is created outside the procedure.
2.
The variable inside the procedure is declared with the globalkeyword.

In Listing E.2 below , each procedure calls global num toaccess the size of the list to be analyzed. This script finds all theprime numbers between two and num and prints them to the screen. Thisuses the same Sieve of Eratosthenes algorithm as the C code in the Chapter4 file available on line, but divides the process into threeprocedures.

ListingE.2 Advanced Tcl: sieve.tcl

The second-to-last line creates the global variable for theprocedures, and the last line starts the computation by calling init . initcreates the primes list and passes it to sieve . sievedetermines which values are composite and passes the list to disp . dispprints out the prime values. Each procedure call passes parameters byvalue,which is how Tcl regularly passes parameters.

Conclusion
Tcl is the interface language for IBM's Full System Simulator, so ifyou intend to perform simulations involving triggers or emitters, it'sthe language to know. But aside from its importance there, Tcl isfascinating in its own right.

A brief treatment such as this can't do justice to the Tcl language,but it's a fine starting place for further investigation. Inparticular, the Tcl/Tk (Tcl toolkit) extension makes it possible tobuild powerful graphical user interfaces that run on many operatingsystems. Tcl also has extensions for sockets, databases, andobject-oriented development.

Matthew Scarpino lives in the San Franciso Bay area anddevelops software to interface embedded devices. He has a master'sdegree in electrical engineering and has spent more than a decade insoftware development. His experience includes computing clusters,digital signal processors, microcontrollers and field programmable gatearrays and, of course, the Cell Processor.

This article is reproduced from the book “Programmingthe Cell Processor”, Copyright © 2009, by permission ofPearson Education, Inc.. Written permission from Pearson Education,Inc. is required for all other uses.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.