The GENESIS Script Language Interpreter (SLI) provides a framework in which a simulation programmer can define and manipulate GENESIS elements. The SLI interprets statements in the GENESIS simulation language, and constitutes the operating system ``shell'' at work when you are running GENESIS.
The simulator shell is an interpretive operating environment which lets you:
You can perform these operations in either of two ways:
User-defined SLI scripts are used to glue the pieces of a simulation together. XODUS graphical objects that you use to define the front end of a simulation and GENESIS data handlers are all controlled from SLI scripts.
The shell contains a library of basic commands which you can augment through the addition of compiled C commands or interpreted SLI functions.
GENESIS routines are called by entering a routine name followed by any necessary arguments and options separated by whitespace.
routine-name arg1 arg2 ... -option1 option1-arg1 ... -option2 ...
A valid routine-name is a script identifier consisting of any combination of alphabetic (A-Z or a-z) or numeric (0-9) characters, or underscores (``_'') -- all other symbols are invalid characters in an identifier.
Routine arguments consist of literal strings of characters, results of other GENESIS routines or expressions, strings of characters including whitespace enclosed in double quotes and the value of parameters passed to a script or function. Combinations of these which appear together without any intervening whitespace are concatenated and passed as a single argument to the routine.
Routine options follow command arguments, and are introduced by a dash character. Option names may be abbreviated to any unambiguous length. Each option may accept additional arguments following the option name.
A carriage return marks the end of a statement, so you do not need to use semicolons at the end of a line. However, you can use semicolons to terminate statements as a way to include multiple statements on a single line. Several examples:
genesis > reset; step 100
genesis > int a, b, c ; a=1 ; b=2 ; c=3
genesis > if( a < b); echo {a} is less than {b}; end
1 is less than 2
In other cases, the ``command'' returns a value and might more properly
be called a function. In the documentation for GENESIS commands, we will
use the term ``routine'' for built-in GENESIS commands, and will reserve the
term ``function'' for a script function that is written in the GENESIS
scripting language. The procedure for creating your own functions is
described under
Functions.
The following two examples illustrate how a routine call can be supplied as the argument to another routine or as a value in a script language expression:
genesis > echo { getfield /neutral_test x }
genesis > float length = { getfield /cell/soma len }
Routines used in the context of an argument to another routine or within a script language expression must be enclosed in curly brackets.
All GENESIS statements are subject to these and other basic syntactical rules. If a statement you submit violates these rules, the interpreter will respond with an error message (and ignore your instruction).
In GENESIS, you create a variable by entering a variable ``type'' specifier at the command line, followed by the variable name (a script identifier), optionally followed by a value to assign to the variable:
variable-type variable-name [= expression]
You can create any of three types of variables at the GENESIS shell:
| Type | Meaning | Example Value |
| int | integer number | 5, 18, 6000, -34 |
| float | double precision floating-point number | 5.0, 3.14, -2001.4 |
| str | character string | five, 5.0, hello |
genesis > int a genesis > float PI = 3.141593 genesis > float myfloat = 2*PI genesis > float floatstr = "6.3" genesis > str hi = "hello there"Note that case is significant for variable names (as in other areas): ``PI'' is different from ``Pi'', which is different from ``pi''. Also note that the character sequence ``6.3'' could be the value of either a floating point variable or a string variable.
Once you have defined a variable, you can change its value using an assignment statement:
variable-name = expressionFor example:
genesis > a = 40 genesis > myfloat = 100.5 genesis > hi = "The value of myfloat = " @ myfloat
Variables declared in a function are local to the function. Those declared outside of a function in a script (or script which is included with the ``include'' statement) are global variables. When a value is assigned to a global variable, it will affect any statements or functions which follow this assignment. One often refers to ``constants'' in a GENESIS script. These are not true constants, but are just variables which are not expected to take on new values during the course of a simulation.
Script variable values are retrieved by naming the variable in the context of an expression. In the description of GENESIS script language statements, expressions appear as indicated. In other contexts the value of an expression may be subtituted by enclosing the expression in curly brackets:
genesis > float pi = 3.1415
genesis > echo pi
pi
genesis > echo { pi }
3.1415
As with many languages, GENESIS will cast expressions involving both floating point and integer variables to floating point. It will also convert a string to a float if the string is a valid representation of a number. For example,
genesis > int i = 5
genesis > int j = 2
genesis > float x = 2
genesis > str num = "5"
genesis > echo {i/j}
2
genesis > echo {i/x}
2.5
genesis > echo {num/2}
2.5
genesis > num = "i/x"
genesis > echo {num}
i/x
genesis > echo {{num}/2}
** Error - CastToFloat: Error casting 'i/x', using 0.0
0
As with any programing language, GENESIS lets you define functions in order to make your script programs more modular and easier to modify. You should group function definitions together at the beginning of a script, preceding any statements that will use them. The listglobals routine will list any user-defined functions.
The general form of a function definition in GENESIS is:
function function-name [ (arg1 [, arg ... ] ) ]
statement-1
.
.
.
statement-n
end
For example:
function print_area(length, diameter)
float length, diameter
float area
float PI=3.14159
area = PI*diameter*length
echo The area is {area}
end
function link_compartment(channel,compartment)
addmsg {channel} {compartment} RAXIAL Ra previous_state
addmsg {compartment} {channel} AXIAL previous_state
end
The SLI also lets you define functions interactively at the GENESIS prompt. For example:
genesis > function my_echo(inputval)
? echo { inputval }
? end
genesis > listglobals
function my_echo
genesis > my_echo 33
33
The return keyword allows a return from the function before the end statement. It may optionally be used to return a value. For example:
function make_positive(num) // a silly version of "abs"
float num
if (num >= 0)
return {num}
else
return {abs {num}}
end
end
The keywords function, return, and end are features of the interpreter, not normal GENESIS commands; consequently, they do not appear in a listing of GENESIS routines (e.g., as given by the listcommands routine).
The routines argc and argv are often used inside of function definitions to return the number of arguments and the array of arguments which are passed to the function.
The table below lists the basic operators available in GENESIS, from highest to lowest precedence. These operators can be applied to variables or constants within a GENESIS expression.
| Operators | Function |
| - | unary minus |
** | power |
* / % ~ | multiply, divide, modulo (int only), bitwise complement |
| + - & | ˆ @ | add, subtract, bitwise and, bitwise or, |
| bitwise xor, string concatenation | |
| ! | logical complement |
| < <= > >= == != | relational operators (perform both numeric |
| and string comparisons) | |
| && || | logical and, logical or |
The following examples illustrate the use of several of the basic operators.
For string concatenation, the ``@'' operator is used:
genesis > echo {"sub" @ "genius"}
subgenius
The following command shows how precedence is employed:
genesis > echo { 24 / 12 + 7 * 2 }
16
You can also explicitly specify the precedence of operations in an expression
by using parentheses:
genesis > echo { 3 * 4 + 5 }
17
genesis > echo { 3 * (4 + 5 ) }
27
The following command does not return 5.4 because each element of the
expression is an integer:
genesis > echo { 9 * 3 / 5 }
5
For comparisons in GENESIS, the integer 0 is considered False; all other
integer values are considered True; GENESIS returns 1 to indicate True. The
following command returns 1 because the expression is True (it would have
returned 0 if the expression had been False):
genesis > echo { 4 > 2 }
1
Here is an example of negation in determining the nonexistence of an element:
if (!{exists {dest}/soma})
...
The relational operators are
defined to be non-associative. This prevents silly expressions like the
following:
1 < 2 < 4 [WRONG]
GENESIS supports four kinds of conditional control structures:
Note that you can break out of any of these loops before their expected termination by using the ``break'' or ``return'' statements.
The GENESIS ``if ...'' conditional structure takes the following form:
if (expression)
statements
elif (expression)
statements
else
statements
end
The elif and else portions of the form are optional and multiple
elif portions may appear.
The ``if''/``elif'' expressions are evaluated in the order of appearance. When an expression evaluates ``true'', all the statements between the ``true'' expression and the following matching ``elif'', ``else'' or ``end'' will be executed; if all evaluated expressions are ``false'', then the statements between the ``else'' and the ``end'' are executed (or no statements are executed if there is no ``else'' clause).
Note that the GENESIS if construct does not recognize the keyword ``then''.
These are some examples of valid if statements:
if(1)
echo hello
end
if(1); echo hello; end
if( (GRAPHICS == 1) || (5+3 > 10) )
echo hello
end
The following function uses the if/elif/else/end construct and prints
``zero'', ``negative'' or ``positive'' depending on the first
argument:
function iftest(arg)
int arg
if ( arg == 0 )
echo zero
elif ( arg < 0 )
echo negative
else
echo positive
end
end
The GENESIS ``while ...'' conditional looping statement has the following syntax:
while (expression)
statements
end
The expression is evaluated. If it is ``true'' (i.e., not 0), then all the
statements will be executed, then the expression will be evaluated again; if
the evaluated expression is ``false'', then all the
statements are skipped and control is turned to the first statement after
the ``end''.
An example of a while loop is the following:
str parent
while(getfield {{parent} object->name} != "xgraph")
parent = {el {parent}/..}
end
Note that the expression can be complicated and can involve some of the actual
work of the loop.
The GENESIS ``for ...'' conditional structure uses an incrementable variable in assessing the condition for continuing through the loop. The syntax of the loop is as follows:
for (init_assignment; expression; incr_assignment)
statements
end
The init_assignment is an assignment statement which is evaluated once prior to entering the loop. The incr_assignment is an assignment statment which is executed following the statements each time through the loop. Otherwise, the for/end statement operates in the same manner as while/end.
To print the numbers one through ten:
int i
for (i = 1; i <= 10; i = i + 1)
echo {i}
end
The GENESIS ``foreach'' statement loops through a set of statements once for each item in a specified argument list, having assigned the value of each item in the list to a looping variable for use by the statements:
foreach loop-var ( arg1 [ arg ...] )
statements
end
For example:
str name
foreach name ({el {path}/##[OBJECT=xform]})
xshow {name}
end
The use of wildcards in the specification of pathnames is described in
the section
Hierarchical Structure. Again,
you need to have declared the variables used in the loop before their
use in the loop.