The Mathemagix syntax

This document describes the syntax of the Mathemagix interpreter, provided by the executable mmx-light, whose usage can be obtained with the –help option. Input is read on the standard input by default. If Readline has been enabled then newline insertion in interactive mode is possible by typing Meta-Return.

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_?]*. 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

In addition to identifiers, Mathemagix provides 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.

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 "<=>"

SEQOR "or", OR "\/", XOR "xor"

SEQAND "and", AND "/\"

EQUAL "=", LESS "<", LEQ "<=", GREATER ">", GEQ ">=", NOT_EQUAL "!=", NOT_LESS "!<", NOT_LEQ "!<=", NOT_GREATER "!>", NOT_GEQ "!>="

INTO "->", MAPSTO ":->"

RANGE "::", RANGEEQ ".."

PLUS "+", MINUS "-" (binary), OPLUS "@+", OMINUS "@-"

TIMES "*", OVER "/", OTIMES "@*", OOVER "@/", DIV "div", MOD "mod", COMPOSE "@"

NOT "!" (infix unitary), MINUS "-" (infix unitary), OMINUS "@-" (infix unitary),

INC "++" (infix unitary), DEC "–" (infix unitary), SIZE "#" (infix unitary)

POWER "^"

INC "++" (postfix unitary), DEC "–" (postfix unitary), NOT "!" (postfix unitary), QUOTE "'" (postfix unitary), BACKQUOTE “‘” (postfix unitary),

TILDA “~” (postifix unitary), ACCESS “.”

2.1.Ranges

a..b means the range [a,b], while a::b stands for the half open range [a,b).

3.Sequences

Tuples are written inside (...). Elements are separated by ,. Row-tuples rows are separated by ;.

Lists are written inside [...].

v := (1, 2, 3);

x := ("a", 3, (7, 0.4));

M := (1, 2; 3, 4; 5, 6);

l := [2, 3, 5, 7, 11];

Automatic constructions are possible through the | resp. || notation:

v := ( i^2 | i in 1..3 );

l := [ i * j | i in 1..3, j in 1..4 ];

m := matrix (i*j | i in 1..5 || j in 1..5)

The default type of lists used in the interpreter is List(Generic).

4.Tables

Tables allow to store the association between keys of one type to values of another type. They are defined by providing a default value. In the following exemple, the default value is 1:

t := table(1);

The definition of specific values is done as follows:

t[1] := -3;

t[34] := 2;

The default type of tables used in the interpreter is Table(Generic,Generic).

5.Functions and macros

5.1.Function definitions

Any function definition can be preceded by quantifiers forall(...) or exists(...).

A function definition is done as follows:

name (arg1: type1, arg2: type2, ...): returned_type == ...

Mathemagix also provides a syntax for lambda expressions:

lambda (arg1: type1, arg2: type2, ...): returned_type do ...

Notice that any of the type specifications can be omitted, in which case the type is assumed to be Generic. Expression macros can be defined by using macro instead of lambda.

When function or macro have only one argument, () can be omited.

square x ==> x^2; // macro for squaring

discr (a, b, c) == b^2 - 4*a*c;

forall (R)

gcd (p: Polynomial(R), q: Polynomial(R)): Polynomial(R) == {...}

5.2.Function Calls

A function or a macro foo is called in the usual way: foo(arg1, arg2,...).

If foo is unitary then () can be omited, but note that foo a b c is equivalent to foo(a(b(c))). Function call is always by value.

6.Control flow

6.1.Sequence of Instructions

Instructions are separated with ;.

x := 1;

y := 3;

z := x*y;

6.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" }

6.3.Case separation

6.4.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 }

7.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.

}/

8.Technical Notes

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