Declaration and control sequences

1.Variables and constants

1.1.Identifiers

Identifiers are formed using letters, digits and the special characters _ and ?. Identifiers must start with a letter or _. Identifiers match the [a-zA-Z_]+[a-zA-Z0-9_?]* regular expression.

Examples of identifiers are x, y2, my_var and test?.

Some special predefined constants are:

true

The boolean constant true.

false

The boolean constant false.

mmout

The standard output stream.

mmerr

The standard error stream.

Notice that streams can be used with the operators << as in C++:

mmout << 3 << "\n";

1.2.Literals

mmx-light supports three types of literal constants:

String literals

Strings can be braced into double quotes " … ". Inside such a string a double quote must be blackslashed. In order to avoid blackslashing one can use the stronger string delimiters /" … "/.

s1 := "This is a string";
s2 := "Print \"foo\"";
s2 := /"Print "foo"/;

Integer literals

An integer literal is a sequence of digits, possible preceded by a minus sign. It matches the regular expression [-]?[0-9]+. Examples: 123456789123456789, -123.

Floating literals

A floating literal is a sequence of digits with a decimal point inside and an optional exponent. It matches the regular expression [-]?[0-9]+[.][0-9]+[[eE][-]?[0-9]+]?. Some examples:

z := 0.0;
w := -3.14159;
x := 1.11e2007

Note that 0. is not permited, one must write 0.0.

1.3.Definition and assignation

To assign a value to a variable, we use the operator :=, while constant values are defined by the operator ==, and cannot be modified hereafter.

Mmx]  
a1 := 1

Mmx]  
a1_? == 2; a1_?

Mmx]  
cst: Int == 11111*111111

Mmx]  
mut: Int := 1010*1234

Mmx]  
cst := - cst

:: ,

cst := - cst

~~~

Mmx]  
mut := - mut

2.Operators

Here we list the operators in increasing priority order, together with their internal names:

== DEFINE
:= ASSIGN
==> DEFINE_MACRO
:=> ASSIGN_MACRO
+= PLUS_ASSIGN
-= MINUS_ASSIGN
*= TIMES_ASSIGN
/= OVER_ASSIGN
<< LEFT_FLUX
<<* LEFT_FLUX_VAR
<<% LEFT_FLUX_STR
>> RIGHT_FLUX
=> IMPLIES
<=> EQUIVALENT
or SEQOR
OR
xor XOR
and SEQAND
AND
= EQUAL
< LESS
<= LEQ
> GREATER
>= GEQ
!= NOT_EQUAL
!< NOT_LESS
!<= NOT_LEQ
!> NOT_GREATER
!>= NOT_GEQ
-> INTO
:-> MAPSTO
.. RANGE
to RANGEEQ
+ PLUS
- MINUS
@+ OPLUS
@- OMINUS
* TIMES
/ OVER
@* OTIMES
@/ OOVER
div DIV
mod MOD
@ COMPOSE
! NOT infix unary
- MINUS infix unary
@- OMINUS infix unary
++ INC infix unary
DEC infix unary
# SIZE infix unary
^ POWER
++ INC postfix unary
DEC postfix unary
! NOT postfix unary
' QUOTE postfix unary
BACKQUOTE postfix unary
~ TILDA postfix unary
. ACCESS

Whenever writing a complex expression you should carefully consider these priority rules in order to avoid using extra parentheses. For example the expression

if ((a*b)+(c)>(d)) then foo ();

should be better written

if a*b + c > d then foo ();

The Mathemagix grammar is specified in the file mmx-parser.ypp of the basix module.

3.Control flow

3.1.Sequence of Instructions

Instructions are separated with ;.

x := 1;
y := 3;
z := x*y;

3.2.Conditionals

The construction is as follows: if condition then block1 else block2.

condition is any expression that evaluates to a boolean. block1 and block2 are either one instruction or a block of instructions braced into {}. The else part is optional.

if true then 1;
if a = b then 1 else 2;
if i = 0 then { x := 1; y := 2} else { z := 3; mmerr << "error" }

For the sake of readability do not write

if a = 0 then { b := 0 }

but

if a = 0 then b := 0;

instead, since {…} are not needed for a block with one instruction only. Notice that, according to the priority rules of the operators listed above, the expression

if ((a = 0) and (b = 0)) then foo ();

should be written

if a = 0 and b = 0 then foo ();

for the sake of readability.

3.3.Loops

Loops are constructed as follows: [for E1] [while E2] [until E3] [step E4] do block.

Here [] means that the expression is optional. block is an instruction or a sequence of instruction delimited by {}. break exits the loop, and continue goes to the next step of the loop.

do mmout << "no end "; // This loop has no end
for i in 1..3 do mmout << i << " ";
i := 0; while i < 0 do { mmout << i << " "; i := i + 1 }

4.Comments

Comments starting with // extend to the end of the physical line. Such a comment may appear at the start of a line or following whitespace or code, but not within a string literal. Multi-line comments must be braced into /{ … }/ and can be nested.

x := 1; // Assign 1 to x.

y := 2;
/{ This
   is multi-line
   comment about y.
}/
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License. If you don't have this file, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.