MPL2 Manual

Algebra - linear algebra primitives and basic algebraic algorithms.

Algorithms - general purpose algorithms.

Containers - collections of data items.

Control functions - stack, flow, and functional control.

Builtins - MPL Easy's common mathematical functions, bitwise and conditional operators, object control, flow control, utilities, memory management sections.

IDE is a web-based development environment for MPL Easy

Examples page provides some examples of how to use MPL Easy Language and demonstrates some key concepts.

Grammar - RR diagram is a visual representation of MPL Easy grammar and the corresponding .ebnf file.

Offline version of this site, that includes all documentation pages as well as in-browser IDE.

Basic syntax

MPL Easy language uses postfix notation. It means that we can put elements on top of stack and call operations without specifying arguments directly in the call syntax. Each operation works with stack contents. For example, in classic notation, we write

2+3*4

and it means that first, we calculate 3*4 because

*
has higher priority than
+
, and then we calculate 2+12. In postfix notation, this expression can be written as

2 3 4 * +

This snippet puts 2, 3, 4 to stack. Then

*
gets top two numbers from stack (these are 3 and 4), multiplies them, and pushes the result (12) back to stack. Stack now contains 2 and 12. Then
+
gets two numbers from stack and pushes the result of their addition (14) back to stack.
String literals are written in double quotes, e.g.
"some text"
.

Variables

Each word that ends with

:
is a new variable. When we write
name:
, we make a new variable ‘name’ and push it to a special ‘label stack’ (it is a different stack from the one mentioned above). This variable cannot be used yet and doesn't have any value. When we write
;
, the top value from stack is assigned to the top label from label stack.
For example:

a: 1;

creates variable with name

a
and value 1.

a:b:1;2;

creates two variables:

a
with value 2 and
b
with value 1, but

a:b:1 2;;

creates

a
with value 1 and
b
with value 2.

Brackets

(
)
are brackets for builtin-lists. Every stack value encountered between these brackets will be added to a list.
For example:

( 1 2 )

makes a builtin-list with two elements 1 and 2.

4 ( 3 - 2 )

makes a builtin-list with the same two elements 1 and 2 (1 will be pushed after calculating

4 3 -
)

"sl/control" useFile #for [times] combinator (2 [i 1 +] times)

again makes a builtin-list with the same two elements 1 and 2, because the inner loop pushes two numbers to stack.
You can access builtin-list elements by index

list: ( "one" 2 ); 0 list @ #stack: "one"
list: ( "one" 2 ); 1 0 list ! 0 list @ #stack: 1

{
}
are brackets for structures. Every label created between these brackets will be added to a structure as a field.
For example:

{ a: 1; b: 2; }

makes a structure with two fields with values 1 and 2. You can get them by index or by

.name
:

point: { a: 1; b: 2; }; point.a #stack: 1 1 point @ #stack: 1 2

You can also change any element of a structure by

.!name
:

point: { a: 1; b: 2; }; 3 point.!a point.a #stack: 3
1 { a:; b: 2; }

makes a structure with two fields,

a
with a value of 1 and
b
with a value of 2.

[
]
are brackets for code fragments. You can write any code between these brackets and then execute it by writing
call
.
For example:

1 [ 2 + ] call

pushes 3 to stack.

Special fields

CALL
- when a structure has a field with this name, pushing this structure to stack leads to invocation of the content of
CALL
field with structure's fields bound to the invocation scope.
Example:

a: { f:1; CALL: [f +]; }; 3 a #stack: 4

If you want push a structure to stack without calling the code, use

@
before the structure's name:

a: { f:1; CALL: [f +]; }; 3 @a #stack: 3 { f:1; CALL: [1 +]; }

PRE
- when a structure has a field with this name, pushing this structure to stack will immediately call the code in this field, check the result, and invoke
CALL
field if the result is TRUE or call the previous definition of the structure otherwise.
For more information, you can check out the description of pfunc or take a look at examples 40 and 41.
DIE
- when a structure has a field with this name, the code in this field will be called when we exit the code block where this structure was labeled and when there are no more references to it.

For more advanced examples, please visit examples page.