Up:
  1. TkScript Reference Guide » Statements
TkScript

reference guide | Statements


 
Table of Contents:

1. Statements

A statement is a single element in a list of statements (statement sequence).
 
Statements are usually executed in first to last order.
Flow control statements, like .e.g. if, for or loop can be used to conditionally execute a statement sequence respectively loop it.
 
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.
 
Statements can be categorized as following:
  • Variable declarations
  • Constant declarations (define, enum)
  • Other datatype declarations (class, module, function, method, exception, ..)
  • Variable/Member/Array/HashTable assignments
  • Flow control (do..while, if, for, foreach, loop, break, while, switch..)
  • Function/method calls
  • Delegate assignments or calls
  • Other (e.g. try/catch/finally/throw, prepare, clamp, wrap, global mutex declaration or signal callback bindings)
1.1. Declarations
TkScript supports the following declarative statements:
  • class
    • Declare a script class datatype
  • define
    • Define a module or class constant
    • Also used to define a new exception/error type
  • enum
    • Create a constant enumeration
  • function
    • Declare a module or class function (static method)
  • module
    • Set the current (unique) module name
  • namespace
    • Create or select a namespace
1.2. Flow control
1.3. Function/method calls
Up:
  1. TkScript reference guide / Functions » Module functions

The following statements are used to handle function or method calls:
  • Native and script function calls
  • Native and script class method calls
  • Special built-in functions and methods
    • clamp
    • prepare
    • use
    • wrap
    • Array/hashtable assignments (yacArray*, yacHash*)

 
The special functions and methods are usually called indirectly by using certain kinds of expressions or statements.
2. Statement sequences
Up:
  1. TkScript Reference Guide » Statements » Statement sequences
Statements are usually grouped in blocks (statement sequences) which are enclosed in {} brackets.
 
For every source file, a top level statement sequence is implicitely created. This 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 {} brackets can be omitted if a statement sequence only contains one single statement but it is recommend to use them anyway to improve code readability and prevent some more obscure problems like e.g. dangling else:

int i = 41, j = 1;

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

print j;

 
In order to make it work as expected, the code above should better be written as:

int i = 41, j = 1;

if(i == 42)
{
if(j == 1)
{
j = 2;
}
}
else
{
j = 3;
}
3. The if..else statement
Up:
  1. TkScript Reference Guide » Statements » 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:

int i = 42;
int j;

if(i == 42)
{
j = 1;
}

 
Example:

int i = 41;
int j;

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

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

int i = 42;
int j;

if i == 42
j = 1;

 
Example:

int i = 41;
int j;

if i == 42
j = 1;
else
j = 2;
4. The do..while statement
Up:
  1. TkScript Reference Guide » Statements » The do..while statement
  2. TkScript reference guide / Expressions » Expressions » Nested expressions

This statement is used to loop a given statement (-sequence) until the boolean expression after while evaluates to false (0).
 
The break statement may 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.
5. The while statement
Up:
  1. TkScript Reference Guide » Statements » The while statement
  2. TkScript reference guide / Expressions » Expressions » Nested expressions

This statement is used to repeat a statement sequence as long as the boolean expression after while evaluates to true (!=0).
 
The break statement may 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++;
}
6. The switch statement
Up:
  1. TkScript Reference Guide » Statements » The switch statement
  2. TkScript reference guide / Expressions » Expressions » Nested expressions

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 is executed. The condition default refers to all conditions not listed explicitely.
 
Each statement sequence should be closed using the break keyword. Otherwise, the statement sequence of the next condition will be executed as well - regardless whether that condition is met or not (run into case label).
 
Example:

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

 
String and float condition expressions are also allowed. case expressions do not need to be constant but may even contain function calls:

function MyFunction() {
return 10;
}

String s = Arguments[0];

switch(s)
{
case "-h":
case "--help":
/* ... */
break;
case MyFunction(): // case 10
/* ... */
break;
}
7. The for statement
Up:
  1. TkScript Reference Guide » Statements » The for statement
  2. TkScript reference guide / Expressions » Expressions » Nested expressions

This statement is used to repeat the loop body as long as the loop condition, a boolean expression, evaluates to true.
 
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 may be used to immediately abort a for loop.
 
Example:

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

* trace "i="+i; - is the loop body
* int i=0; - is the loop initialization
* i<10; - is the loop condition
* i++ -is the modification statement
* i -is the loop counter

 
Example:

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

 
Example:

int n = 16; // http://www.bagley.org/~doug/shootout/nestedloop
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 shortest way to write an infinite loop in TkScript:

for(;;)
{
stdout "*forever";
}
8. The loop statement
Up:
  1. TkScript Reference Guide » Statements » The loop statement
  2. TkScript reference guide / Expressions » Expressions » Nested expressions

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 just 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 may 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++;

 
Example (uses the tksdl and tkopengl plugins):

use tksdl;
use tkopengl;

Texture tex; tex.alloc(256, 256, 4);
int k = 0;
loop(tex.sy)
{
loop(tex.sx)
{
tex[k++] = argb(rnd(255), rnd(255), rnd(255), rnd(255));
}
}
tex.saveImage("test.png");
9. The foreach statement
Up:
  1. TkScript Reference Guide » Statements » The foreach statement
  2. TkScript reference guide / Expressions » Expressions » Nested expressions

The foreach 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 may 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;

 
The following example counts the number of occurences of unique words in a text file:

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

HashTable words; words.alloc(20000);
s.loadLocal("test.tks", true);
foreach k in s.splitSpace(false)
{
k.toLower();
words[k] = int(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;
10. The break statement
Up:
  1. TkScript Reference Guide » Statements » The break statement

This statement is used to break out of do..while, while, for, loop, and 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;
}
11. The try..catch, finally statements
Up:
  1. TkScript Reference Guide » Statements » The try..catch, finally statements
  2. TkScript reference guide / Exceptions » try / catch

The try, catch and finally statements are used to handle exceptions or simply run clean-up code before passing an exception to the caller.
 
Also see TkScript reference guide / Exceptions, Exceptions.
 
Example:

try print "hello, world."; catch(Error e) trace "whoops.."; finally trace "cu!";
12. The prepare statement
Up:
  1. TkScript Reference Guide » Statements » The prepare statement

This statement is used to run one-time initializations in the context of a function.
 
In the following example, the statement sequence given after the prepare keyword will be executed only once for all calls to function FLookUp:

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);

 
Please notice that regular variable initializations are run everytime a function is called:

function FVarInit() {
int i = 42; // a "static" variable
local float f = PI; // a "local" variable
print "i=" + i;
print "f=" + f;
i = 23;
f = 2PI;
}
FVarInit();
FVarInit();
13. The clamp and wrap statements
Up:
  1. TkScript Reference Guide » Statements » The clamp and wrap statements

These statements are used to limit the values of variable (int, float or Object reference) to a given range.
 
Example:

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

 
Example:

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

 
The clamp and wrap functionality is also available for C++/YAC objects although only few classes support it. See tkmath for an example.
 
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);
14. The use statement
Up:
  1. TkScript Reference Guide » Statements » 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).
For more information about the plugin directories, see TKS_PLUGIN_PATH.
 
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 script functions to events raised by C++ objects:

use tkopengl;
use tksdl;

function MyOnKeyboard(Key _k) {
trace "key \""+_k.name+"\" was pressed";
if(_k.pressed == VKEY_ESCAPE) SDL.exitEventLoop();
}

Viewport.openWindow(640,480);

use MyOnKeyboard for SDL.onKeyboard; // bind MyOnKeyboard callback

SDL.eventLoop();

 
The use callbacks syntax is used to automatically bind C++ event/signal handlers to script functions.
The name and signature of the script function must match the C++ signal definition.
 
Example:

use tkopengl;
use tksdl;

function onKeyboard(Key _k) {
trace "key \""+_k.name+"\" was pressed";
if(_k.pressed == VKEY_ESCAPE) SDL.exitEventLoop();
}
Viewport.openWindow(640,480);

use callbacks; // auto-bind all available callbacks

SDL.eventLoop();
15. The define and enum statements
Up:
  1. TkScript Reference Guide » Statements » The define and enum statements
  2. TkScript reference guide / Scanner » User defined constants » Module constants » Enumeration example

These statements are used to define constant values.
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 Object(255&FLAG7).printf("0x%02x");

 
Please notice that 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 class constant parser is a bit more sophisticated and allows complex expressions and strongly typed constants, also see Class constants.
 
16. The print statement
Up:
  1. TkScript Reference Guide » Statements » The print statement
The print statement is used to print a String to the stdout stream.
 
There are a couple of variations of the print statement available:

String s = "hello, world.";
print s; // print to stdout, automatically append linefeed character
stdout s; // print to stdout
stderr s; // print to stderr
17. The trace statement
Up:
  1. TkScript Reference Guide » Statements » The trace statement
The trace statement is used to print a debug String to the stdout stream.
 
In contrary to the print statement, the trace output can be statically excluded from execution at compile-time or dynamically at run-time:

trace s; // mainly used for debug output, can be disabled at compile or runtime
trace true; // enable compile-time "trace" statements (default)
trace false; // disable compile-time "trace" statements
dtrace true; // enable run-time "trace" statements (default)
dtrace false;// (temporarily) disable run-time "trace" statements

 
Example:

function TraceHello(String arg) {
trace "hello" + arg;
}
TraceHello(", world.");

dtrace false;
TraceHello(", what ?");

dtrace true;
TraceHello(", world!");
18. The die statement
Up:
  1. TkScript Reference Guide » Statements » The die statement
  2. TkScript reference guide / Exceptions » die
The die statement is used to raise the fatal/critical Death exception and quit the current application (after automatic clean up, of course).
 
Example:

String s;
try
{
if!(s.loadLocal("somefile.txt", true))
{
die "could not load \"somefile.txt\"";
}
}
catch(Death e)
{
print "caught Death exception. darn :-)";
}

 
Note: The die statement is a reminiscence to the Perl language ;-)
19. The function statement
Up:
  1. TkScript Reference Guide » Statements » The function statement
The function statement is used to define a function.
 
Please see TkScript reference guide / Functions for more information about functions.
 
Example:

function MyFunction(int i, float f, String s) {
print "i="+i+" f="+f+" s=\""+s+"\".";
}
MyFunction(42, PI, "hello, world.");
20. The constraint statement
Up:
  1. TkScript Reference Guide » Statements » The constraint statement
The constraint statement is used to define a function argument or return value constraint expression.
 
Please see Constraints for more information about function constraints.
 
Example:

constraint csisstring _ instanceof String "is a string";

class C {
test(Object o.csisstring) { trace typename(o); }
}

C c;
c.test("hello, world.");
21. The exception statement
Up:
  1. TkScript Reference Guide » Statements » The exception statement
  2. TkScript reference guide / Classes » Exceptions
The exception statement is used to define a new exception type.
 
Please see TkScript reference guide / Exceptions, Exceptions for more information about exceptions.
 
Example:

define exception MyError : UncriticalError;

try
{
throw MyError("cu!");
}
catch(MyError e)
{
trace "caught error "+e.name+" message="+e.message;
}
22. The return statement
Up:
  1. TkScript Reference Guide » Statements » The return statement
The return statement is used to return from a function or method call. It can also be used to set the default return value.
 
Please see The return statement for more information about the return statement.
 
Example:

function Test() {
return "hello, world.";
}
function Test2() {
return = "world.";
stdout "hello, ";
}
print Test();
print Test2();
23. The class statement
Up:
  1. TkScript Reference Guide » Statements » The class statement
  2. TkScript reference guide / Classes » Declaration
The class statement is used to define a class.
 
Please see TkScript reference guide / Classes for more information about classes.
 
Example:

namespace test;

class C {
explain "A simple test class.";

define int CONSTANT = 42;

define exception MyException : UncriticalError;

static boolean b = false;

int i = 23;
float f = PI;
String s = "n/a";

static MyStaticMethod() : boolean {
b = ! b;
return b;
}

public method myMethod() {
print "i="+i+" f="+f+" s=\""+s+"\".";
throw MyException("test");
}
}
C.b = true;
C.MyStaticMethod();

C c;
c.i = 42;
c.s <= "hello, world.";
c.myMethod();
24. The delegate statement
Up:
  1. TkScript Reference Guide » Statements » The delegate statement
  2. TkScript reference guide / Classes » Delegates
The delegate statement is used to declare or call a method delegate.
 
Also see Delegates.
25. The explain statement
Up:
  1. TkScript Reference Guide » Statements » The explain statement

The explain statement is used to embed inline documentation for a previous function, method, class or constant declaration.
 
When a script is run with the -ee, --emitexplanations command line option (see Emitting inline documentation in DOG format), the TkScript runtime will dump all inline documentation, encoded in a very simple ASCII format, to stdout.
 
The DOG (see The DOG manual) documentation tool can parse this output and generate a set of HTML pages. "DOG" uses a JavaDoc-like syntax.
 
Technically speaking, TkScript itself does not define a format for this document string.
 
Example:

function Test(int i) {
explain 'Synopsis for function "Test".

Long description for function "Test".

@arg i Description of argument "i"
@returns Description for return value
@see MyClass
'
;
}

class MyClass {
explain 'Description for class "MyClass"..';

define int CONSTANT = 42;
explain 'Description for integer constant "CONSTANT"..';


public method test(int i) {
explain 'Description for method "test"..

@see Test
'
;
}

}


auto-generated by "DOG", the TkScript document generator. Wed, 31/Dec/2008 15:53:35