This section introduces the most basic notions to write urbiscript code. Some aspects are presented only minimally. The goal of this section is to bootstrap yourself with the urbiscript language, to be able to study more in-depth examples afterward.
Commenting your code is crucial, so let’s start by learning how to do this in urbiscript. Comments are ignored by the interpreter, and can be left as documentation, reminder, …urbiscript supports C and C++ style comments:
1;// This is a C++ style comment.[00000000] 1
2 +/* This is a C-style comment. */2;[00000000] 4/* Contrary to C/C++, this type of comment/* does nest */. */
3;[00000000] 3
As already seen, we can evaluate literal integers. urbiscript supports several other literals, such as:
These literal values can be obtained with the syntax presented below.
42;// Integer literal.[00000000] 42
3.14;// Floating point number literal.[00000000] 3.14"string";// Character string literal.[00000000] "string"
[1, 2,"a","b"];// List literal.[00000000] [1, 2, "a", "b"]
["a"=> 1,"b"=> 2];// Dictionary literal.[00000000] ["a" => 1, "b" => 2]
nil;
void;
This listing highlights some point:
You can call functions with the classical, mathematical notation.
cos(0);// Compute cosine[00000000] 1
max(1, 3);// Get the maximum of the arguments.[00000000] 3
max(1, 3, 4, 2);[00000000] 4
Again, the result of the evaluation are printed out. You can see here that function in urbiscript can be variadic, that is, take different number of arguments, such as the max function. Let’s now try the echo function, that prints out its argument.
The server prints out Hello world!, as expected. Note that this output is still prepended with the time stamp. Since echo returns void, no evaluation result is printed.
Variables can be introduced with the var keyword, given a name and an initial value. They can be assigned new values with the = operator.
Note that, just as in C ++, assignments return the (right-hand side) value, so you can write code like “x = y = 0”. The rule for valid identifiers is also the same as in C ++: they may contain alphanumeric characters and underscores, but they may not start with a digit.
You may omit the initialization value, in which case it defaults to void.
var y;
y;// Remember, the interpreter remains silent// because void is printed out as nothing.// You can convince yourself that y is actually// void with the following methods.
y.asString;[00000000] "void"
y.isVoid;[00000000] true
Scopes are introduced with curly brackets ({}). They can contain any number of statements. Variables declared in a scope only exist within this scope.
Note that the interpreter waits for the whole scope to be inputted to evaluate it. Also note the mandatory terminating semicolon after the closing curly bracket.
Methods are called on objects with the dot (.) notation as in C ++. Method calls can be chained. Methods with no arguments don’t require the parentheses.
0.cos();[00000000] 1"a-b-c".split("-");[00000000] ["a", "b", "c"]// Empty parentheses are optional"foo".length();[00000000] 3"foo".length;[00000000] 3// Method call can be chained"".length.cos;[00000000] 1
In obj.method, we say that obj is the target, and that we are sending him the method message.
You know how to call routines, let’s learn how to write some. Functions can be declared thanks to the function keyword, followed by the comma separated, parentheses surrounded list of formal arguments, and the body between curly brackets.
// Define myFunction
function myFunction()
{
echo("Hello world");
echo("from my function!");
};[00000000] function () {echo("Hello world");echo("from my function!");}
// Invoke it
myFunction();[00000000] *** Hello world[00000000] *** from my function!
Note the strange output after you defined the function. urbiscript seems to be printing the function you just typed in again. This is because a function definition evaluates to the freshly created function.
Functions are first class citizen: they are values, just as 0 or "foobar". The evaluation of a function definition yields the new function, and as always, the interpreter prints out the evaluation result, thus showing you the function again:
// Work in a scope.
{
// Define f
function f()
{
echo("f")
};
// This does not invoke f, it returns its value.
f;
};[00000000] function () {echo("f")}
{
// Define f
function f()
{
echo("Hello World");
};
// This actually calls f
f();
};[00000000] *** Hello World
Here you can see that f is actually a simple value. You can just evaluate it to see its value, that is, its body. By adding the parentheses, you can actually call the function. This is a difference with methods calling, where empty parentheses are optional: method are always evaluated, you cannot retrieve their functional value — of course, you can with a different construct, but that’s not the point here.
Since this output is often irrelevant, most of the time it is hidden in this documentation using the |{}; trick (or even |;): when evaluating code | {};, the server first evaluates code, then evaluates {} and return its value, void, which prints to nothing.
The return keyword enables to return a value from the function. If no return statement is executed, the evaluation of the last expression is returned.
You’re now up and running with basic urbiscript code, and we can dive in details into advanced urbiscript code.