1 | if | conditional expression |
---|---|---|
2 | else | decision block |
3 | ladder | conditional selector |
3 | match | value based selector |
4 | loop | unconditional repetition |
5 | while | conditional repetition |
6 | for | range controlled repetition |
Keyword "if" establish a conditional statement. Also it can be used in expressions. A conditional statement can be a simple statement or a block statement. You can use "if" after a simple statement or before a block statement.
This is syntax for a simple statement with conditional execution. It enable or prevent a statement to be executed. It can not be used for block statements.
# conditioned statement
statement if boolean_variable;
statement if boolean_expression;
Next examples show how we can use conditional to print something when expression is fulfilled.
# conditional print
print "a is even" if (a % 2 = 0);
print "a is odd" if (a % 2 != 0);
In next pattern we use "if/else" keywords to create a decision fork.
decision diagram
# dual path decision
begin [label]:
** local scope
...
if expression then
** true branch
...
else
** false branch
...
done [label];
A ladder is a conditional multi-path selector based on exclusive conditions. Only one branch is executed. If no condition is satisfied the alternative branch is executed. Alternative branch is optional.
decision ladder
#selection ladder
begin [label]:
** local variables
...
if condition_1 then
** first branch
...
else if condition_2 then
** second branch
...
else if condition_3 then
** third branch
...
[else]
** alternative branch
...
done [label];
Notes: Previous pattern show a complex situation having several conditions in cascade. Cases should be exclusive and most probable case should be evaluated first. Last block, after else is optional. Also, the local scope is optional.
This is a multi-path selector similar to switch also named: jump table. It two variants: "all" or "one". That is optional keyword. If used, ALL will evaluate all "when" values it may be matching multiple when blocks. If "one" is used (this is the default), only first block that has a matching value will be executed and the rest are ignored even if a second match exist. The second match should not be present though and is probably a mistake!
Match Diagram
# Define a selector variable
class Type = {V1, V2, V3, V4} <: Ordinal;
...
process
new s := V1;
** create match selector
match s [all | one] [Type]:
** declare locals
...
when V1 then
** first path
...
[break];
when V1, V2 then
** second path
...
when [any | other] then
** V3 or V4 found
...
done [Type];
return;
The compiler will generate a warning message if not all cases are covered and you do not have use the default block. That is maybe an error but not necesarly. Maybe the type was modified.
Match can be used with any data type not only ordinal. When you use other data type, the Type do not have to be specified. It can be inferred from the variable type.
This is a repetitive block statement. The loop is executed until a "break" statement is encounter. The break can be conditioned by "if". This is called an "interruption". You can use keyword "repeat"with conditional "if" to restart the loop early and skip several statements. This is called a "shortcut".
infinite loop
#infinite loop
cycle [label]:
** declare control variable
...
loop
** loop shortcut
skip [label] [if condition] ;
...
** early interruption
stop [label] [if condition];
...
repeat [label] [if condition];
Execute a block of code as long as one condition is true. When the condition become false the repetitive block stops and block "else" is executed. If the condition is never true only the "else" block is executed.
while loop
#conditional loop
cycle [label]:
** declare control variables
...
while condition loop
** shortcut iteration
skip if condition;
...
** early interruption
stop if condition;
...
then
** alternative path
...
repeat [label] [if condition];
/** This driver demonstrate
how to visit members of a List */
driver while_demo:
** create a shared list
set this := ("a","b","c","d","e");
process
** start unlabeled cycle
cycle:
** volatile variables
new i := 0 : Integer;
new e : Symbol;
while i < this.length() loop
let e := this[i];
let i += 1;
if e >= "c" then
write e;
write ',' if e is not this.tail;
done;
then
write "i = " + i;
repeat;
** flush the write buffer
print; -- "c","d","e"
return;
"c","d","e" i = 5
This statement use one control variables to visit elements in a collection or domain. First use-case of this is to iterate over a range of numbers. In Eve the range is represented as (min..nax).
for ... loop
#for loop syntax
cycle [label]:
new var := 0;
for var in (min..max) loop
** block statements;
...
** next iteration
next if condition;
...
** early interruption
stop if condition;
...
repeat [label];
Example of range iteration using step ratio 2:
#example of range iteration
cycle:
new i :Integer;
for i in (1..10:2) loop
** write only odd numbers
write i;
write ',' if (i < 9);
repeat;
print;
1,3,5,7,9
Read next: Processing