back to index

Statements

Statements are used to declare variables, constants, classes, functions and modules. A statement has no return value but is rather used to either store the result value from its contained expression(s) to a memory location or use it as a parameter for a control structure. TKS supports the following control structures:

                 do..while
                 if..else
                 for
                 foreach
                 loop
                 switch..case
                 while

other supported statements are:

                 break
                 clamp
                 class
                 define
                 enum
                 function
                 module
                 prepare
                 use
                 wrap

<builtin function calls> <class method calls> <variable/array/hash/member assignments> <variable declarations> <user defined function calls>

Statements are often grouped in blocks (statement sequences) which are enclosed in {} brackets.

For every source file, a top level statement sequence is implicitely created which makes it possible to write a TKS script which just consists of a single statement, for instance.

Statements outside of functions and methods are executed after successful compilation of all modules defined in the project file. The order of execution hereby equals the order of occurrence in the project file. This mechanism can be used to initialize objects, allocate arrays and/or initialize variables.

Example:

    print "hello, world."; 

...represents a complete, valid TKS program.

In contrary to C, a statement block may not directly contain another statement block:

Example:

    if(i==42) { { /* ..this does not work.. */ } } 

Example:

    if(i==42) { if(j==1) { /* ..this is allowed.. */ } }


The if..else statement

This statement is used to branch conditionally depending on the result of a boolean expression.

If the expression evaluates to true (!=0) then the first statement block will be executed, otherwise the control flow will branch to the else statement, if available.

Example:

    if(i==42) j=1;


Example:

    if(i==42) j=1; else j=2;

Example:

    if(i==42) { j=1; k=2; } else { j=2; k=3; }

Note: The () brackets are not required; actually they are part of the expression:

Example:

    if i==42 j=1;

Example:

    if i==42 j=1; else j=2;

Example:

    if i==42 { j=1; k=2; } else { j=2; k=3; }

The do..while statement

This statement is used to loop a given statement (-sequence) until the boolean expression after while evaluates to false (0).

The break statement can be used to immediately abort a do..while-loop.

Example:

    int i=0; do i++; while (i<10);

Example:

    int i=0,j=0; do { i++; j++; } while (i+j)<10;

The boolean condition will be tested each time a loop iteration finishes, i.e. the do..while loop body is run at least once.

Similar to the if statement, the () brackets around the conditional expression are optional and actually part of the expression.

The while statement

This statement is used to repeat a statement sequence as long as the boolean expression after while evaluates to true (!=0).

The break statement can be used to immediately abort a while-loop.

Example:

    int i=0; while(i<10) i++;

Example:

    int i=0,j=0; while(i+j)<10 { i++; j++; }

The switch statement

This statement is used to test the value of an expression for a number of conditions; if a condition is met, the associated statement sequence will be executed. The condition default hereby refers to all conditions not listed explicitely.

Each statement sequence has to be closed using the break keyword since otherwise the sequence of the next condition will be executed as well (run into case label) regardless whether that condition is met or not.

Example:

    int i=rnd(10);
    switch(i) {
        case 1:
                trace "i is 1.";
                break;
        case 2:
                trace "i is 2.";
                break;
        case 3:
        case 4:
                trace "i is 3 or 4";
                break;
        default:
                trace "i is neither 1,2,3 nor 4.";
                break;
    }

In contrary to C, also String and float condition expressions are allowed; furthermore, case expressions do not need to be constant but may contain even function calls.

Example:

    function MyFunction() {
        return 10;
    }

    String s=Arguments[0];

    switch(s) {
        case "-h":
        case "--help":
            /* ... */
            break;
        case MyFunction(): // case 10
            /* ... */
            break;
    }

The For statement

This statement is used to repeat the loop body as long as the loop condition, a boolean expression, evaluates to true. Thus, the mode of operation of the for loop is similar to the while loop, although additional initialization and modification statements may be provided. The empty statement ( ; ) is used to omit the initialization; no semicolon is required to terminate the modification statement.

The initialization statement is called before the first loop iteration starts, the modification statement is called every time an interation finishes. Before each iteration, the loop condition is tested and if it evaluates to true, the loop body is executed and the next iteration starts.

The break statement can be used to immediately abort a for-loop.

Example:

    for(int i=0; i<10; i++) trace "i="+i;

Example:

    int i=0;
    for(;i<10;) trace "i="+i++; // omit the init + modif. statements

Example:

    int n = 16; // <i>http://www.bagley.org/~doug/shootout/nestedloop</i>
    int x = 0;
    for (int a=0; a<n; a++)
        for (int b=0; b<n; b++)
            for (int c=0; c<n; c++)
                for (int d=0; d<n; d++)
                    for (int e=0; e<n; e++)
                        for (int f=0; f<n; f++)
                            x++;

The loop statement

This statement resembles the while and for statements. Actually, it represents a frequently used special case of the for resp. while statement.

The expression given after the loop keyword determines the number of iterations. This integer expression is evaluated only once before the first iteration starts. There is no way to access the internal loop counter, it will simply be decremented until it reaches 0.

The brackets around the integer expression are, similar to the do..while, while and for statements, technically part of the expression.

The break statement can be used to immediately abort a loop.

Example:

    loop 10 trace "loop.";

Example:

int i=0;
loop(10) trace "i="+i++; 

Example:

    int n = 16; // http://www.bagley.org/~doug/shootout/nestedloop
    int x = 0;
    loop(n)
        loop(n)
            loop(n)
                loop(n)
                    loop(n)
                        loop(n)
                            x++;

The foreach statement

This statement is used to iterate container objects like for instance String lists, Arrays, HashTables or Pools. The loop body will be executed for each element in the given container object.

The break statement can be used to immediately abort a foreach-loop.

Example:

    String t,s="one \"two and a half\" three";
    foreach t in s.splitSpace(true) trace "t="+t;

Example:

    int i; foreach i in [1,2,4,7,9,11] trace "i="+i;

Example:

    int i=0; // http://www.bagley.org/~doug/shootout/bench/wordfreq/
    String s,k;

    HashTable words; words.alloc(20000);
    s.loadLocal("wordfreq.txt", true);
    foreach k in s.splitSpace(false) {
        k.toLower();
        words[k]=tcint(words[k])+1;
    }

    StringArray sta; sta.alloc(words.numElements);
    IntArray ita;    ita.alloc(words.numElements);
    i=0;
    foreach k in words {
        ita[i]=i;
        Integer io; io.value=words[k]; sta[i]=io.printf("%7d")+" "+k;           i++;
    }

    sta.sortByValue(ita, false);
    i=words.numElements;
    loop(--i)
        trace sta[ita[i--]];

    trace "words.numElements="+words.numElements;


The break statement

This statement is used to break out of do..while/while/for/loop/foreach loops.

Example:

int i;

print "loop:";
i=0;
loop(10)
{
    if(i==4)
	break;
    print i++;
}

print "while:";
i=0;
while(i<10)
{
    if(i==4)
	break;
    print i++;
}

print "dowhile:";
    i=0;
do {
    if(i==4)
	break;
    print i++;
} while(i<10);

print "foreach:";
foreach i in [0,1,2,3,5,7] {
    if(i==5)
	break;
    print i;
}

The prepare statement

This statement is used to run one-time initializations in the context of a function. The statement sequence given after the prepare keyword will be executed only once during the application run.

Example:

    function FLookUp(int _i) {
        IntArray lut;
        prepare {
            lut.alloc(512);
            int i=0;
            loop(256) lut.add(i++);
            loop(256) lut.add(255);
        }
         return lut[_i];
    }
    trace FLookUp(184); trace FLookUp(384);

The clamp and wrap statements

This statement is used to limit the value of a variable (int, float or Object reference) to a given range.

The clamp statement is implemented using the following C-code:

if(var->pointer.float_val<min.value.float_val)
   var->pointer.float_val=min.value.float_val;
else
  if(var->pointer.float_val>max.value.float_val)
    var->pointer.float_val=max.value.float_val;

The wrap statement is implemented using the following C-code:

if(var->pointer.float_val<min.value.float_val)
  var->pointer.float_val = (var->pointer.float_val - min.value.float_val) + max.value.float_val;
else if(var->pointer.float_val>=max.value.float_val)
       var->pointer.float_val = min.value.float_val+ (var->pointer.float_val- max.value.float_val);

Example:

    float f=32; clamp f 0 20; // f is 20

Example:

    int i=32; wrap i 0 20; // i is 12

In case the given variable is of type Object, the limits need to have the same datatype as the variable. Hence, this mechanism can be used to validate the range of compound datatypes imported using the C++ plugin interface.

Example:

    use tkopengl;
    Vector v<=vector(2,3,4);
    wrap v vector(0,0,0) vector(1,2,3); // v is (1,1,1)

The use statement

This statement is used to dynamically load native program components (plugins) at runtime.

Each plugin is associated with one shared object file (.dll or .so file extension).

Plugins will first be searched in the current directory, then in the directory determined by the environment variable TKS_PLUGIN_PATH and finally in the directory stored in the registry key HKLM\Software\TKS\TKS_PLUGIN_PATH (Microsoft Windows only).

Example:

    use tkopengl; // load the OpenGL/libPNG extension
    use tksdl; // load the SDL/SDL_net extension
    Viewport.openWindow(640,480);
    SDL.eventLoop();

Another use of the statement is to bind scriptfunctions to events raised by C++ objects, please see p.77 for details.

Example:

    use tkopengl; 
    use tksdl;

    function MyOnKeyboard(Key _k) {
        trace "key \""+_k.name+"\" was pressed";
    }
    Viewport.openWindow(640,480);
    use MyOnKeyboard for SDL.onKeyboard; // bind MyOnKeyboard callback
    SDL.eventLoop();

Example:

    use tkopengl;
    use tksdl;
    function onKeyboard(Key _k) {
        trace "key \""+_k.name+"\" was pressed";
    }
    Viewport.openWindow(640,480);
    use callbacks; // auto-bind all available callbacks
    SDL.eventLoop();

The define and enum statements

These statements are used to define constant values.

Please also see here.

Example:


#define MYCONSTANTINT    41
#define MYCONSTANTFLOAT  1.23
#define MYCONSTANTSTRING "hello, world"

print MYCONSTANTINT+1;
print MYCONSTANTFLOAT*2;
print MYCONSTANTSTRING;

enum { RED,GREEN,BLUE };

print "RED="+RED+" GREEN="+GREEN+" BLUE="+BLUE;  // => RED=0 GREEN=1 BLUE=2


enum { FLAG0=0x01,
       FLAG1=0x02,
       FLAG2=0x04,
       FLAG3=0x08,
       FLAG4=0x10,
       FLAG5=0x20,
       FLAG6=0x40,
       FLAG7=0x80
       };

print 255&FLAG7;
print tcobject(255&FLAG7).printf("0x%02x");



Please notice that in contrary to the "C" language, only single string-replacements are being made. TkScript does not have a macro-preprocessor, i.e. the following code will raise an error:

// !!NOT ALLOWED!!
#define APLUSB (a+b)
int a=1,b=2;
print APLUSB;


The function statement

This statement is used to declare new script functions. Please see here for further information.

The class statement

This statement is used to declare new script classes. Please see here for further information.


back to index

TkScript and the TkScript documentation are (c) Copyright 2001-2004 by Bastian Spiegel.