Modula-2 Advanced Syntax Reference
Program Structure
MODULE ModuleName;
(* This program does ... *) documentation,
comment
FROM IO IMPORT WrStr, WrLn; import
general
procedures
CONST PI =
3.1416; constante-declarations
TYPE HoursSb=[0...24]; type-declarations
PROCEDURE Bla
... procedures
...
END Bla;
VAR aNumber: HoursSb; variabele-declarations
BEGIN
...
statements
END ModuleName.
Single Types
- CARDINAL
- INTEGER
- to mix cardinals and integers in expressions: convert them
with VAL(type, variable)
- eg: int = int - VAL(INTEGER, card);
- eg: card = card DIV VAL(CARDINAL, int);
- REAL
- real constant format: -4.32E-3 (exponential
part is
optional)
- real := 4; is illegal, this should be :
real
:=
4.0;
- BOOLEAN: values FALSE (0) & TRUE (1),
boolean
operators NOT, AND, OR
- CHAR: characterconstant: 'A', stringconstant "A
few
words."
- character := CHR(cardinal); cardinal := ORD(character);
ASCII
conversion
- character := CAP(character); conversion of
character
to its capital
- user-defined single types
- enumerated type:
- TYPE DayEn = (MO, TU, ...);
- MO, TU, ... will be defined as constants,
starting from 0
- operators ORD & VAL
- ORD(TU) returns 1
- VAL to convert a cardinal into an enum: day
:= VAL(DayEn, 1);
- subrange type:
- TYPE MonthSb = [1..12];
- TYPE WeekdaySb = [MO..FR];
- MO & FR must be defined constants
Assignment: variable := value;
Cardinals, integers, booleans, chars, enums and subranges are ordinal
types.
Ordinal operators (like <, MAX, ...) apply.
All variables at module level are initialised with a 0 value, local
variables
of a procedure NOT!!
Structured Types
- ARRAY
- variable declaration: VAR Array1: ARRAY MonthSb OF
CARDINAL;
- with: TYPE MonthSb = [1..12];
- an enum type is also possible to indicate an index range
- type declaration: TYPE StringAr = ARRAY[1..30] OF CHAR;
- use: VAR word1 : StringAr;
- element of array: word1[2] := 'a';
- special array: string (ARRAY OF CHARs)
- assignment: str := "bla";
- a 0 (not the letter '0') is placed in the array after the
last character to indicate the end of the string.
- multidimensional array :
- VAR matrix10by20: ARRAY [1..10] OF ARRAY[1..20] OF
CARDINAL;
- identical declaration: VAR matrix10by20:
ARRAY [1..10], [1..20] OF CARDINAL;
- use: matrix10by20[5, 15] := 7; or
matrix10by20[5][15] := 7;
- passing arrays as arguments of procedures: as array type or as
open array (without indeces [1..20])
- open array: array is indexed starting from 0 until HIGH(arr)
- HIGH() only for open arrays
- RECORD
- type declaration:
- TYPE PersonRc = RECORD
-
name,
firstName: ARRAY[1..35] OF CHAR;
-
length:
CARDINAL;
- END;
- variable declaration: VAR jan : PersonRc;
- use: jan.name := "Lemeire"; jan.firstName :=
"Jan"; jan.length := 190;
- use of WITH:
- WITH jan DO
- name := "Lemeire";
- firstName := "Jan";
- length := 190;
- END;
- record assignment is possible (rec1 := rec2;), but
record
comparison not (rec1 = rec2)!
- for comparison: compare field by field: (rec1.a =
rec2.a) AND (rec1.b = rec2.b)
Procedures
PROCEDURE MyFunction(inputVariable1, VAR inputVariable2: CARDINAL;
inputVariable3: WeekdayEn): BOOLEAN;
VAR result: BOOLEAN; variabele-declarations
BEGIN
...
statements
RETURN result;
END MyFunction;
- 2 types:
- with returnvariable: RETURN value;
- you may use multiple RETURN statements, but the procedure
stops immediately after a return
- without returnvariable
- you may use RETURN; to quit the procedure.
- InputVariables can passed
- by value (default): will not change outside
- by var: will change outside
- call the procedure with a variable (or compiler gives error
"is not
an object")
- ex: procedure call "MyVarProcedure(n + 1)" is not
possible,
'n + 1' is not a variable
- Call a procedure:
- resultVariable := MyFunction(cardinalVariable1,
cardinalVariable2, MONDAY);
- Watch Out: To return an array or to pass an array as argument:
- use an ARRAY type
- not PROCEDURE bla():
ARRAY[1..SIZE] OF
CARDINAL
- but TYPE CardAr = ARRAY[1..10]
OF CARDINAL;
- PROCEDURE
bla():CardAr;
- to pass an array as argument, you can also use open arrays
(see above)
- Local variables of a procedure are NOT initialised
automatically!!
They can have any value at start.
- Scoop (variables, types & procedures): go out & up.
- a procedure must thus be defined before it can be used.
- use FORWARD to declare the procedure first and
implement
it later in the code (eg. when 2 procedures call each other):
- PROCEDURE Bla2(); FORWARD;
Operators
- NOT, AND,
OR boolean
operators
- +, -, *, /, MOD (modulo = 'rest'), y :=
ABS(x) (absolute value, for integers & reals)
- =,
# equals,
different
- <, >, >=,
<= relational
operators
- INC(VAR ordinal); DEC(VAR
ordinal); increment &
decrement ordinal variables
- integer := ORD(ordinal); ordinal := VAL(ordinalType,
cardinal); conversion
- ordinal := MIN(OrdinalType); ordinal :=
MAX(OrdinalType); max & min value of that type
Use round brackets (haakjes) to indicate evaluation priorities
eg: IF x MOD 3 = 0 THEN gives an
error
(the = operation is evaluated before the MOD)
this should be: IF (x MOD 3) = 0 THEN
Control Statements
IF (a > 5) OR (b > 6)
THEN
condition
...
statements
ELSIF ( a > 3) THEN optional
...
statements
ELSE
optional
...
statements
END;
CASE day OF
Monday: statements; use
a
case label only once
| Tuesday .. Thursday: statements;
| Friday, Sunday: statements;
ELSE
when none of the case labels apply
statements
END;
WHILE NOT (i > 10) DO condition
statements...
END;
REPEAT
statements...
UNTIL (i = 10);
LOOP
statements...
IF condition THEN
EXIT
END;
statements...
END;
FOR i := 10 TO 0 BY -1 DO By
clause
is optional
statements...
END;
FOR is possible with all ordinal types (like enums)!
FOR day := MONDAY TO SUNDAY DO
...
END;
Library IO (input - output)
- WrLn;
skip to next line
- cardinalVariable := RdCard();
read cardinal
- WrCard(cardinalVariable, spaces); write
cardinal
- readVariable := RdInt();
- WrInt(intVariable, spaces);
- RdStr(stringVariable);
read
string (variabele tussen de haakjes!!)
- WrStr(stringVariable);
write string to output
- charVariable :=
RdChar() !! 2 ENTER-tokens stay in
input buffer, are readed the next time
with a RdChar
- RdLn;
use RdLn after RdChar to read the rest of the input and the
ENTER-tokens
- WrChar(charVariable);
- booleanVariable :=
RdBool(); ty pe "TRUE" and "FALSE"
- WrBool(booleanVariable, spaces);
- realVariable := RdReal();
read real from user input
- WrReal(realVariable, precision, spaces);
write real to output in 2.897E+1 form (precision: number
of digits)
- WrFixReal(realVariable, precision, spaces);
write real to output in 28.97 form (precision: number of
digits
after comma)
- KeyPressed() returns a boolean to indicate
whether
the user pressed a key.
Library RealMath (mathematical functions on reals)
- CONST pi = 3.141592; exp1 =
2.718281;
- sqrt (x: REAL): REAL; Returns
the
positive square root of x
- exp (x: REAL):
REAL; Returns the
exponential of x
- ln (x: REAL):
REAL; Returns the
natural logarithm of x
The angle in all trigonometric functions is measured in radians
- sin (x: REAL): REAL; cos (x: REAL): REAL; tan
(x: REAL): REAL;
- arcsin (x: REAL): REAL; arccos (x: REAL): REAL; arctan (x:
REAL):
REAL;
- power (base, exponent: REAL): REAL; Returns
the
value of the number base raised to the power exponent. base may not be
negative!!?
- round (x: REAL):
INTEGER; Returns the value
of x rounded to the nearest integer
- IsRMathException ():
BOOLEAN; Returns TRUE if
the current coroutine is in the exceptional execution
state because of the raising of an exception in a routine from this
module;
otherwise returns FALSE.