1. TkScript Reference Guide » Expressions

reference guide | Expressions

Table of Contents:

1. Expressions

Expressions are used to combine one, two, three or many values (subexpressions) to a result value, possibly by using operators.
The most simple example for an expression is a constant value:

int i = 42; // Assign result of constant expression "42" to variable "i"
float f = PI;
String s = "hello, world.";

TkScript supports quite a number of expression types. This section only lists a couple of the more distinct expressions.
You can read more about general unary, binary and ternary expressions in the TkScript reference guide / Operators chapter.
1.1. Nested expressions
It is sometimes necessary to override operator priorities by nesting an expression in a sub-expression:

print 1 + 2 * 3; // => 7
print (1 + 2) * 3; // => 9

Nested expressions can improve the readability of a source code. Notice how the brackets around the if expression are actually part of the expression:

int i = 42;
int j = 41;
String s = "hello, world.";
if (i <= 42) && (++j < 43) && (s == "hello, world.")
print "ok";

Also see The while statement, The for statement, The do..while statement, The loop statement, The foreach statement, The switch statement.
2. Constant expressions
  1. TkScript Reference Guide » Expressions » Constant expressions

The result value of a constant expression is, as the name implies, constant and can be determined while a script is being compiled.

// "2 + 3 * 4" is optimized to constant value "14"
// at compile time:
int i = 2 + 3 * 4;

This constant folding will also be done for objects:

IntArray ia <= [1, 1+1, 3, 4, 5, 6, 7, 8];
3. Variable expressions
  1. TkScript Reference Guide » Expressions » Variable expressions

A variable expression simply returns the value of a variable:

int i;
int j = i + 1; // read "i", add "1" and assign result to "j"
3.1. Pre/Post In/Decrement

Integer and even float variables can be incremented (+1) or decremented (-1) before / after their value is returned in an expression.

int i = 41;
int j = ++i; // increment "i" and assign to "j"
int k = j++; // assign "j" to "k" and increment "j" afterwards
int l = --i; // decrement "i" and assign to "j"
int m = j--; // assign "j" to "k" and decrement "j" afterwards
Double d = 0;
Double e = d++;
Double f = --d; // pre/post inc/dec may not work for all object types..

Since the ++ and -- operators modify a variable, this feature should not be used when the variable is used more than once in an expression. The order of evaluation (left-to-right or right-to-left) is not strictly defined.

int i = 41;
int j = --i + i++;
3.1.1. In statements

The pre/post inc/dec operators can also be used in statements:

int i = 41;
int j = i;
int k = j;
int l = i;
int m = j;


for(int i=0; i<10; i++) {
print i;

loop(20-i) {
print i++;
4. The range expression
The range expression tests whether an int or float value lies between the given boundaries.

boolean b;

int i = 5;
b = (1 < i < 10);

float f = 5.23;
b = (1.1 < f < 10.10);
5. The "mini-if" ternary expression

This expression returns the value of two alternative result expressions depending on the boolean result value of a conditional expression.

int i = rnd(10) , j = rnd(10) , k = i > 5 ? (i + j) : (j - i);

The above example equals the following program in terms of functionality:

int i = rnd(10), j = rnd(10), k;
if(i > 5)
k = i + j;
k = j - i;
6. Object expressions
  1. TkScript Reference Guide » Expressions » The new and deref expressions
6.1. The new expression

The new expression is used to spawn a new instance of the right-handside class type.
This works for native C++ API classes as well as user defined script classes.

function NewString {
String s <= new String; // allocate new String
return deref s; // grab ownership for String from "s" and
// return temporary value
String mynewstring <= NewString();
6.1.1. Arguments to new
TkScript does not support parameter lists in new expressions.
It is recommended to use init/exit, alloc/free or similarly named methods instead:

Buffer b; // Create "blank" instance of Buffer
b.size = 256; // Call setSize() and allocate 256 elements

Parametrizable constructors can also be emulated by using static class methods:

class MyClass {
int i;
float f;
String s;

public static New(int i, float f, String s) returns MyClass {
local MyClass c;
c.init(i, f, deref s);
return deref c;

protected method init(int _i, float _f, String _s) {
i = _i;
f = _f;
s = _s;

MyClass mc <= MyClass.New(42, PI, "hello, world.");
6.2. The deref expression

This expression is used to unlink an object reference, including the ownership for it, from a variable or class member.
The object can then be bound to another container or it will be deleted when the statement which includes the deref expression terminates.

HashTable ht;
Double d;
ht["mydouble"] = deref d; // unlink object from variable "d"
// Variable "d" now stores a simple reference to the Double object.
// The hashtable element "mydouble" will also store a reference to the
// object but it will also have the ownership for it.
// The Double object is deleted when the HashTable object is deleted


class C {
String s;

public method unlinkS() {
return deref s;
C c;
trace #(c.unlinkS());
7. The [] array expression
  1. TkScript Reference Guide » Expressions » The [] array expression

The [] expression is used to create arrays on-the-fly.
The return type of the expression, i.e. the array Object type, actually depends on the array elements:
  • if all elements are integers, an IntArray is returned
  • if all elements are floats, a FloatArray is returned
  • if all elements are objects, a PointerArray is returned
  • if all elements are strings, a StringArray is returned
  • if the element types are mixed, a ValueArray is returned


IntArray ia <= [1, 2, 3];
FloatArray fa <= [1.1, 2.2, 3.3];
PointerArray pa <= [null, Double, Float];
StringArray sa <= ["hello", ", ", "world."];
ValueArray va <= [1, 2.2, "hello, world."];

If uncertain about the array type, you can still assign/copy the returned array to an existing Object (instead of copying the reference to it) :

IntArray ia = [1, 2, 3];
FloatArray fa = [1.1, 2.2, 3.3];
PointerArray pa = [null, Double, Float];
StringArray sa = ["hello", ", ", "world."];
ValueArray va = [1, 2.2, "hello, world."];

Similar to the list and hashtable expressions, prepending the array with the keyword new will make the expression return a new Object each time it is evaluated:

function ReturnNewIntArray() {
return new [1, 2, 3];
IntArray ia <= ReturnNewIntArray();

The array element expressions are usually evaluated each time the array expression is evaluated, regardless whether a new array is returned or simply a non-deletable reference to a static Object.
However, if all array element expressions can be folded to a constant value, and the new keyword was not used, the array object becomes a constant Object.
Also see Via array variables.
8. The #[] hash table expression
  1. TkScript Reference Guide » Expressions » The #[] hash table expression

The #[] expression is used to create associative arrays (hashtables) on-the-fly.
The expression returns a HashTable object whose elements are updated each time the expression is evaluated.

HashTable ht <= #[a=1, b=2, c=3];
print ht["c"];

Please notice that the #[] expression usually returns always the same HashTable object (for each occurence of the expression).
In order to allocate a new HashTable object before the hashtable elements are initialized, prepend the expression with the new keyword:

HashTable ht <= new #[a=1, b=2, c=3];
print #(deref ht);

The #[] expression can be used recursively. For example, in order to create a hash of hashes, try the following:

HashTable ht <= #[hash1=#[a=1, b=2, c=3],
hash2=#[a=#[x=1], b=#[x=1 y=2], c=#[x=1 y=2 z=3]]

Also see The HashTable class.
9. The #() value expression
  1. TkScript Reference Guide » Expressions » The #() value expression

This expression is used to catch the return value, type and Object ownership of an expression and wrap it in a Value Object.
Also see Value wrapper objects, Native functions.

function ReturnSomething(int _what) {
case 0:
return 0;
case 1:
return 42;
case 2:
return PI;
case 3:
return new Time;
case 4:
return "hello, world.";
Value vi <= #(ReturnSomething(1)); // -return an integer
Value vf <= #(ReturnSomething(2)); // -return a floating point number
Value vo <= #(ReturnSomething(3)); // -return an object
Value vs <= #(ReturnSomething(4)); // -return a String
trace "vi.value=" + vi.value;
trace "vf.value=" + vf.value;
trace "vo.value=" + vo.value;
trace "vs.value=" + vs.value;

A new Value object is returned everytime the expression is called:

int i = 42;
trace #(#(i));

There is an exception: If the Value object is optimized to a constant value, the #() value expression will always return the same object:

trace #(#(42));
10. The {} list expression
  1. TkScript Reference Guide » Expressions » The {} list expression
  2. TkScript reference guide / Classes » Members » Permissions

The ListNode expression is used to create arbitrary-length double linked lists on-the-fly.

ListNode l <= {1, 2.2, "hallo"};
trace #(deref l);

The ListNode expression usually returns the same object (per occurence). If you want a new ListNode object to be returned everytime the expression is called, prepend the list with the new keyword:

ListNode l <= new {1, 2.2, "was"};
trace #(deref l);

Here is a simple list example that uses the {} list initializer expression (from 2004):

ListNode l <= {1, 2.2, "hallo"};
ListNode c;
c <= l.tail; c.appendValue(#("welt"));
c <= l.tail; c.appendValue(#(Object(42)));
c <= l.tail; c.appendValue(#(new String()));

Value v;
foreach v in {1, 2.2, "hi", Object(42), #(5), 6}
trace "v.type=" + TKS.constantToString(v.type, "YAC_TYPE_") +
" v.string=" + v.stringValue;
trace l;

ListNode l2,l3;

function evalListExpr() {
trace "---------------------------------";
l2 <= {rnd(1), rnd(2), rnd(3), #(rnd(42))};
l3 <= l2.copy;
c <= l3.tail; c.appendValue(#("EOL."));
trace l3;


Also see Permissions.
11. The instanceof expression
  1. TkScript Reference Guide » Expressions » The instanceof expression
  2. TkScript reference guide / Classes » Polymorphy » Run time type checks

The instanceof expression is used to determine whether the class type of the left-handside value of the expression is compatible to the class type of the right-handside value.

Object o <= StdOutStream;
if(o instanceof Stream)
print "ok";

This works for native C++ API classes as well as user defined script classes:

class BaseClass { }
class MyClass : BaseClass { }

MyClass mc;
if(mc instanceof BaseClass)
print "ok";

Also see Polymorphy.
12. Expressions as statements
  1. TkScript Reference Guide » Expressions » Expressions as statements
Expressions may not be used as statements, in general.
There is a work-around, though: By assigning the result of an expression to a dummy value ("_"), thus discarding it, expressions can be used as statements, too:

_= 1 + 2;
13. Built-in functions
  1. TkScript Reference Guide » Expressions » Built-in functions

The following is a list of function-like expressions, intrinsics, which are built into the scriptengine.
These intrinsics do not involve any real functions calls: For example, when generating code in the JIT compiler, some of these functions can be inlined into the generated code.
13.1. The @() address expression

The @() expression is used to return the address of an object.
On 32bit platforms, this will simply copy the 32bit object address and change the value type to int.
On 64bit platforms, this will wrap the 64bit object address into a new Long object and return it.

String s;
trace #(@(s));

This can sometimes be useful when comparing object references:

String s = "hello, world.";
String t = "hello, world.";
if(@(s) != @(t))
print "ok";
// note: the objects "look" the same but are stored at different
// memory locations !
13.2. The 2n() expression

The 2n() expression returns the next bigger power of two integer value:

int i = 2n(63);
13.3. The abs() expression

The abs() expression returns the absolute value of an int or float value:

int i = abs(-42);
float f = abs(-PI);
13.4. The acos() expression
The acos() expression returns the arc cosine of a float value:

float f = acos(1.0);
13.5. The argb() expression

The argb() expression packs four 8bit values a, r, g, b into a 32bit value:

int a=$11, r=$22, g=$33, b=$44;
int argb32 = argb(a, r, g, b); // argb32 => 0x11223344

Integer io = argb32;
print io.printf("0x%08x");
13.6. The asin() expression
The asin() expression returns the arc sine of a float value:

float f = asin(1.0);
13.7. The ceil() expression
The ceil() expression rounds a float value to the next bigger value:

float f = ceil(-0.2);
13.8. The cos() expression
The cos() expression returns the cosine of a float value (radian measure):

float f = cos(PI);
13.9. The deg() expression
The deg() expression converts an angle (in radian measure) to degrees:

float f = deg(PI);
13.10. The exp() expression
The exp() expression returns e raised to the power of a float value:

float x = 2;
float y = 6;
float f = exp(y * ln(x)); // f => 2^6 => 64
13.11. The float() expression
The float() expression typecasts a value to a float value:

float f = float("3.1415") + 1;
13.12. The floor() expression
The floor() expression rounds a float value to the next smaller value:

float f = floor(1.7);
13.13. The frac() expression
The frac() expression returns the fractional part of a float value:

float f = frac(1.23456);
13.14. The int() expression
The int() expression typecasts a value to an integer value:

int i = int("41") + 1;
13.15. The ln() expression
The ln() expression returns the logarithm naturalis for a float value:

float f = ln(E);
13.16. The Object() expression
The Object() expression typecasts a value to a Object value:

Integer io <= Object(42);
Float fo <= Object(3.1415);
Double d = 10;
Double e <= Object(d); // Create copy of "d"

If the value is already an Object and it is not deletable, the Object() expression creates a copy of the Object :

Double d = PI;
trace #(d);
d <= Object(d);
trace #(deref d);
13.17. The rad() expression
The rad() expression converts an angle (degrees) to radian measure:

float f = sin(rad(90));
13.18. The rgb() expression
The rgb() expression packs three 8bit values into a 32bit integer value:

int r=$11, g=$22, b=$33;
int argb32 = rgb(r, g, b); // argb32 => 0xFF112233;

Integer io = argb32;
print io.printf("0x%08x");
13.19. The rand() expression
The rand() expression returns a random int or float value that ranges between 0 and the given value:

int i = rand(10) - 5; // random int value between -5 and 5
float f = rand(10.0); // random float value between -5.0 and 5.0
print i;
print f;
13.20. The round() expression
The round() expression rounds a float value to the next smaller or bigger value:

float f = round(-0.5);
13.21. The sin() expression
The sin() expression returns the sine for an angle in radian measure:

float f = sin(PI);
13.22. The sqrt() expression
The sqrt() expression returns the square root of an int or float value:

int i = sqrt(64);
float f = sqrt(1.52399025);
13.23. The String() expression
The String() expression typecasts a value to a String value:

String s = String(42);

If the value is already a String and not deletable, the String() expression will create a copy of the String :

String s;
trace #(s);
s <= String("hello, world.");
trace #(deref s);
13.24. The tan() expression
The tan() expression returns the tangens of a float value:

float f = tan(rad(20));
float g = sin(rad(20)) / cos(rad(20));
13.25. The tcchar() expression
The tcchar() expression converts an ASCII character to a String that only consists of that character:

String s = tcchar(65); // s => "A"
13.26. The typeid() expression
The typeid() expression returns the type identifier for a value:

int t0 = typeid(void);
int t1 = typeid(42);
int t2 = typeid(PI);
int t3 = typeid(null);
int t4 = typeid("hello, world.");
13.27. The typename() expression
The typename() expression returns the atomic or C++ class type name for a value:

String t0 = typename(void);
String t1 = typename(42);
String t2 = typename(PI);
String t3 = typename(null);
String t4 = typename("hello, world.");

The C++ class type name for a script class is Class. Use the yacMetaClassName() method to obtain the actual script class name.

class MyClass { }
trace (new MyClass()).yacMetaClassName();

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