Prev: Expressions
Statements
Statements are the smallest unit of execution in m. Statements change values of variables, call functions and control the flow of execution. Most of the time, several statements are executed in a sequence, one after the other.
A sequence of statements is called a statement list. Within a statement list, statements must be separated by a semicolon. This is the only place where m requires a semicolon.
In particular, there is no need to put a semicolon at the end of each statement[4]. However, ending or preceding each statement with a semicolon is not an error, it just produces empty statements which are ignored during execution.
For instance, the following two code fragments are completely equivalent:
use math;
function f(x);
return x*x*math.exp(x/40);
end;
for x=0 to 10 by 0.1 do;
y=f(x);
print x,y;
end;
|
use math
function f(x)
return x*x*math.exp(x/40)
end
for x=0 to 10 by 0.1 do
y=f(x); // this is the only required semicolon
print x,y
end
|
| | |
Statement := |
Assignment | DeclaringAssignment | ConstAssignment |
Increment | Expression |
IfStatement | WhileStatement | DoStatement | ForStatement |
BreakStatement | ReturnStatement | ThrowStatement |
TryStatement | PrintStatement .
StatementList = Statement { ';' Statement } .
|
|
Assignments
This statement type assigns the value of an expression to a variable or array element. It also declares the variable if it didn't occur in the preceding code yet. A variable can be reassigned as often as required, generally also with values of different types (although this is not considered good programming practice, and there is an exception: variables declared to hold instances of a given class can only be assigned such instances, or null).
x = 28*3;
x = ["a", "b", "c"];
x[1] = "b2";
x[2] = null;
x["new"] = "d";
print x
→ [a,b,null,d]
|
When assigning an array, the array is not copied: the expression and the variable or array element it is assigned to will denote the same array:
ma = ["Ma", "Dalton"];
joe = ma; // joe and ma refer to the same array
joe[0] = "Joe"; // this also modifies ma
print ma
→ [Joe,Dalton]
|
array.copy copies an array element by element.
If a variable is being declared, i.e. didn't occur in the preceding code, it can be marked as constant by prefixing the assignment with const. Array elements cannot be marked constant: a constant array can be modified after it has been assigned to another variable.
const C = 2.997e8;
C = 4; // illegal
const A = [1, 2, 3];
A[1] = 7; // illegal
b = A;
b[1] = 7; // perfectly legal, also modifies A[1]
print A
→ [1,7,3]
|
| | |
Assignment := Designator '=' Expression .
DeclaringAssignment := VariableDeclaration '=' Expression .
ConstAssignment := const VariableDeclaration '=' Expression .
VariableDeclaration := Identifier OptionalType .
OptionalType := [ ':' ClassIdentifier ] .
|
|
Declaring assignments declare a variable to hold only instances of a given class. See * () for examples and details.
Increment
This statement type increments or decrements a numeric variable by a numeric expression (+=, -=), or simply by one (++, --). These statements are just shorthand notations for full assignments[5]:
| Increment | Equivalent Assignment |
| x += expr | x = x + expr |
| x -= expr | x = x - expr |
| x++ | x = x + 1 |
| x-- | x = x - 1 |
| |
s=7;
s+=13;
s--;
print s
→ 19
|
| | |
Increment := Designator
('+=' Expression | '-=' Expression | '++' | '--') .
|
|
If Statement
An if statement executes some code depending on the value of boolean expressions (e.g. comparisons). Its simplest form executes statements (the print in the example) if a condition (a > 13) evaluates to true:
a=15;
if a > 13 then
print a + " is greater than 13"
end
→ 15 is greater than 13
|
An optional else block may contain statements which are executed if the condition evaluates to false:
a=9;
if a > 13 then
print a + " is greater than 13"
else
print a + " is less than 13"
end
→ 9 is less than 13
|
To test for more than just two alternatives, an arbitrary number of elsif blocks can be added. These must occur after the if/then and before the (optional) else block:
a=13;
if a > 14 then
print a + " is greater than 14"
elsif a < 13 then
print a + " is less than 13"
elsif a = 13 then
print a + " is equal to 13"
else
print a + " must be 14"
end
→ 13 is equal to 13
|
If any of the conditions evaluates to true, the remaining conditions are not evaluated.
Throws ExcNotBoolean if any of the evaluated conditions is not boolean.
| | |
IfStatement := if Expression then StatementList
{elsif Expression then StatementList}
[else StatementList]
end .
|
|
While Statement
The while statement repeats some code as long as a condition evaluates to true. The condition is tested before each repetition.
a=[430, 241, 187, 53, -1, 17];
s=0; i=0;
while i<len(a) and a[i]>=0 do
s += a[i]; i++
end;
print i, s
→ 4 911
|
Throws ExcNotBoolean if the condition is not boolean.
| | |
WhileStatement := while Expression do StatementList end .
|
|
Do-Until Statement
The do statement repeats some code until a condition evaluates to true. The condition is tested after each repetition.
x=2; y=x;
do
y0=y; y=(y+x/y)/2
until y>=y0;
print y, y*y
→ 1.4142135624 2
|
Throws ExcNotBoolean if the condition is not boolean.
| | |
DoStatement := do StatementList until Expression .
|
|
For Statement
The for statement lets an index variable iterate through a range of numbers or through the elements of an array, and executes some code for each value. The index variable must be a simple variable, either local in the current function or global in the current module. It cannot be an array element or a variable in another module.
- The for loop iterating through a range of numbers looks as follows:
for >index=>StartExpr to >EndExpr [by >IncrExpr] do
>statements
end
|
The range is defined by StartExpr and EndExpr, and an optional IncrExpr defining the amount by which the variable is incremented after each iteration. IncrExpr defaults to 1.
All three expressions are evaluated only once, before the loop is entered.
The loop exits if index > EndExpr (if IncrExpr > 0), or if index < EndExpr (if IncrExpr <= 0).
for x=5 to 6 by 0.25 do
print x*x
end
→ 25
27.5625
30.25
33.0625
36
|
A for loop over a range is equivalent to the following while loop:
>index=>StartExpr; e=>EndExpr; d=>IncrExpr;
while d>0 and >index <= e or d<=0 and >index >= e do
>statements;
>index += d
end
|
Care must be taken when using for loops with fractional numbers: rounding errors may lead to surprising results:
for i=5 to 6 by 0.2 do
print i
end
→ 5
5.2
5.4
5.6
5.8
print i-6
→ 8.881784E-16
|
- The for loop iterating through the elements of an array looks as follows:
for >index in >ArrayExpr do
>statements
end
|
The array is defined by ArrayExpr. index iterates through all elements of the array, starting at index 0 and ending with the last element (index len(ArrayExpr)-1).
a=[430, 241, 187, 53, -1, 17]; s=0;
for x in a do
s += x
end;
print s
→ 927
|
A for loop over an array is equivalent to the following while loop:
>a=>ArrayExpr; i=0;
while i<len(a) do
>index = a[i];
>statements;
i++
end
|
| | |
ForStatement := for IndexVariable
( = Expression to Expression [by Expression] | in Expression )
do StatementList end .
IndexVariable := Identifier .
|
|
Case Statement
The case statement executes a sequence of statements depending on the value of an expression matching the tag or tags of this sequence. It looks as follows:
case >Expression
in >TagExpr1:
>statements1
in >TagExpr2a, >TagExpr2b:
>statements2
else
>statements3
end
|
This case statement is equivalent to the following if statement:
>x=>Expression;
if >x=>TagExpr1 then
>statements1
elsif >x=>TagExpr2a or >x=>TagExpr2b then
>statements2
else
>statements3
end
|
>Expression is evaluated only once.
The tags (>TagExpr1, >TagExpr2a,...) are evaluated when they are tested. Once a matching tag has been found, the remaining tags are not evaluated.
Equality of expression and tag is tested using the = operator (see section * ()). Arrays are thus not compared elementwise, and string comparison is case sensitive.
The following example prints a different message for different values of i:
for i=1 to 10 do
case i
in 1:
print i,"is somewhat prime"
in 2, 3, 5, 7:
print i,"is prime"
else
print i,"is not prime"
end
end
→ 1 is somewhat prime
2 is prime
3 is prime
4 is not prime
5 is prime
6 is not prime
7 is prime
8 is not prime
9 is
|
| | |
CaseStatement := case Expression
{ in TagList ":" StatementList }
[ else StatementList ] end .
TagList := Expression { "," Expression } .
|
|
Break Statement
The break statement exits from the loop (while, do-until, for) containing it, and continues execution after the end of the loop.
x=-3;
while true do
if x<0 then break end;
y=x; x=x/2+1/x;
if x>=y then break end
end;
print x, x*x
→ -3 9
|
break always exits the innermost loop containing it. Breaking out of an outer loop is not possible.
| | |
BreakStatement := break .
|
|
Return Statement
The return statement returns the value of an expression as a function result. Outside a function, it ends execution of the module's body; the return value is discarded.
See section * () for examples.
| | |
ReturnStatement := return Expression .
|
|
print Statement
The print statement provides a simple way of producing output. It writes a line with zero, one or several expressions to the console. The expressions are separated by single spaces. print without expressions just outputs a new line.
print "odd:",3/7
→ odd: 0.4285714286
print
→
|
Expressions are formatted depending on their type:
- A Number is printed as string of length 12 or less (and rounded, if necessary). If the value cannot be represented within 12 characters, scientific representation is chosen.
print 13.5
→ 13.5
print 3e11
→ 300000000000
print -3e11; // -300000000000 has 13 characters
→ -3E+11
|
- A String is printed as is.
print "Hello,", 'world!'
→ Hello, world!
|
- A Boolean is printed as "true" or "false":
- An Array is printed elementwise, up to a length of 128. Elements which are themselves arrays are printed as [...<len>].
a=[];
for i=1 to 10 do append(a, i) end;
print a
→ [1,2,3,4,5,6,7,8,9,10]
a[0]=a;
print a
→ [[...<10>],2,3,4,5,6,7,8,9,10]
for i=11 to 100 do append(a, i) end;
print a
→ [[...<100>],2,3,4,5,6,7,8,9,10,11,12,13,14,
15,16,17,18,19,20,21,22,23,24,25,26,27,28,
29,30,31,32,33,34,35,36,37,38,39,...<100>]
|
- A Function Reference is printed as &module.function.
f=&io.read;
print f
→ &io.read
|
- The Null value is printed as null.
- A Native Object is printed as type@address. type defines the object type, address is the location of the underlying native object in memory.
f=io.create("sample.xml");
print f
→ stream@41255c
|
For finer control over output formatting, see
.str and module
io.
| | |
PrintStatement := 'print' [ Expression { ',' Expression } ] .
|
|
Next: Functions© 2004-2011 airbit AG, CH-8008 Zürich
Document AB-M-REF-887