Overview
Statements are very close to those found in C or Java:
- Expression: expression statement
- Locals: declare a local variable
- Return: exit from a method
- If/Else: conditional branching
- While: conditional looping
- For: just like C
for
statement - Foreach: array iteration
- Goto: unconditional branching
- Switch: jump tables
- Assert: used for unit testing
Unlike C or Java, statements are not required to be terminated with a semicolon. By convention they are terminated with a newline, although they can also be terminated with a semicolon or "}". All of these are valid statements:
if (c) { doSomething() orAnother() } if (c) { doSomething(); orAnother(); } if (c) { doSomething(); orAnother() }
Note that Sedona's grammar is not always unambiguous when terminating a
statement with a newline. So on occasion you might be required to use
a semicolon. If you get a weird compiler error you don't understand
try sticking in a semicolon. This might happen if you have a statement
that starts with a parenthesis such as ((Type)x).something()
.
Expression
The most common type of statements are stand alone expressions. The following expressions can be used as a statement:
- Assignment:
x = y, x++, x[i] = y, x.f += y
- Method calls:
x()
Local Variables
Local variables are declared as follows:
float f int i = 5 Component c = doSomething()
Local variables are scoped within their block - they are not visible to parent blocks. A local variable must be definitely assigned before it is used or the compiler will generate an error. Sedona doesn't currently support declaring multiple local variables in one statement like C or Java.
Return
The return statement is used to exit a method. If a return is used in a non-void method, then it must specify the expression to return:
// void return return // non-void return return expr
If/Else
Sedona supports C style if/else statements:
// if, no else if (cond) block // if-else if (cond) block else block // if, if-else, else if (cond) block else if (cond) block else block
Like C/Java, each block may be a single statement, or a block of statements wrapped in "{ }" curly braces.
Looping
Sedona supports the traditional while, do-while, and for loops of C like languages. Sedona also has a foreach statement for iterating arrays. In each case, the repeated code can be a single statement or a sequence of statements wrapped in "{ }" curly braces.
While
The while statement is used to loop while a boolean expression evaluates to true:
while (cond) block
Do While
The do-while statement works just like the while loop, except the condition is evaluated at the end of the block. It is typically used when you wish to guarantee the loops executes at least once:
do block while (cond)
For
The for statement works like a while loop except it allows an initialization expression and an update expression that executes after each loop iteration:
for (init; cond; update) block // example - prints 0 to 4 for (int i=0; i<5; ++i) Sys.out.print("i = $i\n")
Any of the init, cond, or update expressions may be omitted. If the cond is omitted, then it defaults to true and the loop must be terminated with a break or return statement inside the block.
Foreach
Sedona provides the foreach statement to iterate through an array. Using the foreach statement is more efficient than using a for loop because is compiles into a specialized instruction. The foreach statement takes a local variable declaration, an array to iterate, and an optional array length:
foreach (type var : array) block foreach (type var : array, length) block // example - prints each kit name and version foreach (Kit kit : Sys.kits, Sys.kitsLen) Sys.out.print("$kit.name $kit.version").nl()
The length may be omitted only if the compiler can infer the length of the array from its declaration.
Break
The break statement is used to exit a loop. It may be used with any looping statement (while, do-while, for, and foreach):
// prints 0 to 3, then breaks for (int i=0; i<10; ++i) { if (i == 4) break Sys.out.print("i=$i\n") }
If a break is used inside nested loops, it breaks from the inner-most loop. Labeled breaks are not supported.
Continue
The continue statement causes the next iteration of the containing loop to begin. For a while and do-while, the loop condition is executed immediately. For a for or foreach loop, control is passed to the increment step.
// prints 0, 1, 3 (skips 2) for (int i=0; i<4; ++i) { if (i == 2) continue Sys.out.print("i=$i\n") }
If a continue is used inside nested loops, it continues the inner-most loop. Labeled continues are not supported.
Goto
The goto statement performs an unconditional jump to a labeled statement within the same method:
// this method always returns "y" static Str f() { goto foo return "x" foo: return "y" }
Switch
The switch statement works just like C and Java. It evaluates an integer expression and jumps to a cast label:
Str s = null switch (i) { case 0: case 1: s = "0 or 1" break case 2: s = "2" break default: s = "not 0, 1, or 2" }
Like C, case blocks fall through to the next case block - use a break statement to break out of the switch statement. The default block handles any value without an matching case label. The default block is optional; if omitted then unmatched values fall through to the next statement after the switch. However, if the default block exists, it must be the last label in the switch statement.
If the last case statement does not break and there is a default block, the last case statement will fall through into the default block.
switch(i) { case 0: reset() break case 1: init() // fall through to default block default: work() // whenever i is not zero }
Limits on Case Values
To reduce code size, case values must not be too widely spaced.
For a difference delta
between the minimum and maximum case values,
and total number of case values num
, at least
one of the following must be true:
-
delta <= 30
-
num*3 >= delta
if/else if/.../else
idiom.
Assert
The assert statement is used for unit testing.
assert(cond)
The condition must be a boolean expression. Failed assertions result
in a call to the Sedona VM's onAssertFailure
callback.
On most platforms, this will print a message to stdout. See
Porting for more details.