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 |
|
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]
|
|
Declaring assignments declare a variable to hold only instances of a given class. See * () for examples and details.
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
|
|
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.
|
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.
|
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.
|
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.
|
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
print i-65.2 5.4 5.6 5.8 → 8.881784E-16
|
|
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 |
|
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 |
|
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.
|
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.
|
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:
|
print 13.5 → 13.5
print 3e11→ 300000000000
print -3e11; // -300000000000 has 13 characters→ -3E+11
|
|
print "Hello,", 'world!' → Hello, world!
|
|
print 1 < 3 → true
|
|
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>] |
|
f=&io.read; print f → &io.read
|
|
f=io.create("sample.xml"); print f → stream@41255c
|
|