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]:

IncrementEquivalent Assignment
x += exprx = x + expr
x -= exprx = 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.

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 TagExpr2aTagExpr2b:
  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:

For finer control over output formatting, see .str and module io.

PrintStatement := 'print' [ Expression { ',' Expression } ] . 


© 2004-2010 airbit AG, CH-8008 Zürich
Document AB-M-REF-869