# Oberon language test and validation suite # options --mayTrap --prolog="Compiler.Compile TesterInput.txt" --command="SystemTools.Free Test Dummy B A;SystemTools.Load Test" --logFile="FoxExecutionTest.Log" --result="Oberon.Execution.Test.Diff" # test halt and assert statements and simple procedure call (basics for the test suite) positive: empty module MODULE Test; END Test. negative: simple halt MODULE Test; BEGIN HALT (1234); END Test. positive: satisified assertion MODULE Test; VAR b: BOOLEAN; BEGIN b := TRUE; ASSERT (b); END Test. negative: unsatisified assertion MODULE Test; VAR b: BOOLEAN; BEGIN b := FALSE; ASSERT (b); END Test. negative: simple halt in global procedure MODULE Test; PROCEDURE Procedure; BEGIN HALT (1234); END Procedure; BEGIN Procedure; END Test. positive: satisified assertion in global procedure MODULE Test; PROCEDURE Procedure; VAR b: BOOLEAN; BEGIN b := TRUE; ASSERT (b); END Procedure; BEGIN Procedure; END Test. negative: unsatisified assertion in global procedure MODULE Test; PROCEDURE Procedure; VAR b: BOOLEAN; BEGIN b := FALSE; ASSERT (b); END Procedure; BEGIN Procedure; END Test. positive: parameterless procedure call MODULE Test; VAR called: BOOLEAN; PROCEDURE P; BEGIN called := TRUE; END P; BEGIN called := FALSE; P; ASSERT(called); END Test. # basic types storage test positive: Char stored in PAF MODULE Test; PROCEDURE Char; VAR a,b: CHAR; BEGIN a := 'a'; b := a; ASSERT(b = 'a'); END Char; BEGIN Char; END Test. positive: Shortint stored in PAF MODULE Test; PROCEDURE Shortint; VAR a,b: SHORTINT; BEGIN a := 13; b := a; ASSERT(b = 13); END Shortint; BEGIN Shortint; END Test. positive: Integer stored in PAF MODULE Test; PROCEDURE Integer; VAR a,b: INTEGER; BEGIN a := 2233; b := a; ASSERT(b = 2233); END Integer; BEGIN Integer; END Test. positive: Longint stored in PAF MODULE Test; PROCEDURE Longint; VAR a,b: LONGINT; BEGIN a := 70800; b := a; ASSERT(b = 70800); END Longint; BEGIN Longint; END Test. positive: Hugeint stored in PAF MODULE Test; PROCEDURE Hugeint; VAR a,b: HUGEINT; BEGIN a := 70800; b := a; ASSERT(b = 70800); END Hugeint; BEGIN Hugeint; END Test. positive: Real stored in PAF MODULE Test; PROCEDURE Real; VAR a,b: REAL; BEGIN a := 888; b := a; ASSERT(b = 888); END Real; BEGIN Real; END Test. positive: Longreal stored in PAF MODULE Test; PROCEDURE Longreal; VAR a,b: LONGREAL; BEGIN a := 888; b := a; ASSERT(b = 888); END Longreal; BEGIN Longreal; END Test. positive: Set stored in PAF MODULE Test; PROCEDURE Set; VAR a,b: SET; BEGIN a := {1,2,8,9,31}; b := a; ASSERT(b = {1,2,8,9,31}); END Set; BEGIN Set; END Test. positive: Boolean stored in PAF MODULE Test; PROCEDURE Boolean; VAR a,b,c: BOOLEAN; BEGIN a := FALSE; b := TRUE; c := FALSE; ASSERT(b = TRUE); END Boolean; BEGIN Boolean; END Test. # constant declarations positive: expression containing a constant MODULE Test; CONST N = 10000; VAR i: INTEGER; BEGIN i := N - 1; ASSERT (i = 9999); END Test. positive: lengths of string constants MODULE Test; CONST String = "This string is not empty"; CONST Copy = String; PROCEDURE Assert (CONST str: ARRAY OF CHAR); BEGIN ASSERT (LEN (str) # 0); END Assert; BEGIN Assert (String); Assert (Copy); END Test. # basic type declarations positive: constant boolean assignment MODULE Test; VAR b: BOOLEAN; BEGIN b := TRUE; ASSERT (b = TRUE); END Test. positive: variable boolean assignment MODULE Test; VAR b1, b2: BOOLEAN; BEGIN b1 := TRUE; b2 := FALSE; b2 := b1; ASSERT (b2 = TRUE); END Test. positive: boolean equality MODULE Test; VAR b1, b2: BOOLEAN; BEGIN b1 := TRUE; b2 := b1; ASSERT (b1 = b2); b1 := FALSE; b2 := b1; ASSERT (b1 = b2); END Test. positive: array of boolean values MODULE Test; VAR b: ARRAY 2 OF BOOLEAN; BEGIN b[1] := TRUE; ASSERT (b[1]); END Test. positive: constant character assignment MODULE Test; VAR c: CHAR; BEGIN c := 'c'; ASSERT (c = 'c'); END Test. positive: variable character assignment MODULE Test; VAR c1, c2: CHAR; BEGIN c1 := 'A'; c2 := 'B'; c2 := c1; ASSERT (c2 = 'A'); END Test. positive: char array variable assignment MODULE Test; VAR v: ARRAY 2 OF CHAR; BEGIN v[0] := CHR(92); ASSERT (ORD(v[0]) = 92); END Test. positive: heximal character value assignment MODULE Test; VAR c: CHAR; BEGIN c := 020X; ASSERT (c = ' '); END Test. positive: constant integer assignment MODULE Test; VAR i: INTEGER; BEGIN i := 2; ASSERT (i = 2); END Test. positive: variable integer assignment MODULE Test; VAR i1, i2: INTEGER; BEGIN i1 := 45; i2 := 64; i2 := i1; ASSERT (i1 = 45); END Test. positive: constant real assignment MODULE Test; VAR r: REAL; BEGIN r := 2; ASSERT (r = 2); END Test. positive: variable real assignment MODULE Test; VAR r1, r2: REAL; BEGIN r1 := 2.25; r2 := 3.75; r2 := r1; ASSERT (r1 = 2.25); END Test. positive: real value assignment to real variable MODULE Test; VAR r: REAL; BEGIN r := 1.25; ASSERT (r = 1.25); END Test. positive: constant set assignment MODULE Test; VAR s: SET; BEGIN s := {1}; ASSERT (1 IN s); END Test. positive: variable set assignment MODULE Test; VAR s1, s2: SET; i: INTEGER; BEGIN i := 5; s1 := {i}; s2 := {}; s2 := s1; ASSERT (i IN s2); END Test. positive: set inclusions MODULE Test; VAR s: SET; i, j, k: INTEGER; BEGIN i := 1; j := 3; k := 7; s := {1, 3, 5..8}; ASSERT ((i IN s) & (j IN s) & (k IN s)); END Test. negative: set value out of bounds at maximum MODULE Test; VAR n: INTEGER; s: SET; BEGIN n := MAX(SET) + 1; s := {n}; END Test. negative: set value out of bounds at minimum MODULE Test; VAR n: INTEGER; s: SET; BEGIN n := MIN(SET) - 1; s := {n}; END Test. # array type declarations negative: array out of bounds while reading MODULE Test; VAR a: ARRAY 1 OF INTEGER; r, i: INTEGER; BEGIN a[0] := 0; i := 1; r := a[i]; END Test. negative: array out of bounds while writing MODULE Test; VAR a: ARRAY 1 OF INTEGER; i: INTEGER; BEGIN i := 1; a[i] := 0; END Test. positive: index of array element is record variable MODULE Test; TYPE R = RECORD i: INTEGER END; VAR ai: ARRAY 2 OF INTEGER; ar: ARRAY 2 OF R; BEGIN ai[0] := 0; ai[1] := 5; ar[0].i := 1; ASSERT (ai[ar[ai[0]].i] = 5); END Test. positive: one-dimensional array element assignment MODULE Test; VAR a: ARRAY 2 OF CHAR; BEGIN a[1] := 'c'; ASSERT (a[1] = 'c'); END Test. positive: two-dimensional array element assignment MODULE Test; VAR a: ARRAY 2, 2 OF BOOLEAN; BEGIN a[1, 1] := TRUE; ASSERT (a[1, 1] = TRUE); END Test. # record type declarations positive: record initialization MODULE Test; VAR r: RECORD i: INTEGER END; BEGIN r.i := 5; ASSERT (r.i = 5); END Test. positive: record copies MODULE Test; VAR a, b: RECORD i, j: INTEGER END; BEGIN a.i := 1; a.j := 2; b := a; ASSERT (b.i = 1); ASSERT (b.j = 2); END Test. # pointer type declarations positive: dynamic record allocation with new MODULE Test; VAR p: POINTER TO RECORD x: INTEGER END; BEGIN NEW (p); ASSERT (p # NIL); p.x := 3; ASSERT (p.x = 3); END Test. positive: valid type guard test MODULE Test; TYPE R1 = RECORD END; R2 = RECORD (R1) END; P1 = POINTER TO R1; P2 = POINTER TO R2; VAR p1: P1; p2: P2; BEGIN NEW (p2); p1 := p2; p2 := p1(P2); END Test. # procedure type declarations positive: procedure type with value parameter INTEGER MODULE Test; VAR a: ARRAY 5 OF INTEGER; i: INTEGER; r: INTEGER; PROCEDURE Iterate (VAR a: ARRAY OF INTEGER; p : PROCEDURE (r: INTEGER)); VAR i: LONGINT; BEGIN FOR i := 0 TO LEN (a) - 1 DO p (a[i]) END; END Iterate; PROCEDURE Accummulate (v: INTEGER); BEGIN r := r + v; END Accummulate; BEGIN FOR i := 0 TO 4 DO a[i] := i END; r := 0; Iterate (a, Accummulate); ASSERT (r = 10); END Test. positive: procedure type with value parameter REAL MODULE Test; VAR a: ARRAY 5 OF REAL; i: INTEGER; r: REAL; PROCEDURE Iterate (VAR a: ARRAY OF REAL; p : PROCEDURE (r: REAL)); VAR i: LONGINT; BEGIN FOR i := 0 TO LEN (a) - 1 DO p (a[i]) END; END Iterate; PROCEDURE Accummulate (v: REAL); BEGIN r := r + v; END Accummulate; BEGIN FOR i := 0 TO 4 DO a[i] := i END; r := 0; Iterate (a, Accummulate); ASSERT (r = 10); END Test. positive: procedure type with var parameter INTEGER MODULE Test; VAR i: INTEGER; k: INTEGER; p: PROCEDURE (VAR r: INTEGER; b: INTEGER); PROCEDURE Accummulate (VAR r: INTEGER; v: INTEGER); BEGIN r := r + v; END Accummulate; BEGIN k := 0; p := Accummulate; FOR i := 0 TO 4 DO p (k, i) END; ASSERT (k = 10); END Test. positive: procedure type with var parameter REAL MODULE Test; VAR i: INTEGER; k: REAL; p: PROCEDURE (VAR r: REAL; b: REAL); PROCEDURE Accummulate (VAR r: REAL; v: REAL); BEGIN r := r + v; END Accummulate; BEGIN k := 0; p := Accummulate; FOR i := 0 TO 4 DO p (k, i) END; ASSERT (k = 10); END Test. positive: procedure type with result type INTEGER MODULE Test; VAR r: INTEGER; p: PROCEDURE (a, b: INTEGER): INTEGER; PROCEDURE Add (a, b: INTEGER): INTEGER; BEGIN RETURN a + b; END Add; BEGIN p := Add; r := p (3, 4); ASSERT (r = 7); END Test. positive: procedure type with result type REAL MODULE Test; VAR r: REAL; p: PROCEDURE (a, b: REAL): REAL; PROCEDURE Add (a, b: REAL): REAL; BEGIN RETURN a + b; END Add; BEGIN p := Add; r := p (3, 4); ASSERT (r = 7); END Test. positive: procedure type with result type in record INTEGER MODULE Test; VAR r: INTEGER; p: RECORD p: PROCEDURE (a, b: INTEGER): INTEGER END; PROCEDURE Add (a, b: INTEGER): INTEGER; BEGIN RETURN a + b; END Add; BEGIN p.p := Add; r := p.p (3, 4); ASSERT (r = 7); END Test. positive: procedure type with result type in record REAL MODULE Test; VAR r: REAL; p: RECORD p: PROCEDURE (a, b: REAL): REAL END; PROCEDURE Add (a, b: REAL): REAL; BEGIN RETURN a + b; END Add; BEGIN p.p := Add; r := p.p (3, 4); ASSERT (r = 7); END Test. positive: procedure array MODULE Test; VAR i: INTEGER; a: ARRAY 10 OF PROCEDURE (VAR a: INTEGER); PROCEDURE Add3 (VAR v: INTEGER); BEGIN INC (v, 3); END Add3; BEGIN i := 3; a[6] := Add3; a[6] (i); ASSERT (i = 6); a[i](i); ASSERT (i = 9); END Test. positive: procedure array with return type MODULE Test; VAR i: INTEGER; a: ARRAY 10 OF PROCEDURE (i: INTEGER): INTEGER; PROCEDURE Add2 (v: INTEGER): INTEGER; BEGIN RETURN v + 2; END Add2; BEGIN a[3] := Add2; i := a[3](1); ASSERT (i = 3); INC (i, a[i](i)); ASSERT (i = 8); END Test. # conversions positive: constant positive real to integer conversion MODULE Test; VAR i: LONGINT; BEGIN i := ENTIER (3.5); ASSERT (i = 3); END Test. positive: constant negative real to integer conversion MODULE Test; VAR i: LONGINT; BEGIN i := ENTIER (-3.5); ASSERT (i = -4); END Test. positive: positive real to integer conversion MODULE Test; VAR r: REAL; i: LONGINT; BEGIN r := 3.5; i := ENTIER (r); ASSERT (i = 3); END Test. positive: negative real to integer conversion MODULE Test; VAR r: REAL; i: LONGINT; BEGIN r := -3.5; i := ENTIER (r); ASSERT (i = -4); END Test. # variable declarations positive: two-dimensional array assignment MODULE Test; VAR a: ARRAY 8, 12 OF INTEGER; BEGIN a[1, 2] := 3; ASSERT (a[1][2] = 3); END Test. positive: two-dimensional open array assignment MODULE Test; VAR a: ARRAY 8, 12 OF INTEGER; PROCEDURE P (VAR b: ARRAY OF ARRAY OF INTEGER); BEGIN b[1][2] := 3; END P; BEGIN P (a); ASSERT (a[1][2] = 3); END Test. # operations positive: logical operations MODULE Test; VAR a, b: BOOLEAN; BEGIN a := FALSE; ASSERT (~a); b := FALSE; ASSERT (~a & ~b); ASSERT (~a OR ~b); b := TRUE; ASSERT (~a & b); ASSERT (~a OR b); a := TRUE; ASSERT (a); b := FALSE; ASSERT (a & ~b); ASSERT (a OR ~b); b := TRUE; ASSERT (a & b); ASSERT (a OR b); END Test. positive: arithmetic operations MODULE Test; VAR a, b: INTEGER; BEGIN a := 9; b := 7; ASSERT (+a = 9); ASSERT (+b = 7); ASSERT (-a = -9); ASSERT (-b = -7); ASSERT (a + b = 16); ASSERT (b + a = 16); ASSERT (a - b = 2); ASSERT (b - a = -2); ASSERT (a * b = 63); ASSERT (b * a = 63); ASSERT (a DIV b = 1); ASSERT (b DIV a = 0); ASSERT (a MOD b = 2); ASSERT (b MOD a = 7); END Test. positive: set operations MODULE Test; VAR a, b, c: SET; BEGIN a := {0, 1, 2}; ASSERT (a = {0..2}); ASSERT ((0 IN a) & (1 IN a) & (2 IN a) & ~(3 IN a) & ~(4 IN a)); b := {2, 3, 4}; ASSERT (b = {2..4}); ASSERT (~(0 IN b) & ~(1 IN b) & (2 IN b) & (3 IN b) & (4 IN b)); c := a + b; ASSERT (c = {0..4}); ASSERT ((0 IN c) & (1 IN c) & (2 IN c) & (3 IN c) & (4 IN c)); c := a - b; ASSERT (c = {0..1}); ASSERT ((0 IN c) & (1 IN c) & ~(2 IN c) & ~(3 IN c) & ~(4 IN c)); c := a * b; ASSERT (c = {2..2}); ASSERT (~(0 IN c) & ~(1 IN c) & (2 IN c) & ~(3 IN c) & ~(4 IN c)); c := a / b; ASSERT (c = {0..1, 3..4}); ASSERT ((0 IN c) & (1 IN c) & ~(2 IN c) & (3 IN c) & (4 IN c)); END Test. positive: relations MODULE Test; VAR ai, bi: INTEGER; as, bs: SET; ar, br: REAL; BEGIN ai := 0; bi := 1; ASSERT (~(ai = bi)); ASSERT (ai # bi); ASSERT (ai < bi); ASSERT (ai <= bi); ASSERT (~(ai > bi)); ASSERT (~(ai >= bi)); as := {1}; bs := {1, 2}; ASSERT (~(as = bs)); ASSERT (as # bs); ASSERT (as < bs); ASSERT (as <= bs); ASSERT (~(as > bs)); ASSERT (~(as >= bs)); ar := 0; br := 1; ASSERT (~(ar = br)); ASSERT (ar # br); ASSERT (ar < br); ASSERT (ar <= br); ASSERT (~(ar > br)); ASSERT (~(ar >= br)); END Test. # complement positive: complement on booleans MODULE Test; VAR value: BOOLEAN; BEGIN value := TRUE; ASSERT (value); ASSERT (~~value); value := FALSE; ASSERT (~value); ASSERT (~~~value); END Test. # relational operations positive: relational operations on booleans MODULE Test; VAR value: BOOLEAN; BEGIN value := TRUE; ASSERT (value = TRUE); ASSERT (~(value = FALSE)); ASSERT (value = value); ASSERT (value # FALSE); ASSERT (~(value # TRUE)); ASSERT (~(value # value)); value := FALSE; ASSERT (value = FALSE); ASSERT (~(value = TRUE)); ASSERT (value = value); ASSERT (value # TRUE); ASSERT (~(value # FALSE)); ASSERT (~(value # value)); END Test. positive: relational operations on characters MODULE Test; VAR value: CHAR; BEGIN value := 'a'; ASSERT (value = 'a'); ASSERT (~(value = 'b')); ASSERT (value = value); ASSERT (value # 'b'); ASSERT (~(value # 'a')); ASSERT (~(value # value)); ASSERT (value < 'z'); ASSERT (~(value < 0X)); ASSERT (~(value < value)); ASSERT (value <= 'z'); ASSERT (~(value <= 0X)); ASSERT (value <= value); ASSERT (value > 0X); ASSERT (~(value > 'z')); ASSERT (~(value > value)); ASSERT (value >= 0X); ASSERT (~(value >= 'z')); ASSERT (value >= value); END Test. positive: relational operations on short integers MODULE Test; VAR value: SHORTINT; BEGIN value := 5; ASSERT (value = 5); ASSERT (~(value = 6)); ASSERT (value = value); ASSERT (value # 6); ASSERT (~(value # 5)); ASSERT (~(value # value)); ASSERT (value < 6); ASSERT (~(value < 4)); ASSERT (~(value < value)); ASSERT (value <= 6); ASSERT (~(value <= 4)); ASSERT (value <= value); ASSERT (value > 4); ASSERT (~(value > 6)); ASSERT (~(value > value)); ASSERT (value >= 4); ASSERT (~(value >= 6)); ASSERT (value >= value); END Test. positive: relational operations on integers MODULE Test; VAR value: INTEGER; BEGIN value := 5; ASSERT (value = 5); ASSERT (~(value = 6)); ASSERT (value = value); ASSERT (value # 6); ASSERT (~(value # 5)); ASSERT (~(value # value)); ASSERT (value < 6); ASSERT (~(value < 4)); ASSERT (~(value < value)); ASSERT (value <= 6); ASSERT (~(value <= 4)); ASSERT (value <= value); ASSERT (value > 4); ASSERT (~(value > 6)); ASSERT (~(value > value)); ASSERT (value >= 4); ASSERT (~(value >= 6)); ASSERT (value >= value); END Test. positive: relational operations on long integers MODULE Test; VAR value: LONGINT; BEGIN value := 5; ASSERT (value = 5); ASSERT (~(value = 6)); ASSERT (value = value); ASSERT (value # 6); ASSERT (~(value # 5)); ASSERT (~(value # value)); ASSERT (value < 6); ASSERT (~(value < 4)); ASSERT (~(value < value)); ASSERT (value <= 6); ASSERT (~(value <= 4)); ASSERT (value <= value); ASSERT (value > 4); ASSERT (~(value > 6)); ASSERT (~(value > value)); ASSERT (value >= 4); ASSERT (~(value >= 6)); ASSERT (value >= value); END Test. positive: relational operations on huge integers MODULE Test; VAR value: HUGEINT; BEGIN value := 5; ASSERT (value = 5); ASSERT (~(value = 6)); ASSERT (value = value); ASSERT (value # 6); ASSERT (~(value # 5)); ASSERT (~(value # value)); ASSERT (value < 6); ASSERT (~(value < 4)); ASSERT (~(value < value)); ASSERT (value <= 6); ASSERT (~(value <= 4)); ASSERT (value <= value); ASSERT (value > 4); ASSERT (~(value > 6)); ASSERT (~(value > value)); ASSERT (value >= 4); ASSERT (~(value >= 6)); ASSERT (value >= value); END Test. positive: relational operations on reals MODULE Test; VAR value: REAL; BEGIN value := 5; ASSERT (value = 5); ASSERT (~(value = 6)); ASSERT (value = value); ASSERT (value # 6); ASSERT (~(value # 5)); ASSERT (~(value # value)); ASSERT (value < 6); ASSERT (~(value < 4)); ASSERT (~(value < value)); ASSERT (value <= 6); ASSERT (~(value <= 4)); ASSERT (value <= value); ASSERT (value > 4); ASSERT (~(value > 6)); ASSERT (~(value > value)); ASSERT (value >= 4); ASSERT (~(value >= 6)); ASSERT (value >= value); END Test. positive: relational operations on long reals MODULE Test; VAR value: LONGREAL; BEGIN value := 5; ASSERT (value = 5); ASSERT (~(value = 6)); ASSERT (value = value); ASSERT (value # 6); ASSERT (~(value # 5)); ASSERT (~(value # value)); ASSERT (value < 6); ASSERT (~(value < 4)); ASSERT (~(value < value)); ASSERT (value <= 6); ASSERT (~(value <= 4)); ASSERT (value <= value); ASSERT (value > 4); ASSERT (~(value > 6)); ASSERT (~(value > value)); ASSERT (value >= 4); ASSERT (~(value >= 6)); ASSERT (value >= value); END Test. positive: relational operations on sets MODULE Test; VAR value: SET; BEGIN value := {1, 2}; ASSERT (value = {1, 2}); ASSERT (~(value = {2})); ASSERT (value = value); ASSERT (value # {2}); ASSERT (~(value # {1, 2})); ASSERT (~(value # value)); ASSERT (value < {1, 2, 3}); ASSERT (~(value < {2})); ASSERT (~(value < value)); ASSERT (value <= {1, 2, 3}); ASSERT (~(value <= {2})); ASSERT (value <= value); ASSERT (value > {2}); ASSERT (~(value > {1, 2, 3})); ASSERT (~(value > value)); ASSERT (value >= {2}); ASSERT (~(value >= {1, 2, 3})); ASSERT (value >= value); END Test. positive: relational operations on character arrays MODULE Test; VAR value: ARRAY 10 OF CHAR; BEGIN value := "text"; ASSERT (value = "text"); ASSERT (~(value = "abc")); ASSERT (value = value); ASSERT (value # "abc"); ASSERT (~(value # "text")); ASSERT (~(value # value)); ASSERT (value < "xyz"); ASSERT (~(value < "abc")); ASSERT (~(value < value)); ASSERT (value <= "xyz"); ASSERT (~(value <= "abc")); ASSERT (value <= value); ASSERT (value > "abc"); ASSERT (~(value > "xyz")); ASSERT (~(value > value)); ASSERT (value >= "abc"); ASSERT (~(value >= "xyz")); ASSERT (value >= value); ASSERT (value[0] = 't'); ASSERT (value[1] = 'e'); ASSERT (value[2] = 'x'); ASSERT (value[3] = 't'); ASSERT (value[4] = 0X); END Test. # negation positive: negation on short integers MODULE Test; VAR value: SHORTINT; BEGIN value := 5; ASSERT (-value = -5); ASSERT (-(-value) = 5); ASSERT (-(-value) = value) END Test. positive: negation on integers MODULE Test; VAR value: INTEGER; BEGIN value := 5; ASSERT (-value = -5); ASSERT (-(-value) = 5); ASSERT (-(-value) = value) END Test. positive: negation on long integers MODULE Test; VAR value: LONGINT; BEGIN value := 5; ASSERT (-value = -5); ASSERT (-(-value) = 5); ASSERT (-(-value) = value) END Test. positive: negation on huge integers MODULE Test; VAR value: HUGEINT; BEGIN value := 5; ASSERT (-value = -5); ASSERT (-(-value) = 5); ASSERT (-(-value) = value) END Test. positive: negation on reals MODULE Test; VAR value: REAL; BEGIN value := 5; ASSERT (-value = -5); ASSERT (-(-value) = 5); ASSERT (-(-value) = value) END Test. positive: negation on long reals MODULE Test; VAR value: LONGREAL; BEGIN value := 5; ASSERT (-value = -5); ASSERT (-(-value) = 5); ASSERT (-(-value) = value) END Test. positive: negation on sets MODULE Test; VAR value: SET; BEGIN value := {1, 2}; ASSERT (-value = {0, 3 .. MAX (SET)}); ASSERT (-(-value) = {1, 2}); ASSERT (-(-value) = value) END Test. # absolute value positive: absolute value of short integer MODULE Test; VAR value: SHORTINT; BEGIN value := 5; ASSERT (ABS (value) = 5); ASSERT (ABS (-value) = 5); ASSERT (ABS (value) = value); ASSERT (ABS (-value) = value); value := -5; ASSERT (ABS (value) = 5); ASSERT (ABS (-value) = 5); ASSERT (ABS (value) = -value); ASSERT (ABS (-value) = -value); END Test. positive: absolute value of integer MODULE Test; VAR value: INTEGER; BEGIN value := 5; ASSERT (ABS (value) = 5); ASSERT (ABS (-value) = 5); ASSERT (ABS (value) = value); ASSERT (ABS (-value) = value); value := -5; ASSERT (ABS (value) = 5); ASSERT (ABS (-value) = 5); ASSERT (ABS (value) = -value); ASSERT (ABS (-value) = -value); END Test. positive: absolute value of long integer MODULE Test; VAR value: LONGINT; BEGIN value := 5; ASSERT (ABS (value) = 5); ASSERT (ABS (-value) = 5); ASSERT (ABS (value) = value); ASSERT (ABS (-value) = value); value := -5; ASSERT (ABS (value) = 5); ASSERT (ABS (-value) = 5); ASSERT (ABS (value) = -value); ASSERT (ABS (-value) = -value); END Test. positive: absolute value of huge integer MODULE Test; VAR value: HUGEINT; BEGIN value := 5; ASSERT (ABS (value) = 5); ASSERT (ABS (-value) = 5); ASSERT (ABS (value) = value); ASSERT (ABS (-value) = value); value := -5; ASSERT (ABS (value) = 5); ASSERT (ABS (-value) = 5); ASSERT (ABS (value) = -value); ASSERT (ABS (-value) = -value); END Test. positive: absolute value of real MODULE Test; VAR value: REAL; BEGIN value := 5; ASSERT (ABS (value) = 5); ASSERT (ABS (-value) = 5); ASSERT (ABS (value) = value); ASSERT (ABS (-value) = value); value := -5; ASSERT (ABS (value) = 5); ASSERT (ABS (-value) = 5); ASSERT (ABS (value) = -value); ASSERT (ABS (-value) = -value); END Test. positive: absolute value of long real MODULE Test; VAR value: LONGREAL; BEGIN value := 5; ASSERT (ABS (value) = 5); ASSERT (ABS (-value) = 5); ASSERT (ABS (value) = value); ASSERT (ABS (-value) = value); value := -5; ASSERT (ABS (value) = 5); ASSERT (ABS (-value) = 5); ASSERT (ABS (value) = -value); ASSERT (ABS (-value) = -value); END Test. # logical operations positive: logical and on booleans MODULE Test; VAR a, b: BOOLEAN; BEGIN a := FALSE; b := FALSE; ASSERT (a & b = FALSE); a := FALSE; b := TRUE; ASSERT (a & b = FALSE); a := TRUE; b := FALSE; ASSERT (a & b = FALSE); a := TRUE; b := TRUE; ASSERT (a & b = TRUE); END Test. positive: logical and on boolean return values MODULE Test; PROCEDURE True (): BOOLEAN; BEGIN RETURN TRUE; END True; PROCEDURE False (): BOOLEAN; BEGIN RETURN FALSE; END False; BEGIN ASSERT (False () & False () = FALSE); ASSERT (False () & True () = FALSE); ASSERT (True () & False () = FALSE); ASSERT (True () & True () = TRUE); END Test. positive: logical or on booleans MODULE Test; VAR a, b: BOOLEAN; BEGIN a := FALSE; b := FALSE; ASSERT (a OR b = FALSE); a := FALSE; b := TRUE; ASSERT (a OR b = TRUE); a := TRUE; b := FALSE; ASSERT (a OR b = TRUE); a := TRUE; b := TRUE; ASSERT (a OR b = TRUE); END Test. positive: logical or on boolean return values MODULE Test; PROCEDURE True (): BOOLEAN; BEGIN RETURN TRUE; END True; PROCEDURE False (): BOOLEAN; BEGIN RETURN FALSE; END False; BEGIN ASSERT (False () OR False () = FALSE); ASSERT (False () OR True () = TRUE); ASSERT (True () OR False () = TRUE); ASSERT (True () OR True () = TRUE); END Test. positive: short-circuit evaluation MODULE Test; PROCEDURE True (): BOOLEAN; BEGIN RETURN TRUE; END True; PROCEDURE False (): BOOLEAN; BEGIN RETURN FALSE; END False; PROCEDURE Halt (): BOOLEAN; BEGIN HALT (1234); END Halt; BEGIN ASSERT (False () & Halt () = FALSE); ASSERT (True () OR Halt () = TRUE); END Test. # capital letter operation positive: capital letter of character MODULE Test; VAR value: CHAR; BEGIN value := '0'; ASSERT (CAP (value) = '0'); ASSERT (CAP (value) = CAP ('0')); value := '9'; ASSERT (CAP (value) = '9'); ASSERT (CAP (value) = CAP ('9')); value := 'a'; ASSERT (CAP (value) = 'A'); ASSERT (CAP (value) = CAP ('a')); value := 'z'; ASSERT (CAP (value) = 'Z'); ASSERT (CAP (value) = CAP ('z')); value := 'A'; ASSERT (CAP (value) = 'A'); ASSERT (CAP (value) = CAP ('A')); value := 'Z'; ASSERT (CAP (value) = 'Z'); ASSERT (CAP (value) = CAP ('Z')); END Test. # character annd ordinal value operations positive: ordinal value of character MODULE Test; VAR value: CHAR; i: INTEGER; BEGIN value := '0'; ASSERT (ORD (value) = ORD ('0')); value := '9'; ASSERT (ORD (value) = ORD ('9')); value := 'a'; ASSERT (ORD (value) = ORD ('a')); value := 'z'; ASSERT (ORD (value) = ORD ('z')); value := 'A'; ASSERT (ORD (value) = ORD ('A')); value := 'Z'; ASSERT (ORD (value) = ORD ('Z')); FOR i := ORD (0X) TO ORD (0FFX) DO value := CHR (i); ASSERT (ORD (value) = i); END; END Test. positive: character value of short integer MODULE Test; VAR value: SHORTINT; BEGIN value := ORD ('0'); ASSERT (CHR (value) = '0'); value := ORD ('9'); ASSERT (CHR (value) = '9'); value := ORD ('a'); ASSERT (CHR (value) = 'a'); value := ORD ('z'); ASSERT (CHR (value) = 'z'); value := ORD ('A'); ASSERT (CHR (value) = 'A'); value := ORD ('Z'); ASSERT (CHR (value) = 'Z'); END Test. positive: character value of integer MODULE Test; VAR value: INTEGER; BEGIN value := ORD ('0'); ASSERT (CHR (value) = '0'); value := ORD ('9'); ASSERT (CHR (value) = '9'); value := ORD ('a'); ASSERT (CHR (value) = 'a'); value := ORD ('z'); ASSERT (CHR (value) = 'z'); value := ORD ('A'); ASSERT (CHR (value) = 'A'); value := ORD ('Z'); ASSERT (CHR (value) = 'Z'); END Test. positive: character value of long integer MODULE Test; VAR value: LONGINT; BEGIN value := ORD ('0'); ASSERT (CHR (value) = '0'); value := ORD ('9'); ASSERT (CHR (value) = '9'); value := ORD ('a'); ASSERT (CHR (value) = 'a'); value := ORD ('z'); ASSERT (CHR (value) = 'z'); value := ORD ('A'); ASSERT (CHR (value) = 'A'); value := ORD ('Z'); ASSERT (CHR (value) = 'Z'); END Test. positive: character value of huge integer MODULE Test; VAR value: HUGEINT; BEGIN value := ORD ('0'); ASSERT (CHR (value) = '0'); value := ORD ('9'); ASSERT (CHR (value) = '9'); value := ORD ('a'); ASSERT (CHR (value) = 'a'); value := ORD ('z'); ASSERT (CHR (value) = 'z'); value := ORD ('A'); ASSERT (CHR (value) = 'A'); value := ORD ('Z'); ASSERT (CHR (value) = 'Z'); END Test. # set element operations positive: short integer as set element MODULE Test; VAR element: SHORTINT; set: SET; BEGIN element := MIN (SET); set := {element}; ASSERT (element IN set); ASSERT (set - {element} = {}); element := MIN (SET) + 2; set := {element}; ASSERT (element IN set); ASSERT (set - {element} = {}); element := MAX (SET); set := {element}; ASSERT (element IN set); ASSERT (set - {element} = {}); element := MAX (SET) - 2; set := {element}; ASSERT (element IN set); ASSERT (set - {element} = {}); END Test. negative: short integer as too small set element MODULE Test; VAR element: SHORTINT; set: SET; BEGIN element := MIN (SET) - 1; set := {element}; END Test. negative: short integer as too large set element MODULE Test; VAR element: SHORTINT; set: SET; BEGIN element := MAX (SET) + 1; set := {element}; END Test. positive: short integer as first set element MODULE Test; VAR element: SHORTINT; set: SET; BEGIN element := MIN (SET); set := {element .. MAX (SET)}; ASSERT (element IN set); ASSERT (set = {MIN (SET) .. MAX (SET)}); ASSERT (-set = {}); element := MIN (SET); set := {element .. MIN (SET)}; ASSERT (element IN set); ASSERT (set = {MIN (SET) .. MIN (SET)}); ASSERT (set = {element}); ASSERT (set = {MIN (SET)}); element := MIN (SET) + 2; set := {element .. MAX (SET)}; ASSERT (element IN set); ASSERT (set = {MIN (SET) + 2 .. MAX (SET)}); ASSERT (-set = {MIN (SET), MIN (SET) + 1}); element := MIN (SET) + 2; set := {element .. MIN (SET)}; ASSERT (~(element IN set)); ASSERT (set = {element .. MIN (SET)}); ASSERT (set = {}); END Test. negative: short integer as too small first set element MODULE Test; VAR element: SHORTINT; set: SET; BEGIN element := MIN (SET) - 1;set := {element .. MAX (SET)}; END Test. negative: short integer as too large first set element MODULE Test; VAR element: SHORTINT; set: SET; BEGIN element := MAX (SET) + 1;set := {element .. MAX (SET)}; END Test. positive: short integer as last set element MODULE Test; VAR element: SHORTINT; set: SET; BEGIN element := MAX (SET); set := {MIN (SET) .. element}; ASSERT (element IN set); ASSERT (set = {MIN (SET) .. MAX (SET)}); ASSERT (-set = {}); element := MAX (SET); set := {MAX (SET) .. element}; ASSERT (element IN set); ASSERT (set = {MAX (SET) .. MAX (SET)}); ASSERT (set = {MAX (SET)}); element := MAX (SET) - 2; set := {MIN (SET) .. element}; ASSERT (element IN set); ASSERT (set = {MIN (SET) .. MAX (SET) - 2}); ASSERT (-set = {MAX (SET) - 1, MAX (SET)}); element := MAX (SET) - 2; set := {MAX (SET).. element}; ASSERT (~(element IN set)); ASSERT (set = {MAX (SET) .. element}); ASSERT (set = {}); END Test. negative: short integer as too small last set element MODULE Test; VAR element: SHORTINT; set: SET; BEGIN element := MIN (SET) - 1;set := {MIN (SET) .. element}; END Test. negative: short integer as too large last set element MODULE Test; VAR element: SHORTINT; set: SET; BEGIN element := MAX (SET) + 1;set := {MIN (SET) .. element}; END Test. positive: short integers as set elements MODULE Test; VAR first, last: SHORTINT; set: SET; BEGIN first := MIN (SET); last := MAX (SET); set := {first .. last}; ASSERT (set = {MIN (SET) .. MAX (SET)}); ASSERT (first IN set); ASSERT (last IN set); ASSERT (-set = {}); first := MIN (SET) + 2; last := MAX (SET) - 2; set := {first .. last}; ASSERT (set = {MIN (SET) + 2 .. MAX (SET) - 2}); ASSERT (first IN set); ASSERT (last IN set); ASSERT (-set = {MIN (SET), MIN (SET) + 1, MAX (SET) - 1, MAX (SET)}); first := MIN (SET) + 2; last := first; set := {first .. last}; ASSERT (set = {first}); first := MIN (SET) + 2; last := first + 1; set := {first .. last}; ASSERT (set = {first, last}); first := MIN (SET) + 2; last := first - 1; set := {first .. last}; ASSERT (set = {}); END Test. positive: integer as set element MODULE Test; VAR element: INTEGER; set: SET; BEGIN element := MIN (SET); set := {element}; ASSERT (element IN set); ASSERT (set - {element} = {}); element := MAX (SET); set := {element}; ASSERT (element IN set); ASSERT (set - {element} = {}); END Test. negative: integer as too small set element MODULE Test; VAR element: INTEGER; set: SET; BEGIN element := MIN (SET) - 1; set := {element}; END Test. negative: integer as too large set element MODULE Test; VAR element: INTEGER; set: SET; BEGIN element := MAX (SET) + 1; set := {element}; END Test. positive: integer as first set element MODULE Test; VAR element: INTEGER; set: SET; BEGIN element := MIN (SET); set := {element .. MAX (SET)}; ASSERT (element IN set); ASSERT (set = {MIN (SET) .. MAX (SET)}); ASSERT (-set = {}); element := MIN (SET); set := {element .. MIN (SET)}; ASSERT (element IN set); ASSERT (set = {MIN (SET) .. MIN (SET)}); ASSERT (set = {element}); ASSERT (set = {MIN (SET)}); element := MIN (SET) + 2; set := {element .. MAX (SET)}; ASSERT (element IN set); ASSERT (set = {MIN (SET) + 2 .. MAX (SET)}); ASSERT (-set = {MIN (SET), MIN (SET) + 1}); element := MIN (SET) + 2; set := {element .. MIN (SET)}; ASSERT (~(element IN set)); ASSERT (set = {element .. MIN (SET)}); ASSERT (set = {}); END Test. negative: integer as too small first set element MODULE Test; VAR element: INTEGER; set: SET; BEGIN element := MIN (SET) - 1;set := {element .. MAX (SET)}; END Test. negative: integer as too large first set element MODULE Test; VAR element: INTEGER; set: SET; BEGIN element := MAX (SET) + 1;set := {element .. MAX (SET)}; END Test. positive: integer as last set element MODULE Test; VAR element: INTEGER; set: SET; BEGIN element := MAX (SET); set := {MIN (SET) .. element}; ASSERT (element IN set); ASSERT (set = {MIN (SET) .. MAX (SET)}); ASSERT (-set = {}); element := MAX (SET); set := {MAX (SET) .. element}; ASSERT (element IN set); ASSERT (set = {MAX (SET) .. MAX (SET)}); ASSERT (set = {MAX (SET)}); element := MAX (SET) - 2; set := {MIN (SET) .. element}; ASSERT (element IN set); ASSERT (set = {MIN (SET) .. MAX (SET) - 2}); ASSERT (-set = {MAX (SET) - 1, MAX (SET)}); element := MAX (SET) - 2; set := {MAX (SET).. element}; ASSERT (~(element IN set)); ASSERT (set = {MAX (SET) .. element}); ASSERT (set = {}); END Test. negative: integer as too small last set element MODULE Test; VAR element: INTEGER; set: SET; BEGIN element := MIN (SET) - 1;set := {MIN (SET) .. element}; END Test. negative: integer as too large last set element MODULE Test; VAR element: INTEGER; set: SET; BEGIN element := MAX (SET) + 1;set := {MIN (SET) .. element}; END Test. positive: integers as set elements MODULE Test; VAR first, last: INTEGER; set: SET; BEGIN first := MIN (SET); last := MAX (SET); set := {first .. last}; ASSERT (set = {MIN (SET) .. MAX (SET)}); ASSERT (first IN set); ASSERT (last IN set); ASSERT (-set = {}); first := MIN (SET) + 2; last := MAX (SET) - 2; set := {first .. last}; ASSERT (set = {MIN (SET) + 2 .. MAX (SET) - 2}); ASSERT (first IN set); ASSERT (last IN set); ASSERT (-set = {MIN (SET), MIN (SET) + 1, MAX (SET) - 1, MAX (SET)}); first := MIN (SET) + 2; last := first; set := {first .. last}; ASSERT (set = {first}); first := MIN (SET) + 2; last := first + 1; set := {first .. last}; ASSERT (set = {first, last}); first := MIN (SET) + 2; last := first - 1; set := {first .. last}; ASSERT (set = {}); END Test. positive: long integer as set element MODULE Test; VAR element: LONGINT; set: SET; BEGIN element := MIN (SET); set := {element}; ASSERT (element IN set); ASSERT (set - {element} = {}); element := MAX (SET); set := {element}; ASSERT (element IN set); ASSERT (set - {element} = {}); END Test. negative: long integer as too small set element MODULE Test; VAR element: LONGINT; set: SET; BEGIN element := MIN (SET) - 1; set := {element}; END Test. negative: long integer as too large set element MODULE Test; VAR element: LONGINT; set: SET; BEGIN element := MAX (SET) + 1; set := {element}; END Test. positive: long integer as first set element MODULE Test; VAR element: LONGINT; set: SET; BEGIN element := MIN (SET); set := {element .. MAX (SET)}; ASSERT (element IN set); ASSERT (set = {MIN (SET) .. MAX (SET)}); ASSERT (-set = {}); element := MIN (SET); set := {element .. MIN (SET)}; ASSERT (element IN set); ASSERT (set = {MIN (SET) .. MIN (SET)}); ASSERT (set = {element}); ASSERT (set = {MIN (SET)}); element := MIN (SET) + 2; set := {element .. MAX (SET)}; ASSERT (element IN set); ASSERT (set = {MIN (SET) + 2 .. MAX (SET)}); ASSERT (-set = {MIN (SET), MIN (SET) + 1}); element := MIN (SET) + 2; set := {element .. MIN (SET)}; ASSERT (~(element IN set)); ASSERT (set = {element .. MIN (SET)}); ASSERT (set = {}); END Test. negative: long integer as too small first set element MODULE Test; VAR element: LONGINT; set: SET; BEGIN element := MIN (SET) - 1;set := {element .. MAX (SET)}; END Test. negative: long integer as too large first set element MODULE Test; VAR element: LONGINT; set: SET; BEGIN element := MAX (SET) + 1;set := {element .. MAX (SET)}; END Test. positive: long integer as last set element MODULE Test; VAR element: LONGINT; set: SET; BEGIN element := MAX (SET); set := {MIN (SET) .. element}; ASSERT (element IN set); ASSERT (set = {MIN (SET) .. MAX (SET)}); ASSERT (-set = {}); element := MAX (SET); set := {MAX (SET) .. element}; ASSERT (element IN set); ASSERT (set = {MAX (SET) .. MAX (SET)}); ASSERT (set = {MAX (SET)}); element := MAX (SET) - 2; set := {MIN (SET) .. element}; ASSERT (element IN set); ASSERT (set = {MIN (SET) .. MAX (SET) - 2}); ASSERT (-set = {MAX (SET) - 1, MAX (SET)}); element := MAX (SET) - 2; set := {MAX (SET).. element}; ASSERT (~(element IN set)); ASSERT (set = {MAX (SET) .. element}); ASSERT (set = {}); END Test. negative: long integer as too small last set element MODULE Test; VAR element: LONGINT; set: SET; BEGIN element := MIN (SET) - 1;set := {MIN (SET) .. element}; END Test. negative: long integer as too large last set element MODULE Test; VAR element: LONGINT; set: SET; BEGIN element := MAX (SET) + 1;set := {MIN (SET) .. element}; END Test. positive: long integers as set elements MODULE Test; VAR first, last: LONGINT; set: SET; BEGIN first := MIN (SET); last := MAX (SET); set := {first .. last}; ASSERT (set = {MIN (SET) .. MAX (SET)}); ASSERT (first IN set); ASSERT (last IN set); ASSERT (-set = {}); first := MIN (SET) + 2; last := MAX (SET) - 2; set := {first .. last}; ASSERT (set = {MIN (SET) + 2 .. MAX (SET) - 2}); ASSERT (first IN set); ASSERT (last IN set); ASSERT (-set = {MIN (SET), MIN (SET) + 1, MAX (SET) - 1, MAX (SET)}); first := MIN (SET) + 2; last := first; set := {first .. last}; ASSERT (set = {first}); first := MIN (SET) + 2; last := first + 1; set := {first .. last}; ASSERT (set = {first, last}); first := MIN (SET) + 2; last := first - 1; set := {first .. last}; ASSERT (set = {}); END Test. positive: huge integer as set element MODULE Test; VAR element: HUGEINT; set: SET; BEGIN element := MIN (SET); set := {element}; ASSERT (element IN set); ASSERT (set - {element} = {}); element := MAX (SET); set := {element}; ASSERT (element IN set); ASSERT (set - {element} = {}); END Test. negative: huge integer as too small set element MODULE Test; VAR element: HUGEINT; set: SET; BEGIN element := MIN (SET) - 1; set := {element}; END Test. negative: huge integer as too large set element MODULE Test; VAR element: HUGEINT; set: SET; BEGIN element := MAX (SET) + 1; set := {element}; END Test. positive: huge integer as first set element MODULE Test; VAR element: HUGEINT; set: SET; BEGIN element := MIN (SET); set := {element .. MAX (SET)}; ASSERT (element IN set); ASSERT (set = {MIN (SET) .. MAX (SET)}); ASSERT (-set = {}); element := MIN (SET); set := {element .. MIN (SET)}; ASSERT (element IN set); ASSERT (set = {MIN (SET) .. MIN (SET)}); ASSERT (set = {element}); ASSERT (set = {MIN (SET)}); element := MIN (SET) + 2; set := {element .. MAX (SET)}; ASSERT (element IN set); ASSERT (set = {MIN (SET) + 2 .. MAX (SET)}); ASSERT (-set = {MIN (SET), MIN (SET) + 1}); element := MIN (SET) + 2; set := {element .. MIN (SET)}; ASSERT (~(element IN set)); ASSERT (set = {element .. MIN (SET)}); ASSERT (set = {}); END Test. negative: huge integer as too small first set element MODULE Test; VAR element: HUGEINT; set: SET; BEGIN element := MIN (SET) - 1;set := {element .. MAX (SET)}; END Test. negative: huge integer as too large first set element MODULE Test; VAR element: HUGEINT; set: SET; BEGIN element := MAX (SET) + 1;set := {element .. MAX (SET)}; END Test. positive: huge integer as last set element MODULE Test; VAR element: HUGEINT; set: SET; BEGIN element := MAX (SET); set := {MIN (SET) .. element}; ASSERT (element IN set); ASSERT (set = {MIN (SET) .. MAX (SET)}); ASSERT (-set = {}); element := MAX (SET); set := {MAX (SET) .. element}; ASSERT (element IN set); ASSERT (set = {MAX (SET) .. MAX (SET)}); ASSERT (set = {MAX (SET)}); element := MAX (SET) - 2; set := {MIN (SET) .. element}; ASSERT (element IN set); ASSERT (set = {MIN (SET) .. MAX (SET) - 2}); ASSERT (-set = {MAX (SET) - 1, MAX (SET)}); element := MAX (SET) - 2; set := {MAX (SET).. element}; ASSERT (~(element IN set)); ASSERT (set = {MAX (SET) .. element}); ASSERT (set = {}); END Test. negative: huge integer as too small last set element MODULE Test; VAR element: HUGEINT; set: SET; BEGIN element := MIN (SET) - 1;set := {MIN (SET) .. element}; END Test. negative: huge integer as too large last set element MODULE Test; VAR element: HUGEINT; set: SET; BEGIN element := MAX (SET) + 1;set := {MIN (SET) .. element}; END Test. positive: huge integers as set elements MODULE Test; VAR first, last: HUGEINT; set: SET; BEGIN first := MIN (SET); last := MAX (SET); set := {first .. last}; ASSERT (set = {MIN (SET) .. MAX (SET)}); ASSERT (first IN set); ASSERT (last IN set); ASSERT (-set = {}); first := MIN (SET) + 2; last := MAX (SET) - 2; set := {first .. last}; ASSERT (set = {MIN (SET) + 2 .. MAX (SET) - 2}); ASSERT (first IN set); ASSERT (last IN set); ASSERT (-set = {MIN (SET), MIN (SET) + 1, MAX (SET) - 1, MAX (SET)}); first := MIN (SET) + 2; last := first; set := {first .. last}; ASSERT (set = {first}); first := MIN (SET) + 2; last := first + 1; set := {first .. last}; ASSERT (set = {first, last}); first := MIN (SET) + 2; last := first - 1; set := {first .. last}; ASSERT (set = {}); END Test. # odd test positive: odd test on short integer MODULE Test; VAR value: SHORTINT; BEGIN value := 0; ASSERT (~ODD (value)); ASSERT (ODD (value + 1)); value := 5; ASSERT (ODD (value)); ASSERT (~ODD (value + 1)); value := -5; ASSERT (ODD (value)); ASSERT (~ODD (value + 1)); END Test. positive: odd test on integer MODULE Test; VAR value: INTEGER; BEGIN value := 0; ASSERT (~ODD (value)); ASSERT (ODD (value + 1)); value := 5; ASSERT (ODD (value)); ASSERT (~ODD (value + 1)); value := -5; ASSERT (ODD (value)); ASSERT (~ODD (value + 1)); END Test. positive: odd test on long integer MODULE Test; VAR value: LONGINT; BEGIN value := 0; ASSERT (~ODD (value)); ASSERT (ODD (value + 1)); value := 5; ASSERT (ODD (value)); ASSERT (~ODD (value + 1)); value := -5; ASSERT (ODD (value)); ASSERT (~ODD (value + 1)); END Test. positive: odd test on huge integer MODULE Test; VAR value: HUGEINT; BEGIN value := 0; ASSERT (~ODD (value)); ASSERT (ODD (value + 1)); value := 5; ASSERT (ODD (value)); ASSERT (~ODD (value + 1)); value := -5; ASSERT (ODD (value)); ASSERT (~ODD (value + 1)); END Test. # explicit basic type conversions positive: long on short integer MODULE Test; VAR value: SHORTINT; BEGIN value := 11H; ASSERT (LONG (value) = 11H); ASSERT (LONG (value) = LONG (11H)); END Test. positive: long on integer MODULE Test; VAR value: INTEGER; BEGIN value := 1122H; ASSERT (LONG (value) = 1122H); ASSERT (LONG (value) = LONG (1122H)); END Test. positive: long on long integer MODULE Test; VAR value: LONGINT; BEGIN value := 11223344H; ASSERT (LONG (value) = 11223344H); ASSERT (LONG (value) = LONG (11223344H)); END Test. positive: short on integer MODULE Test; VAR value: INTEGER; BEGIN value := 1122H; ASSERT (SHORT (value) = SHORT (INTEGER(1122H))); END Test. positive: short on long integer MODULE Test; VAR value: LONGINT; BEGIN value := 11223344H;ASSERT (SHORT (value) = SHORT (LONGINT(11223344H))); END Test. positive: short on huge integer MODULE Test; VAR value: HUGEINT; BEGIN value := 1122334455667788H; ASSERT (SHORT (value) = SHORT (HUGEINT(1122334455667788H))); END Test. positive: entier on reals MODULE Test; VAR value: REAL; BEGIN value := 0; ASSERT (ENTIER (value) = 0); value := 1; ASSERT (ENTIER (value) = 1); value := 1.75; ASSERT (ENTIER (value) = 1); value := -1; ASSERT (ENTIER (value) = -1); value := -1.75; ASSERT (ENTIER (value) = -2); END Test. positive: entier on long reals MODULE Test; VAR value: LONGREAL; BEGIN value := 0; ASSERT (ENTIER (value) = 0); value := 1; ASSERT (ENTIER (value) = 1); value := 1.75; ASSERT (ENTIER (value) = 1); value := -1; ASSERT (ENTIER (value) = -1); value := -1.75; ASSERT (ENTIER (value) = -2); END Test. # arithmetic operations positive: addition on short integers MODULE Test; VAR a, b: SHORTINT; BEGIN a := 3; b := 2; ASSERT (a + b = +5); ASSERT (a + b = 3 + 2); a := -3; b := 2; ASSERT (a + b = -1); ASSERT (a + b = (-3) + 2); a := 3; b := -2; ASSERT (a + b = +1); ASSERT (a + b = 3 + (-2)); a := -3; b := -2; ASSERT (a + b = -5); ASSERT (a + b = (-3) + (-2)); a := MAX (SHORTINT); b := MIN (SHORTINT) + 1; ASSERT (a + b = 0); ASSERT (a + b = MAX (SHORTINT) + MIN (SHORTINT) + 1); END Test. positive: addition on integers MODULE Test; VAR a, b: INTEGER; BEGIN a := 3; b := 2; ASSERT (a + b = +5); ASSERT (a + b = 3 + 2); a := -3; b := 2; ASSERT (a + b = -1); ASSERT (a + b = (-3) + 2); a := 3; b := -2; ASSERT (a + b = +1); ASSERT (a + b = 3 + (-2)); a := -3; b := -2; ASSERT (a + b = -5); ASSERT (a + b = (-3) + (-2)); a := MAX (INTEGER); b := MIN (INTEGER) + 1; ASSERT (a + b = 0); ASSERT (a + b = MAX (INTEGER) + MIN (INTEGER) + 1); END Test. positive: addition on long integers MODULE Test; VAR a, b: LONGINT; BEGIN a := 3; b := 2; ASSERT (a + b = +5); ASSERT (a + b = 3 + 2); a := -3; b := 2; ASSERT (a + b = -1); ASSERT (a + b = (-3) + 2); a := 3; b := -2; ASSERT (a + b = +1); ASSERT (a + b = 3 + (-2)); a := -3; b := -2; ASSERT (a + b = -5); ASSERT (a + b = (-3) + (-2)); a := MAX (LONGINT); b := MIN (LONGINT) + 1; ASSERT (a + b = 0); ASSERT (a + b = MAX (LONGINT) + MIN (LONGINT) + 1); END Test. positive: addition on huge integers MODULE Test; VAR a, b: HUGEINT; BEGIN a := 3; b := 2; ASSERT (a + b = +5); ASSERT (a + b = 3 + 2); a := -3; b := 2; ASSERT (a + b = -1); ASSERT (a + b = (-3) + 2); a := 3; b := -2; ASSERT (a + b = +1); ASSERT (a + b = 3 + (-2)); a := -3; b := -2; ASSERT (a + b = -5); ASSERT (a + b = (-3) + (-2)); a := MAX (HUGEINT); b := MIN (HUGEINT) + 1; ASSERT (a + b = 0); ASSERT (a + b = MAX (HUGEINT) + MIN (HUGEINT) + 1); END Test. positive: addition on reals MODULE Test; VAR a, b: REAL; BEGIN a := 3.5; b := 2.5; ASSERT (a + b = +6); ASSERT (a + b = 3.5 + 2.5); a := -3.5; b := 2.5; ASSERT (a + b = -1); ASSERT (a + b = (-3.5) + 2.5); a := 3.5; b := -2.5; ASSERT (a + b = +1); ASSERT (a + b = 3.5 + (-2.5)); a := -3.5; b := -2.5; ASSERT (a + b = -6); ASSERT (a + b = (-3.5) + (-2.5)); END Test. positive: addition on long reals MODULE Test; VAR a, b: LONGREAL; BEGIN a := 3; b := 2; ASSERT (a + b = +5); ASSERT (a + b = 3 + 2); a := -3; b := 2; ASSERT (a + b = -1); ASSERT (a + b = (-3) + 2); a := 3; b := -2; ASSERT (a + b = +1); ASSERT (a + b = 3 + (-2)); a := -3; b := -2; ASSERT (a + b = -5); ASSERT (a + b = (-3) + (-2)); END Test. positive: subtraction on short integers MODULE Test; VAR a, b: SHORTINT; BEGIN a := 3; b := 2; ASSERT (a - b = +1); ASSERT (a - b = 3 - 2); a := -3; b := 2; ASSERT (a - b = -5); ASSERT (a - b = (-3) - 2); a := 3; b := -2; ASSERT (a - b = +5); ASSERT (a - b = 3 - (-2)); a := -3; b := -2; ASSERT (a - b = -1); ASSERT (a - b = (-3) - (-2)); a := MIN (SHORTINT) + 1; b := MAX (SHORTINT); ASSERT (a - b = 2); ASSERT (a - b = SHORT (INTEGER(MIN (SHORTINT) + 1 - MAX (SHORTINT)))); END Test. positive: subtraction on integers MODULE Test; VAR a, b: INTEGER; BEGIN a := 3; b := 2; ASSERT (a - b = +1); ASSERT (a - b = 3 - 2); a := -3; b := 2; ASSERT (a - b = -5); ASSERT (a - b = (-3) - 2); a := 3; b := -2; ASSERT (a - b = +5); ASSERT (a - b = 3 - (-2)); a := -3; b := -2; ASSERT (a - b = -1); ASSERT (a - b = (-3) - (-2)); a := MIN (INTEGER) + 1; b := MAX (INTEGER); ASSERT (a - b = 2); ASSERT (a - b = SHORT (LONGINT(MIN (INTEGER) + 1 - MAX (INTEGER)))); END Test. positive: subtraction on long integers MODULE Test; VAR a, b: LONGINT; BEGIN a := 3; b := 2; ASSERT (a - b = +1); ASSERT (a - b = 3 - 2); a := -3; b := 2; ASSERT (a - b = -5); ASSERT (a - b = (-3) - 2); a := 3; b := -2; ASSERT (a - b = +5); ASSERT (a - b = 3 - (-2)); a := -3; b := -2; ASSERT (a - b = -1); ASSERT (a - b = (-3) - (-2)); a := MIN (LONGINT) + 1; b := MAX (LONGINT); ASSERT (a - b = 2); (* ASSERT (a - b = SHORT (MIN (LONGINT) + 1 - MAX (LONGINT))); *) END Test. positive: subtraction on huge integers MODULE Test; VAR a, b: HUGEINT; BEGIN a := 3; b := 2; ASSERT (a - b = +1); ASSERT (a - b = 3 - 2); a := -3; b := 2; ASSERT (a - b = -5); ASSERT (a - b = (-3) - 2); a := 3; b := -2; ASSERT (a - b = +5); ASSERT (a - b = 3 - (-2)); a := -3; b := -2; ASSERT (a - b = -1); ASSERT (a - b = (-3) - (-2)); a := MIN (HUGEINT) + 1; b := MAX (HUGEINT); ASSERT (a - b = 2); ASSERT (a - b = MIN (HUGEINT) + 1 - MAX (HUGEINT)); END Test. positive: subtraction on reals MODULE Test; VAR a, b: REAL; BEGIN a := 3.5; b := 2.5; ASSERT (a - b = +1); ASSERT (a - b = 3.5 - 2.5); a := -3.5; b := 2.5; ASSERT (a - b = -6); ASSERT (a - b = (-3.5) - 2.5); a := 3.5; b := -2.5; ASSERT (a - b = +6); ASSERT (a - b = 3.5 - (-2.5)); a := -3.5; b := -2.5; ASSERT (a - b = -1); ASSERT (a - b = (-3.5) - (-2.5)); END Test. positive: subtraction on long reals MODULE Test; VAR a, b: LONGREAL; BEGIN a := 3.5; b := 2.5; ASSERT (a - b = +1); ASSERT (a - b = 3.5 - 2.5); a := -3.5; b := 2.5; ASSERT (a - b = -6); ASSERT (a - b = (-3.5) - 2.5); a := 3.5; b := -2.5; ASSERT (a - b = +6); ASSERT (a - b = 3.5 - (-2.5)); a := -3.5; b := -2.5; ASSERT (a - b = -1); ASSERT (a - b = (-3.5) - (-2.5)); END Test. positive: multiplication on short integers MODULE Test; VAR a, b: SHORTINT; BEGIN a := 3; b := 2; ASSERT (a * b = +6); ASSERT (a * b = 3 * 2); a := -3; b := 2; ASSERT (a * b = -6); ASSERT (a * b = (-3) * 2); a := 3; b := -2; ASSERT (a * b = -6); ASSERT (a * b = 3 * (-2)); a := -3; b := -2; ASSERT (a * b = +6); ASSERT (a * b = (-3) * (-2)); a := MAX (SHORTINT); b := MAX (SHORTINT); ASSERT (a * b = 1); ASSERT (a * b = SHORT (INTEGER(MAX (SHORTINT) * MAX (SHORTINT)))); END Test. positive: multiplication on integers MODULE Test; VAR a, b: INTEGER; BEGIN a := 3; b := 2; ASSERT (a * b = +6); ASSERT (a * b = 3 * 2); a := -3; b := 2; ASSERT (a * b = -6); ASSERT (a * b = (-3) * 2); a := 3; b := -2; ASSERT (a * b = -6); ASSERT (a * b = 3 * (-2)); a := -3; b := -2; ASSERT (a * b = +6); ASSERT (a * b = (-3) * (-2)); a := MAX (INTEGER); b := MAX (INTEGER); ASSERT (a * b = 1); ASSERT (a * b = SHORT (LONGINT(MAX (INTEGER) * MAX (INTEGER)))); END Test. positive: multiplication on long integers MODULE Test; VAR a, b: LONGINT; BEGIN a := 3; b := 2; ASSERT (a * b = +6); ASSERT (a * b = 3 * 2); a := -3; b := 2; ASSERT (a * b = -6); ASSERT (a * b = (-3) * 2); a := 3; b := -2; ASSERT (a * b = -6); ASSERT (a * b = 3 * (-2)); a := -3; b := -2; ASSERT (a * b = +6); ASSERT (a * b = (-3) * (-2)); a := MAX (LONGINT); b := MAX (LONGINT); ASSERT (a * b = 1); (*ASSERT (a * b = SHORT (HUGEINT(MAX (LONGINT) * MAX (LONGINT))));*) END Test. positive: multiplication on huge integers MODULE Test; VAR a, b: HUGEINT; BEGIN a := 3; b := 2; ASSERT (a * b = +6); ASSERT (a * b = 3 * 2); a := -3; b := 2; ASSERT (a * b = -6); ASSERT (a * b = (-3) * 2); a := 3; b := -2; ASSERT (a * b = -6); ASSERT (a * b = 3 * (-2)); a := -3; b := -2; ASSERT (a * b = +6); ASSERT (a * b = (-3) * (-2)); a := MAX (HUGEINT); b := MAX (HUGEINT); ASSERT (a * b = 1); ASSERT (a * b = MAX (HUGEINT) * MAX (HUGEINT)); END Test. positive: multiplication on reals MODULE Test; VAR a, b: REAL; BEGIN a := 3.5; b := 2.5; ASSERT (a * b = +8.75); ASSERT (a * b = 3.5 * 2.5); a := -3.5; b := 2.5; ASSERT (a * b = -8.75); ASSERT (a * b = (-3.5) * 2.5); a := 3.5; b := -2.5; ASSERT (a * b = -8.75); ASSERT (a * b = 3.5 * (-2.5)); a := -3.5; b := -2.5; ASSERT (a * b = +8.75); ASSERT (a * b = (-3.5) * (-2.5)); END Test. positive: multiplication on long reals MODULE Test; VAR a, b: LONGREAL; BEGIN a := 3.5; b := 2.5; ASSERT (a * b = +8.75); ASSERT (a * b = 3.5 * 2.5); a := -3.5; b := 2.5; ASSERT (a * b = -8.75); ASSERT (a * b = (-3.5) * 2.5); a := 3.5; b := -2.5; ASSERT (a * b = -8.75); ASSERT (a * b = 3.5 * (-2.5)); a := -3.5; b := -2.5; ASSERT (a * b = +8.75); ASSERT (a * b = (-3.5) * (-2.5)); END Test. positive: integer division on short integers with positive divisor MODULE Test; VAR a, b: SHORTINT; BEGIN a := 3; b := 2; ASSERT (a DIV b = +1); ASSERT (a DIV b = 3 DIV 2); a := -3; b := 2; ASSERT (a DIV b = -2); ASSERT (a DIV b = (-3) DIV 2); a := 2; b := 3; ASSERT (a DIV b = +0); ASSERT (a DIV b = 2 DIV 3); a := -2; b := 3; ASSERT (a DIV b = -1); ASSERT (a DIV b = (-2) DIV 3); a := MAX (SHORTINT); b := MAX (SHORTINT); ASSERT (a DIV b = 1); ASSERT (a DIV b = MAX (SHORTINT) DIV MAX (SHORTINT)); END Test. negative: integer division on short integers with negative divisor MODULE Test; VAR a, b, c: SHORTINT; BEGIN a := 3; b := -2; c := a DIV b; END Test. negative: integer division by zero on short integer MODULE Test; VAR a, b, r: SHORTINT; BEGIN a := 3; b := 0; r := a DIV b; END Test. positive: integer division on integers with positive divisor MODULE Test; VAR a, b: INTEGER; BEGIN a := 3; b := 2; ASSERT (a DIV b = +1); ASSERT (a DIV b = 3 DIV 2); a := -3; b := 2; ASSERT (a DIV b = -2); ASSERT (a DIV b = (-3) DIV 2); a := 2; b := 3; ASSERT (a DIV b = +0); ASSERT (a DIV b = 2 DIV 3); a := -2; b := 3; ASSERT (a DIV b = -1); ASSERT (a DIV b = (-2) DIV 3); a := MAX (INTEGER); b := MAX (INTEGER); ASSERT (a DIV b = 1); ASSERT (a DIV b = MAX (INTEGER) DIV MAX (INTEGER)); END Test. negative: integer division on integers with negative divisor MODULE Test; VAR a, b, c: INTEGER; BEGIN a := 3; b := -2; c := a DIV b; END Test. negative: integer division by zero on integer MODULE Test; VAR a, b, r: INTEGER; BEGIN a := 3; b := 0; r := a DIV b; END Test. positive: integer division on long integers with positive divisor MODULE Test; VAR a, b: LONGINT; BEGIN a := 3; b := 2; ASSERT (a DIV b = +1); ASSERT (a DIV b = 3 DIV 2); a := -3; b := 2; ASSERT (a DIV b = -2); ASSERT (a DIV b = (-3) DIV 2); a := 2; b := 3; ASSERT (a DIV b = +0); ASSERT (a DIV b = 2 DIV 3); a := -2; b := 3; ASSERT (a DIV b = -1); ASSERT (a DIV b = (-2) DIV 3); a := MAX (LONGINT); b := MAX (LONGINT); ASSERT (a DIV b = 1); ASSERT (a DIV b = MAX (LONGINT) DIV MAX (LONGINT)); END Test. negative: integer division on long integers with negative divisor MODULE Test; VAR a, b, c: LONGINT; BEGIN a := 3; b := -2; c := a DIV b; END Test. negative: integer division by zero on long integer MODULE Test; VAR a, b, r: LONGINT; BEGIN a := 3; b := 0; r := a DIV b; END Test. positive: integer division on huge integers with positive divisor MODULE Test; VAR a, b: HUGEINT; BEGIN a := 3; b := 2; ASSERT (a DIV b = +1); ASSERT (a DIV b = 3 DIV 2); a := -3; b := 2; ASSERT (a DIV b = -2); ASSERT (a DIV b = (-3) DIV 2); a := 2; b := 3; ASSERT (a DIV b = +0); ASSERT (a DIV b = 2 DIV 3); a := -2; b := 3; ASSERT (a DIV b = -1); ASSERT (a DIV b = (-2) DIV 3); a := MAX (HUGEINT); b := MAX (HUGEINT); ASSERT (a DIV b = 1); ASSERT (a DIV b = MAX (HUGEINT) DIV MAX (HUGEINT)); END Test. negative: integer division on huge integers with negative divisor MODULE Test; VAR a, b, c: HUGEINT; BEGIN a := 3; b := -2; c := a DIV b; END Test. negative: integer division by zero on huge integer MODULE Test; VAR a, b, r: HUGEINT; BEGIN a := 3; b := 0; r := a DIV b; END Test. positive: real division on short integers MODULE Test; VAR a, b: SHORTINT; BEGIN a := 3; b := 2; ASSERT (a / b = 1.5); ASSERT (a / b = 3 / 2); END Test. positive: real division on integers MODULE Test; VAR a, b: INTEGER; BEGIN a := 3; b := 2; ASSERT (a / b = 1.5); ASSERT (a / b = 3 / 2); END Test. positive: real division on long integers MODULE Test; VAR a, b: LONGINT; BEGIN a := 3; b := 2; ASSERT (a / b = 1.5); ASSERT (a / b = 3 / 2); END Test. positive: real division on huge integers MODULE Test; VAR a, b: HUGEINT; BEGIN a := 3; b := 2; ASSERT (a / b = 1.5); ASSERT (a / b = 3 / 2); END Test. positive: real division on reals MODULE Test; VAR a, b: REAL; BEGIN a := 3; b := 2; ASSERT (a / b = 1.5); ASSERT (a / b = 3 / 2); END Test. positive: real division on long reals MODULE Test; VAR a, b: LONGREAL; BEGIN a := 3; b := 2; ASSERT (a / b = 1.5); ASSERT (a / b = 3 / 2); END Test. positive: modulo on short integers MODULE Test; VAR a, b: SHORTINT; BEGIN a := 3; b := 2; ASSERT (a MOD b = +1); ASSERT (3 MOD b = +1); ASSERT (a MOD 2 = +1); ASSERT (a MOD b = 3 MOD 2); a := -3; b := 2; ASSERT (a MOD b = +1); ASSERT ((-3) MOD b = +1); ASSERT (a MOD 2 = +1); ASSERT (a MOD b = (-3) MOD 2); a := 2; b := 3; ASSERT (a MOD b = +2); ASSERT (2 MOD b = +2); ASSERT (a MOD 3 = +2); ASSERT (a MOD b = 2 MOD 3); a := -2; b := 3; ASSERT (a MOD b = 1); ASSERT ((-2) MOD b = 1); ASSERT (a MOD 3 = 1); ASSERT (a MOD b = (-2) MOD 3); a := MAX (SHORTINT); b := MAX (SHORTINT); ASSERT (a MOD b = 0); ASSERT (a MOD b = MAX (SHORTINT) MOD MAX (SHORTINT)); END Test. negative: modulo by zero on short integer MODULE Test; VAR a, b, r: SHORTINT; BEGIN a := 3; b := 0; r := a MOD b; END Test. positive: modulo on integers MODULE Test; VAR a, b: INTEGER; BEGIN a := 3; b := 2; ASSERT (a MOD b = +1); ASSERT (3 MOD b = +1); ASSERT (a MOD 2 = +1); ASSERT (a MOD b = 3 MOD 2); a := -3; b := 2; ASSERT (a MOD b = +1); ASSERT ((-3) MOD b = +1); ASSERT (a MOD 2 = +1); ASSERT (a MOD b = (-3) MOD 2); a := 2; b := 3; ASSERT (a MOD b = +2); ASSERT (2 MOD b = +2); ASSERT (a MOD 3 = +2); ASSERT (a MOD b = 2 MOD 3); a := -2; b := 3; ASSERT (a MOD b = 1); ASSERT ((-2) MOD b = 1); ASSERT (a MOD 3 = 1); ASSERT (a MOD b = (-2) MOD 3); a := MAX (INTEGER); b := MAX (INTEGER); ASSERT (a MOD b = 0); ASSERT (a MOD b = MAX (INTEGER) MOD MAX (INTEGER)); END Test. negative: modulo by zero on integer MODULE Test; VAR a, b, r: INTEGER; BEGIN a := 3; b := 0; r := a MOD b; END Test. positive: modulo on long integers MODULE Test; VAR a, b: LONGINT; BEGIN a := 3; b := 2; ASSERT (a MOD b = +1); ASSERT (3 MOD b = +1); ASSERT (a MOD 2 = +1); ASSERT (a MOD b = 3 MOD 2); a := -3; b := 2; ASSERT (a MOD b = +1); ASSERT ((-3) MOD b = +1); ASSERT (a MOD 2 = +1); ASSERT (a MOD b = (-3) MOD 2); a := 2; b := 3; ASSERT (a MOD b = +2); ASSERT (2 MOD b = +2); ASSERT (a MOD 3 = +2); ASSERT (a MOD b = 2 MOD 3); a := -2; b := 3; ASSERT (a MOD b = 1); ASSERT ((-2) MOD b = 1); ASSERT (a MOD 3 = 1); ASSERT (a MOD b = (-2) MOD 3); a := MAX (LONGINT); b := MAX (LONGINT); ASSERT (a MOD b = 0); ASSERT (a MOD b = MAX (LONGINT) MOD MAX (LONGINT)); END Test. negative: modulo by zero on long integer MODULE Test; VAR a, b, r: LONGINT; BEGIN a := 3; b := 0; r := a MOD b; END Test. positive: modulo on huge integers MODULE Test; VAR a, b: HUGEINT; BEGIN a := 3; b := 2; ASSERT (a MOD b = +1); ASSERT (3 MOD b = +1); ASSERT (a MOD 2 = +1); ASSERT (a MOD b = 3 MOD 2); a := -3; b := 2; ASSERT (a MOD b = +1); ASSERT ((-3) MOD b = +1); ASSERT (a MOD 2 = +1); ASSERT (a MOD b = (-3) MOD 2); a := 2; b := 3; ASSERT (a MOD b = +2); ASSERT (2 MOD b = +2); ASSERT (a MOD 3 = +2); ASSERT (a MOD b = 2 MOD 3); a := -2; b := 3; ASSERT (a MOD b = 1); ASSERT ((-2) MOD b = 1); ASSERT (a MOD 3 = 1); ASSERT (a MOD b = (-2) MOD 3); a := MAX (HUGEINT); b := MAX (HUGEINT); ASSERT (a MOD b = 0); ASSERT (a MOD b = MAX (HUGEINT) MOD MAX (HUGEINT)); END Test. negative: modulo by zero on huge integer MODULE Test; VAR a, b, r: HUGEINT; BEGIN a := 3; b := 0; r := a MOD b; END Test. positive: arithmetic shift on short integer MODULE Test; VAR a, b: SHORTINT; BEGIN a := 6; b := 2; ASSERT (ASH (a, b) = 24); ASSERT (ASH (a, b) = ASH (a, 2)); ASSERT (ASH (a, b) = ASH (6, 2)); a := 6; b := 0; ASSERT (ASH (a, b) = 6); ASSERT (ASH (a, b) = ASH (a, 0)); ASSERT (ASH (a, b) = ASH (6, 0)); a := 6; b := -2; ASSERT (ASH (a, b) = 1); ASSERT (ASH (a, b) = ASH (a, -2)); ASSERT (ASH (a, b) = ASH (6, -2)); END Test. positive: arithmetic shift on integer MODULE Test; VAR a, b: INTEGER; BEGIN a := 6; b := 2; ASSERT (ASH (a, b) = 24); ASSERT (ASH (a, b) = ASH (a, 2)); ASSERT (ASH (a, b) = ASH (6, 2)); a := 6; b := 0; ASSERT (ASH (a, b) = 6); ASSERT (ASH (a, b) = ASH (a, 0)); ASSERT (ASH (a, b) = ASH (6, 0)); a := 6; b := -2; ASSERT (ASH (a, b) = 1); ASSERT (ASH (a, b) = ASH (a, -2)); ASSERT (ASH (a, b) = ASH (6, -2)); END Test. positive: arithmetic shift on long integer MODULE Test; VAR a, b: LONGINT; BEGIN a := 6; b := 2; ASSERT (ASH (a, b) = 24); ASSERT (ASH (a, b) = ASH (a, 2)); ASSERT (ASH (a, b) = ASH (6, 2)); a := 6; b := 0; ASSERT (ASH (a, b) = 6); ASSERT (ASH (a, b) = ASH (a, 0)); ASSERT (ASH (a, b) = ASH (6, 0)); a := 6; b := -2; ASSERT (ASH (a, b) = 1); ASSERT (ASH (a, b) = ASH (a, -2)); ASSERT (ASH (a, b) = ASH (6, -2)); END Test. positive: arithmetic shift on huge integer MODULE Test; VAR a, b: HUGEINT; BEGIN a := 6; b := 2; ASSERT (ASH (a, b) = 24); ASSERT (ASH (a, b) = ASH (a, 2)); ASSERT (ASH (a, b) = ASH (6, 2)); a := 6; b := 0; ASSERT (ASH (a, b) = 6); ASSERT (ASH (a, b) = ASH (a, 0)); ASSERT (ASH (a, b) = ASH (6, 0)); a := 6; b := -2; ASSERT (ASH (a, b) = 1); ASSERT (ASH (a, b) = ASH (a, -2)); ASSERT (ASH (a, b) = ASH (6, -2)); END Test. # set operators positive: set union MODULE Test; VAR a, b: SET; BEGIN a := {}; b := {}; ASSERT (a + b = {}); ASSERT (a + b = {} + {}); a := {1, 2}; b := {}; ASSERT (a + b = {1, 2}); ASSERT (a + b = {1, 2} + {}); a := {}; b := {2, 3}; ASSERT (a + b = {2, 3}); ASSERT (a + b = {} + {2, 3}); a := {1, 2}; b := {2, 3}; ASSERT (a + b = {1..3}); ASSERT (a + b = {1, 2} + {2, 3}); a := {}; b := {}; ASSERT (a + {} = {}); ASSERT ({} + b = {} + {}); a := {1, 2}; b := {}; ASSERT (a + {} = {1, 2}); ASSERT ({1,2} + b = {1, 2} + {}); a := {}; b := {2, 3}; ASSERT (a + {2,3} = {2, 3}); ASSERT ({} + b = {} + {2, 3}); a := {1, 2}; b := {2, 3}; ASSERT (a + {2,3} = {1..3}); ASSERT ({1,2} + b = {1, 2} + {2, 3}); END Test. positive: set difference MODULE Test; VAR a, b: SET; BEGIN a := {}; b := {}; ASSERT (a - b = {}); ASSERT (a - b = {} - {}); a := {1, 2}; b := {}; ASSERT (a - b = {1, 2}); ASSERT (a - b = {1, 2} - {}); a := {}; b := {2, 3}; ASSERT (a - b = {}); ASSERT (a - b = {} - {2, 3}); a := {1, 2}; b := {2, 3}; ASSERT (a - b = {1}); ASSERT (a - b = {1, 2} - {2, 3}); a := {}; b := {}; ASSERT (a - {} = {}); ASSERT ({} - b = {} - {}); a := {1, 2}; b := {}; ASSERT (a - {} = {1, 2}); ASSERT ({1,2} - b = {1, 2} - {}); a := {}; b := {2, 3}; ASSERT (a - {2,3} = {}); ASSERT ({} - b = {} - {2, 3}); a := {1, 2}; b := {2, 3}; ASSERT (a - {2,3} = {1}); ASSERT ({1,2} - b = {1, 2} - {2, 3}); END Test. positive: set intersection MODULE Test; VAR a, b: SET; BEGIN a := {}; b := {}; ASSERT (a * b = {}); ASSERT (a * b = {} * {}); a := {1, 2}; b := {}; ASSERT (a * b = {}); ASSERT (a * b = {1, 2} * {}); a := {}; b := {2, 3}; ASSERT (a * b = {}); ASSERT (a * b = {} * {2, 3}); a := {1, 2}; b := {2, 3}; ASSERT (a * b = {2}); ASSERT (a * b = {1, 2} * {2, 3}); a := {}; b := {}; ASSERT ({} * b = {}); ASSERT (a * {} = {} * {}); a := {1, 2}; b := {}; ASSERT ({1,2} * b = {}); ASSERT (a * {} = {1, 2} * {}); a := {}; b := {2, 3}; ASSERT (a * {2,3} = {}); ASSERT ({} * b = {} * {2, 3}); a := {1, 2}; b := {2, 3}; ASSERT ({1,2} * b = {2}); ASSERT (a * {2,3} = {1, 2} * {2, 3}); END Test. positive: symmetric set difference MODULE Test; VAR a, b: SET; BEGIN a := {}; b := {}; ASSERT (a / b = {}); ASSERT (a / b = {} / {}); a := {1, 2}; b := {}; ASSERT (a / b = {1, 2}); ASSERT (a / b = {1, 2} / {}); a := {}; b := {2, 3}; ASSERT (a / b = {2, 3}); ASSERT (a / b = {} / {2, 3}); a := {1, 2}; b := {2, 3}; ASSERT (a / b = {1, 3}); ASSERT (a / b = {1, 2} / {2, 3}); a := {}; b := {}; ASSERT (a / {} = {}); ASSERT (a / {} = {} / {}); a := {1, 2}; b := {}; ASSERT ({1,2} / b = {1, 2}); ASSERT (a / {} = {1, 2} / {}); a := {}; b := {2, 3}; ASSERT ({} / b = {2, 3}); ASSERT (a / {2,3} = {} / {2, 3}); a := {1, 2}; b := {2, 3}; ASSERT ({1,2} / b = {1, 3}); ASSERT (a / {2,3} = {1, 2} / {2, 3}); END Test. # type guards positive: type guard on same global record MODULE Test; TYPE R = RECORD b: BOOLEAN END; VAR r: R; BEGIN r.b := TRUE; ASSERT (r(R).b); END Test. positive: type guard on same local record MODULE Test; PROCEDURE Procedure; TYPE R = RECORD b: BOOLEAN END; VAR r: R; BEGIN r.b := TRUE; ASSERT (r(R).b); END Procedure; BEGIN Procedure; END Test. positive: type guard on same parameter record MODULE Test; TYPE R = RECORD b: BOOLEAN END; VAR r: R; PROCEDURE Procedure (r: R); BEGIN ASSERT (r(R).b); END Procedure; BEGIN r.b := TRUE; Procedure (r); END Test. positive: type guard on same variable parameter record MODULE Test; TYPE R = RECORD b: BOOLEAN END; VAR r: R; PROCEDURE Procedure (VAR r: R); BEGIN ASSERT (r(R).b); END Procedure; BEGIN r.b := TRUE; Procedure (r); END Test. positive: type guard on same constant parameter record MODULE Test; TYPE R = RECORD b: BOOLEAN END; VAR r: R; PROCEDURE Procedure (CONST r: R); BEGIN ASSERT (r(R).b); END Procedure; BEGIN r.b := TRUE; Procedure (r); END Test. positive: type guard on variable parameter record MODULE Test; TYPE R0 = RECORD END; R1 = RECORD (R0) b: BOOLEAN END; VAR r: R1; PROCEDURE Procedure (VAR r: R0); BEGIN ASSERT (r(R1).b); END Procedure; BEGIN r.b := TRUE; Procedure (r); END Test. negative: unsatisfied type guard on variable parameter record MODULE Test; TYPE R0 = RECORD END; R1 = RECORD (R0) b: BOOLEAN END; VAR r: R0; PROCEDURE Procedure (VAR r: R0); BEGIN ASSERT (r(R1).b); END Procedure; BEGIN Procedure (r); END Test. positive: type guard on constant parameter record MODULE Test; TYPE R0 = RECORD END; R1 = RECORD (R0) b: BOOLEAN END; VAR r: R1; PROCEDURE Procedure (CONST r: R0); BEGIN ASSERT (r(R1).b); END Procedure; BEGIN r.b := TRUE; Procedure (r); END Test. negative: unsatisfied type guard on constant parameter record MODULE Test; TYPE R0 = RECORD END; R1 = RECORD (R0) b: BOOLEAN END; VAR r: R0; PROCEDURE Procedure (CONST r: R0); BEGIN ASSERT (r(R1).b); END Procedure; BEGIN Procedure (r); END Test. positive: type guard on same pointer to record MODULE Test; TYPE R = RECORD b: BOOLEAN END; P = POINTER TO R; VAR p: P; BEGIN NEW (p); p.b := TRUE; ASSERT (p(P).b); ASSERT (p^(R).b); END Test. positive: type guard on pointer to record MODULE Test; TYPE R0 = RECORD END; P0 = POINTER TO R0 TYPE R1 = RECORD (R0) b: BOOLEAN END; P1 = POINTER TO R1; VAR p0: P0; p1: P1; BEGIN NEW (p1); p1.b := TRUE; p0 := p1; ASSERT (p0(P1).b); ASSERT (p0^(R1).b); END Test. positive: type guard on returned pointer to record MODULE Test; TYPE R0 = RECORD END; P0 = POINTER TO R0 TYPE R1 = RECORD (R0) b: BOOLEAN END; P1 = POINTER TO R1; VAR p1: P1; PROCEDURE Function (): P0; BEGIN NEW (p1); p1.b := TRUE; RETURN p1; END Function; BEGIN ASSERT (Function ()(P1).b); ASSERT (Function ()^(R1).b); END Test. negative: unsatisfied type guard on pointer to record MODULE Test; TYPE R0 = RECORD END; P0 = POINTER TO R0; TYPE R1 = RECORD (R0) END; P1 = POINTER TO R1; VAR p0: P0; p1: P1; BEGIN NEW (p0); p1 := p0(P1); END Test. positive: type guard on nil pointer to same record MODULE Test; TYPE R = RECORD END; P = POINTER TO R; VAR p: P; BEGIN p := NIL; p := p(P); END Test. negative: type guard on nil pointer to record MODULE Test; TYPE R0 = RECORD END; P0 = POINTER TO R0; TYPE R1 = RECORD (R0) END; P1 = POINTER TO R1; VAR p0: P0; p1: P1; BEGIN p0 := NIL; p1 := p0(P1); END Test. negative: type guard on returned nil pointer to record MODULE Test; TYPE R0 = RECORD END; P0 = POINTER TO R0 TYPE R1 = RECORD (R0) END; P1 = POINTER TO R1; VAR p1: P1; PROCEDURE Function (): P0; BEGIN RETURN NIL; END Function; BEGIN p1 := Function ()(P1); END Test. positive: type guard on same object MODULE Test; TYPE O = OBJECT VAR b: BOOLEAN END O; VAR o: O; BEGIN NEW (o); o.b := TRUE; ASSERT (o(O).b); END Test. positive: type guard on object MODULE Test; TYPE O0 = OBJECT END O0; TYPE O1 = OBJECT (O0) VAR b: BOOLEAN END O1; VAR o0: O0; o1: O1; BEGIN NEW (o1); o1.b := TRUE; o0 := o1; ASSERT (o0(O1).b); END Test. positive: type guard on returned object MODULE Test; TYPE O0 = OBJECT END O0; TYPE O1 = OBJECT (O0) VAR b: BOOLEAN END O1; VAR o1: O1; PROCEDURE Function (): O0; BEGIN NEW (o1); o1.b := TRUE; RETURN o1; END Function; BEGIN ASSERT (Function ()(O1).b); END Test. negative: unsatisfied type guard on object MODULE Test; TYPE O0 = OBJECT END O0; TYPE O1 = OBJECT (O0) END O1; VAR o0: O0; o1: O1; BEGIN NEW (o0); o1 := o0(O1); END Test. positive: type guard on same nil object MODULE Test; TYPE O = OBJECT END O; VAR o: O; BEGIN o := NIL; o := o(O); END Test. negative: type guard on nil object MODULE Test; TYPE O0 = OBJECT END O0; TYPE O1 = OBJECT (O0) END O1; VAR o0: O0; o1: O1; BEGIN o0 := NIL; o1 := o0(O1); END Test. negative: type guard on returned nil object MODULE Test; TYPE O0 = OBJECT END O0; TYPE O1 = OBJECT (O0) END O1; VAR o1: O1; PROCEDURE Function (): O0; BEGIN RETURN NIL; END Function; BEGIN o1 := Function ()(O1); END Test. positive: type guard on base object MODULE Test; TYPE O0 = OBJECT; TYPE O1 = OBJECT (O0) VAR b: BOOLEAN END O1; VAR o0: O0; o1: O1; BEGIN NEW (o1); o1.b := TRUE; o0 := o1; ASSERT (o0(O1).b); END Test. positive: type guard on returned base object MODULE Test; TYPE O0 = OBJECT; TYPE O1 = OBJECT (O0) VAR b: BOOLEAN END O1; VAR o1: O1; PROCEDURE Function (): O0; BEGIN NEW (o1); o1.b := TRUE; RETURN o1; END Function; BEGIN ASSERT (Function ()(O1).b); END Test. negative: type guard on nil base object MODULE Test; TYPE O0 = OBJECT; TYPE O1 = OBJECT (O0) END O1; VAR o0: O0; o1: O1; BEGIN o0 := NIL; o1 := o0(O1); END Test. negative: type guard on returned nil base object MODULE Test; TYPE O0 = OBJECT; TYPE O1 = OBJECT (O0) END O1; VAR o1: O1; PROCEDURE Function (): O0; BEGIN RETURN NIL; END Function; BEGIN o1 := Function ()(O1); END Test. # type tests positive: type test on same global record MODULE Test; TYPE R = RECORD END; VAR r: R; BEGIN ASSERT (r IS R); END Test. positive: type test on same local record MODULE Test; PROCEDURE Procedure; TYPE R = RECORD END; VAR r: R; BEGIN ASSERT (r IS R); END Procedure; BEGIN Procedure; END Test. positive: type test on same parameter record MODULE Test; TYPE R = RECORD END; VAR r: R; PROCEDURE Procedure (r: R); BEGIN ASSERT (r IS R); END Procedure; BEGIN Procedure (r); END Test. positive: type test on same variable parameter record MODULE Test; TYPE R = RECORD END; VAR r: R; PROCEDURE Procedure (VAR r: R); BEGIN ASSERT (r IS R); END Procedure; BEGIN Procedure (r); END Test. positive: type test on same constant parameter record MODULE Test; TYPE R = RECORD END; VAR r: R; PROCEDURE Procedure (CONST r: R); BEGIN ASSERT (r IS R); END Procedure; BEGIN Procedure (r); END Test. positive: type test on variable parameter record MODULE Test; TYPE R0 = RECORD END; R1 = RECORD (R0) END; VAR r: R1; PROCEDURE Procedure (VAR r: R0); BEGIN ASSERT (r IS R1); END Procedure; BEGIN Procedure (r); END Test. positive: unsatisfied type test on variable parameter record MODULE Test; TYPE R0 = RECORD END; R1 = RECORD (R0) END; VAR r: R0; PROCEDURE Procedure (VAR r: R0); BEGIN ASSERT (~(r IS R1)); END Procedure; BEGIN Procedure (r); END Test. positive: type test on constant parameter record MODULE Test; TYPE R0 = RECORD END; R1 = RECORD (R0) END; VAR r: R1; PROCEDURE Procedure (CONST r: R0); BEGIN ASSERT (r IS R1); END Procedure; BEGIN Procedure (r); END Test. positive: unsatisfied type test on constant parameter record MODULE Test; TYPE R0 = RECORD END; R1 = RECORD (R0) END; VAR r: R0; PROCEDURE Procedure (CONST r: R0); BEGIN ASSERT (~(r IS R1)); END Procedure; BEGIN Procedure (r); END Test. positive: type test on same pointer to record MODULE Test; TYPE R = RECORD END; P = POINTER TO R; VAR p: P; BEGIN NEW (p); ASSERT (p IS P); ASSERT (p^ IS R); END Test. positive: type test on pointer to record MODULE Test; TYPE R0 = RECORD END; P0 = POINTER TO R0 TYPE R1 = RECORD (R0) END; P1 = POINTER TO R1; VAR p0: P0; p1: P1; BEGIN NEW (p1); p0 := p1; ASSERT (p0 IS P1); ASSERT (p0^ IS R1); END Test. positive: type test on returned pointer to record MODULE Test; TYPE R0 = RECORD END; P0 = POINTER TO R0 TYPE R1 = RECORD (R0) END; P1 = POINTER TO R1; VAR p1: P1; PROCEDURE Function (): P0; BEGIN NEW (p1); RETURN p1; END Function; BEGIN ASSERT (Function () IS P1); ASSERT (Function ()^ IS R1); END Test. positive: unsatisfied type test on pointer to record MODULE Test; TYPE R0 = RECORD END; P0 = POINTER TO R0 TYPE R1 = RECORD (R0) END; P1 = POINTER TO R1; VAR p0: P0; BEGIN NEW (p0); ASSERT (~(p0 IS P1)); ASSERT (~(p0^ IS R1)); END Test. positive: unsatisfied type test on returned pointer to record MODULE Test; TYPE R0 = RECORD END; P0 = POINTER TO R0 TYPE R1 = RECORD (R0) END; P1 = POINTER TO R1; VAR p0: P0; PROCEDURE Function (): P0; BEGIN NEW (p0); RETURN p0; END Function; BEGIN ASSERT (~(Function () IS P1)); ASSERT (~(Function ()^ IS R1)); END Test. positive: type test on nil pointer to same record MODULE Test; TYPE R = RECORD END; P = POINTER TO R; VAR p: P; result: BOOLEAN BEGIN p := NIL; result := p IS P; END Test. negative: type test on nil pointer to record MODULE Test; TYPE R0 = RECORD END; P0 = POINTER TO R0; TYPE R1 = RECORD (R0) END; P1 = POINTER TO R1; VAR p0: P0; result: BOOLEAN BEGIN p0 := NIL; result := p0 IS P1; END Test. negative: type test on returned nil pointer to record MODULE Test; TYPE R0 = RECORD END; P0 = POINTER TO R0; TYPE R1 = RECORD (R0) END; P1 = POINTER TO R1; VAR result: BOOLEAN PROCEDURE Function (): P0; BEGIN RETURN NIL; END Function; BEGIN result := Function () IS P1; END Test. positive: type test on same object MODULE Test; TYPE O = OBJECT END O; VAR o: O; BEGIN NEW (o); ASSERT (o IS O); END Test. positive: type test on object MODULE Test; TYPE O0 = OBJECT END O0; TYPE O1 = OBJECT (O0) END O1; VAR o0: O0; o1: O1; BEGIN NEW (o1); o0 := o1; ASSERT (o0 IS O1); END Test. positive: type test on returned object MODULE Test; TYPE O0 = OBJECT END O0; TYPE O1 = OBJECT (O0) END O1; VAR o1: O1; PROCEDURE Function (): O0; BEGIN NEW (o1); RETURN o1; END Function; BEGIN ASSERT (Function () IS O1); END Test. positive: unsatisfied type test on object MODULE Test; TYPE O0 = OBJECT END O0; TYPE O1 = OBJECT (O0) END O1; VAR o0: O0; BEGIN NEW (o0); ASSERT (~(o0 IS O1)); END Test. positive: unsatisfied type test on returned object MODULE Test; TYPE O0 = OBJECT END O0; TYPE O1 = OBJECT (O0) END O1; VAR o0: O0; PROCEDURE Function (): O0; BEGIN NEW (o0); RETURN o0; END Function; BEGIN ASSERT (~(Function () IS O1)); END Test. positive: type test on same nil object MODULE Test; TYPE O = OBJECT END O; VAR o: O; result: BOOLEAN; BEGIN o := NIL; result := o IS O; END Test. negative: type test on nil object MODULE Test; TYPE O0 = OBJECT END O0; TYPE O1 = OBJECT (O0) END O1; VAR o0: O0; result: BOOLEAN; BEGIN o0 := NIL; result := o0 IS O1; END Test. negative: type test on returned nil object MODULE Test; TYPE O0 = OBJECT END O0; TYPE O1 = OBJECT (O0) END O1; VAR result: BOOLEAN; PROCEDURE Function (): O0; BEGIN RETURN NIL; END Function; BEGIN result := Function () IS O1; END Test. positive: type test on base object MODULE Test; TYPE O0 = OBJECT; TYPE O1 = OBJECT (O0) END O1; VAR o0: O0; o1: O1; BEGIN NEW (o1); o0 := o1; ASSERT (o0 IS O1); END Test. positive: type test on returned base object MODULE Test; TYPE O0 = OBJECT; TYPE O1 = OBJECT (O0) END O1; VAR o1: O1; PROCEDURE Function (): O0; BEGIN NEW (o1); RETURN o1; END Function; BEGIN ASSERT (Function () IS O1); END Test. negative: type test on nil base object MODULE Test; TYPE O0 = OBJECT; TYPE O1 = OBJECT (O0) END O1; VAR o0: O0; result: BOOLEAN; BEGIN o0 := NIL; result := o0 IS O1; END Test. negative: type test on returned nil base object MODULE Test; TYPE O0 = OBJECT; TYPE O1 = OBJECT (O0) END O1; VAR result: BOOLEAN; PROCEDURE Function (): O0; BEGIN RETURN NIL; END Function; BEGIN result := Function () IS O1; END Test. # dereferencing positive: explicit dereference on pointer to record MODULE Test; VAR p: POINTER TO RECORD a: INTEGER END; BEGIN NEW (p); p^.a := 45; ASSERT (p.a = 45); END Test. negative: explicit dereference of nil pointer to record MODULE Test; VAR p: POINTER TO RECORD a: INTEGER END; BEGIN p := NIL; p^.a := 45; END Test. positive: implicit dereference on pointer to record MODULE Test; VAR p: POINTER TO RECORD a: INTEGER END; BEGIN NEW (p); p.a := 45; ASSERT (p^.a = 45); END Test. negative: implicit dereference of nil pointer to record MODULE Test; VAR p: POINTER TO RECORD a: INTEGER END; BEGIN p := NIL; p.a := 45; END Test. positive: explicit dereference on pointer to array MODULE Test; VAR p: POINTER TO ARRAY 10 OF INTEGER; BEGIN NEW (p); p^[4] := 45; ASSERT (p[4] = 45); END Test. positive: implicit dereference on pointer to array MODULE Test; VAR p: POINTER TO ARRAY 10 OF INTEGER; BEGIN NEW (p); p[4] := 45; ASSERT (p^[4] = 45); END Test. negative: explicit dereference of nil pointer to array MODULE Test; VAR p: POINTER TO ARRAY 10 OF INTEGER; BEGIN p := NIL; p^[4] := 45; END Test. negative: implicit dereference of nil pointer to array MODULE Test; VAR p: POINTER TO ARRAY 10 OF INTEGER; BEGIN p := NIL; p[4] := 45; END Test. # array length positive: length of one-dimensional open array MODULE Test; VAR a: ARRAY 10 OF INTEGER; PROCEDURE Procedure (p: ARRAY OF INTEGER; len: INTEGER); BEGIN ASSERT (LEN (p) = len); END Procedure; BEGIN Procedure (a, 10); Procedure (a, LEN (a)); END Test. positive: first dimension of one-dimensional open array MODULE Test; VAR a: ARRAY 10 OF INTEGER; PROCEDURE Procedure (p: ARRAY OF INTEGER; len: INTEGER); BEGIN ASSERT (LEN (p, 0) = len); END Procedure; BEGIN Procedure (a, 10); Procedure (a, LEN (a, 0)); END Test. positive: dynamic dimension of one-dimensional open array MODULE Test; VAR a: ARRAY 10 OF INTEGER; PROCEDURE Procedure (p: ARRAY OF INTEGER; dim, len: INTEGER); BEGIN ASSERT (LEN (p, dim) = len); END Procedure; BEGIN Procedure (a, 0, 10); Procedure (a, 0, LEN (a, 0)); END Test. negative: negative dynamic dimension of one-dimensional open array MODULE Test; VAR a: ARRAY 10 OF INTEGER; PROCEDURE Procedure (p: ARRAY OF INTEGER; dim: INTEGER); VAR len: LONGINT; BEGIN len := LEN (p, dim); END Procedure; BEGIN Procedure (a, -1); END Test. negative: invalid dynamic dimension of one-dimensional open array MODULE Test; VAR a: ARRAY 10 OF INTEGER; PROCEDURE Procedure (p: ARRAY OF INTEGER; dim: INTEGER); VAR len: LONGINT; BEGIN len := LEN (p, dim); END Procedure; BEGIN Procedure (a, 1); END Test. positive: length of two-dimensional open array MODULE Test; VAR a: ARRAY 10, 20 OF INTEGER; PROCEDURE Procedure (p: ARRAY OF ARRAY OF INTEGER; len: INTEGER); BEGIN ASSERT (LEN (p) = len); END Procedure; BEGIN Procedure (a, 10); Procedure (a, LEN (a)); END Test. positive: first dimension of two-dimensional open array MODULE Test; VAR a: ARRAY 10, 20 OF INTEGER; PROCEDURE Procedure (p: ARRAY OF ARRAY OF INTEGER; len: INTEGER); BEGIN ASSERT (LEN (p, 0) = len); END Procedure; BEGIN Procedure (a, 10); Procedure (a, LEN (a, 0)); END Test. positive: second dimension of two-dimensional open array MODULE Test; VAR a: ARRAY 10, 20 OF INTEGER; PROCEDURE Procedure (p: ARRAY OF ARRAY OF INTEGER; len: INTEGER); BEGIN ASSERT (LEN (p, 1) = len); END Procedure; BEGIN Procedure (a, 20); Procedure (a, LEN (a, 1)); END Test. positive: dynamic dimension of two-dimensional open array MODULE Test; VAR a: ARRAY 10, 20 OF INTEGER; PROCEDURE Procedure (p: ARRAY OF ARRAY OF INTEGER; dim, len: INTEGER); BEGIN ASSERT (LEN (p, dim) = len); END Procedure; BEGIN Procedure (a, 0, 10); Procedure (a, 0, LEN (a, 0)); Procedure (a, 1, 20); Procedure (a, 1, LEN (a, 1)); END Test. negative: negative dynamic dimension of two-dimensional open array MODULE Test; VAR a: ARRAY 10, 20 OF INTEGER; PROCEDURE Procedure (p: ARRAY OF ARRAY OF INTEGER; dim: INTEGER); VAR len: LONGINT; BEGIN len := LEN (p, dim); END Procedure; BEGIN Procedure (a, -1); END Test. negative: invalid dynamic dimension of two-dimensional open array MODULE Test; VAR a: ARRAY 10, 20 OF INTEGER; PROCEDURE Procedure (p: ARRAY OF ARRAY OF INTEGER; dim: INTEGER); VAR len: LONGINT; BEGIN len := LEN (p, dim); END Procedure; BEGIN Procedure (a, 2); END Test. positive: length of one-dimensional variable open array MODULE Test; VAR a: ARRAY 10 OF INTEGER; PROCEDURE Procedure (VAR p: ARRAY OF INTEGER; len: INTEGER); BEGIN ASSERT (LEN (p) = len); END Procedure; BEGIN Procedure (a, 10); Procedure (a, LEN (a)); END Test. positive: first dimension of one-dimensional variable open array MODULE Test; VAR a: ARRAY 10 OF INTEGER; PROCEDURE Procedure (VAR p: ARRAY OF INTEGER; len: INTEGER); BEGIN ASSERT (LEN (p, 0) = len); END Procedure; BEGIN Procedure (a, 10); Procedure (a, LEN (a, 0)); END Test. positive: dynamic dimension of one-dimensional variable open array MODULE Test; VAR a: ARRAY 10 OF INTEGER; PROCEDURE Procedure (VAR p: ARRAY OF INTEGER; dim, len: INTEGER); BEGIN ASSERT (LEN (p, dim) = len); END Procedure; BEGIN Procedure (a, 0, 10); Procedure (a, 0, LEN (a, 0)); END Test. negative: negative dynamic dimension of one-dimensional variable open array MODULE Test; VAR a: ARRAY 10 OF INTEGER; PROCEDURE Procedure (VAR p: ARRAY OF INTEGER; dim: INTEGER); VAR len: LONGINT; BEGIN len := LEN (p, dim); END Procedure; BEGIN Procedure (a, -1); END Test. negative: invalid dynamic dimension of one-dimensional variable open array MODULE Test; VAR a: ARRAY 10 OF INTEGER; PROCEDURE Procedure (VAR p: ARRAY OF INTEGER; dim: INTEGER); VAR len: LONGINT; BEGIN len := LEN (p, dim); END Procedure; BEGIN Procedure (a, 1); END Test. positive: length of two-dimensional variable open array MODULE Test; VAR a: ARRAY 10, 20 OF INTEGER; PROCEDURE Procedure (VAR p: ARRAY OF ARRAY OF INTEGER; len: INTEGER); BEGIN ASSERT (LEN (p) = len); END Procedure; BEGIN Procedure (a, 10); Procedure (a, LEN (a)); END Test. positive: first dimension of two-dimensional variable open array MODULE Test; VAR a: ARRAY 10, 20 OF INTEGER; PROCEDURE Procedure (VAR p: ARRAY OF ARRAY OF INTEGER; len: INTEGER); BEGIN ASSERT (LEN (p, 0) = len); END Procedure; BEGIN Procedure (a, 10); Procedure (a, LEN (a, 0)); END Test. positive: second dimension of two-dimensional variable open array MODULE Test; VAR a: ARRAY 10, 20 OF INTEGER; PROCEDURE Procedure (VAR p: ARRAY OF ARRAY OF INTEGER; len: INTEGER); BEGIN ASSERT (LEN (p, 1) = len); END Procedure; BEGIN Procedure (a, 20); Procedure (a, LEN (a, 1)); END Test. positive: dynamic dimension of two-dimensional variable open array MODULE Test; VAR a: ARRAY 10, 20 OF INTEGER; PROCEDURE Procedure (VAR p: ARRAY OF ARRAY OF INTEGER; dim, len: INTEGER); BEGIN ASSERT (LEN (p, dim) = len); END Procedure; BEGIN Procedure (a, 0, 10); Procedure (a, 0, LEN (a, 0)); Procedure (a, 1, 20); Procedure (a, 1, LEN (a, 1)); END Test. negative: negative dynamic dimension of two-dimensional variable open array MODULE Test; VAR a: ARRAY 10, 20 OF INTEGER; PROCEDURE Procedure (VAR p: ARRAY OF ARRAY OF INTEGER; dim: INTEGER); VAR len: LONGINT; BEGIN len := LEN (p, dim); END Procedure; BEGIN Procedure (a, -1); END Test. negative: invalid dynamic dimension of two-dimensional variable open array MODULE Test; VAR a: ARRAY 10, 20 OF INTEGER; PROCEDURE Procedure (VAR p: ARRAY OF ARRAY OF INTEGER; dim: INTEGER); VAR len: LONGINT; BEGIN len := LEN (p, dim); END Procedure; BEGIN Procedure (a, 2); END Test. positive: length of one-dimensional constant open array MODULE Test; VAR a: ARRAY 10 OF INTEGER; PROCEDURE Procedure (CONST p: ARRAY OF INTEGER; len: INTEGER); BEGIN ASSERT (LEN (p) = len); END Procedure; BEGIN Procedure (a, 10); Procedure (a, LEN (a)); END Test. positive: first dimension of one-dimensional constant open array MODULE Test; VAR a: ARRAY 10 OF INTEGER; PROCEDURE Procedure (CONST p: ARRAY OF INTEGER; len: INTEGER); BEGIN ASSERT (LEN (p, 0) = len); END Procedure; BEGIN Procedure (a, 10); Procedure (a, LEN (a, 0)); END Test. positive: dynamic dimension of one-dimensional constant open array MODULE Test; VAR a: ARRAY 10 OF INTEGER; PROCEDURE Procedure (CONST p: ARRAY OF INTEGER; dim, len: INTEGER); BEGIN ASSERT (LEN (p, dim) = len); END Procedure; BEGIN Procedure (a, 0, 10); Procedure (a, 0, LEN (a, 0)); END Test. negative: negative dynamic dimension of one-dimensional constant open array MODULE Test; VAR a: ARRAY 10 OF INTEGER; PROCEDURE Procedure (CONST p: ARRAY OF INTEGER; dim: INTEGER); VAR len: LONGINT; BEGIN len := LEN (p, dim); END Procedure; BEGIN Procedure (a, -1); END Test. negative: invalid dynamic dimension of one-dimensional constant open array MODULE Test; VAR a: ARRAY 10 OF INTEGER; PROCEDURE Procedure (CONST p: ARRAY OF INTEGER; dim: INTEGER); VAR len: LONGINT; BEGIN len := LEN (p, dim); END Procedure; BEGIN Procedure (a, 1); END Test. positive: length of two-dimensional constant open array MODULE Test; VAR a: ARRAY 10, 20 OF INTEGER; PROCEDURE Procedure (CONST p: ARRAY OF ARRAY OF INTEGER; len: INTEGER); BEGIN ASSERT (LEN (p) = len); END Procedure; BEGIN Procedure (a, 10); Procedure (a, LEN (a)); END Test. positive: first dimension of two-dimensional constant open array MODULE Test; VAR a: ARRAY 10, 20 OF INTEGER; PROCEDURE Procedure (CONST p: ARRAY OF ARRAY OF INTEGER; len: INTEGER); BEGIN ASSERT (LEN (p, 0) = len); END Procedure; BEGIN Procedure (a, 10); Procedure (a, LEN (a, 0)); END Test. positive: second dimension of two-dimensional constant open array MODULE Test; VAR a: ARRAY 10, 20 OF INTEGER; PROCEDURE Procedure (CONST p: ARRAY OF ARRAY OF INTEGER; len: INTEGER); BEGIN ASSERT (LEN (p, 1) = len); END Procedure; BEGIN Procedure (a, 20); Procedure (a, LEN (a, 1)); END Test. positive: dynamic dimension of two-dimensional constant open array MODULE Test; VAR a: ARRAY 10, 20 OF INTEGER; PROCEDURE Procedure (CONST p: ARRAY OF ARRAY OF INTEGER; dim, len: INTEGER); BEGIN ASSERT (LEN (p, dim) = len); END Procedure; BEGIN Procedure (a, 0, 10); Procedure (a, 0, LEN (a, 0)); Procedure (a, 1, 20); Procedure (a, 1, LEN (a, 1)); END Test. negative: negative dynamic dimension of two-dimensional constant open array MODULE Test; VAR a: ARRAY 10, 20 OF INTEGER; PROCEDURE Procedure (CONST p: ARRAY OF ARRAY OF INTEGER; dim: INTEGER); VAR len: LONGINT; BEGIN len := LEN (p, dim); END Procedure; BEGIN Procedure (a, -1); END Test. negative: invalid dynamic dimension of two-dimensional constant open array MODULE Test; VAR a: ARRAY 10, 20 OF INTEGER; PROCEDURE Procedure (CONST p: ARRAY OF ARRAY OF INTEGER; dim: INTEGER); VAR len: LONGINT; BEGIN len := LEN (p, dim); END Procedure; BEGIN Procedure (a, 2); END Test. positive: length of pointer to one-dimensional open array MODULE Test; VAR a: POINTER TO ARRAY OF INTEGER; PROCEDURE Procedure (CONST p: ARRAY OF INTEGER; len: LONGINT); BEGIN ASSERT (LEN (p) = len); END Procedure; BEGIN NEW (a, 10); ASSERT (LEN (a) = 10); Procedure (a^, 10); Procedure (a^, LEN (a)); END Test. positive: first dimension of pointer to one-dimensional open array MODULE Test; VAR a: POINTER TO ARRAY OF INTEGER; PROCEDURE Procedure (CONST p: ARRAY OF INTEGER; len: LONGINT); BEGIN ASSERT (LEN (p, 0) = len); END Procedure; BEGIN NEW (a, 10); ASSERT (LEN (a, 0) = 10); Procedure (a^, 10); Procedure (a^, LEN (a, 0)); END Test. positive: dynamic dimension of pointer to one-dimensional open array MODULE Test; VAR a: POINTER TO ARRAY OF INTEGER; PROCEDURE Procedure (CONST p: ARRAY OF INTEGER; dim, len: LONGINT); BEGIN ASSERT (LEN (p, dim) = len); END Procedure; BEGIN NEW (a, 10); Procedure (a^, 0, 10); Procedure (a^, 0, LEN (a, 0)); END Test. negative: negative dynamic dimension of pointer to one-dimensional open array MODULE Test; VAR a: POINTER TO ARRAY OF INTEGER; PROCEDURE Procedure (CONST p: ARRAY OF INTEGER; dim: INTEGER); VAR len: LONGINT; BEGIN len := LEN (p, dim); END Procedure; BEGIN NEW (a, 10); Procedure (a^, -1); END Test. negative: invalid dynamic dimension of pointer to one-dimensional open array MODULE Test; VAR a: POINTER TO ARRAY OF INTEGER; PROCEDURE Procedure (CONST p: ARRAY OF INTEGER; dim: INTEGER); VAR len: LONGINT; BEGIN len := LEN (p, dim); END Procedure; BEGIN NEW (a, 10); Procedure (a^, 1); END Test. positive: length of pointer to two-dimensional open array MODULE Test; VAR a: POINTER TO ARRAY OF ARRAY OF INTEGER; PROCEDURE Procedure (CONST p: ARRAY OF ARRAY OF INTEGER; len: LONGINT); BEGIN ASSERT (LEN (p) = len); END Procedure; BEGIN NEW (a, 10, 20); Procedure (a^, 10); Procedure (a^, LEN (a)); END Test. positive: first dimension of pointer to two-dimensional open array MODULE Test; VAR a: POINTER TO ARRAY OF ARRAY OF INTEGER; PROCEDURE Procedure (CONST p: ARRAY OF ARRAY OF INTEGER; len: LONGINT); BEGIN ASSERT (LEN (p, 0) = len); END Procedure; BEGIN NEW (a, 10, 20); Procedure (a^, 10); Procedure (a^, LEN (a, 0)); END Test. positive: second dimension of pointer to two-dimensional open array MODULE Test; VAR a: POINTER TO ARRAY OF ARRAY OF INTEGER; PROCEDURE Procedure (CONST p: ARRAY OF ARRAY OF INTEGER; len: LONGINT); BEGIN ASSERT (LEN (p, 1) = len); END Procedure; BEGIN NEW (a, 10, 20); Procedure (a^, 20); Procedure (a^, LEN (a, 1)); END Test. positive: dynamic dimension of pointer to two-dimensional open array MODULE Test; VAR a: POINTER TO ARRAY OF ARRAY OF INTEGER; PROCEDURE Procedure (CONST p: ARRAY OF ARRAY OF INTEGER; dim, len: LONGINT); BEGIN ASSERT (LEN (p, dim) = len); END Procedure; BEGIN NEW (a, 10, 20); Procedure (a^, 0, 10); Procedure (a^, 0, LEN (a, 0)); Procedure (a^, 1, 20); Procedure (a^, 1, LEN (a, 1)); END Test. negative: negative dynamic dimension of pointer to two-dimensional open array MODULE Test; VAR a: POINTER TO ARRAY OF ARRAY OF INTEGER; PROCEDURE Procedure (CONST p: ARRAY OF ARRAY OF INTEGER; dim: INTEGER); VAR len: LONGINT; BEGIN len := LEN (p, dim); END Procedure; BEGIN NEW (a, 10, 20); Procedure (a^, -1); END Test. negative: invalid dynamic dimension of pointer to two-dimensional open array MODULE Test; VAR a: POINTER TO ARRAY OF ARRAY OF INTEGER; PROCEDURE Procedure (CONST p: ARRAY OF ARRAY OF INTEGER; dim: INTEGER); VAR len: LONGINT; BEGIN len := LEN (p, dim); END Procedure; BEGIN NEW (a, 10, 20); Procedure (a^, 2); END Test. # indexing positive: indexing global array MODULE Test; VAR g: ARRAY 10 OF INTEGER; BEGIN g[0] := 1; g[1] := 2; g[2] := LEN (g); ASSERT (g[0] = 1); ASSERT (g[1] = 2); ASSERT (g[g[0]] = 2); ASSERT (g[g[g[0]]] = 10); END Test. negative: negative index into global array MODULE Test; VAR g: ARRAY 10 OF INTEGER; index: LONGINT; BEGIN index := -1; g[index] := 0; END Test. negative: too large index into global array MODULE Test; VAR g: ARRAY 10 OF INTEGER; index: LONGINT; BEGIN index := LEN (g); g[index] := 0; END Test. positive: reading global array MODULE Test; VAR g: ARRAY 10 OF INTEGER; PROCEDURE Set (VAR p: ARRAY OF INTEGER; index, value: INTEGER); BEGIN p[index] := value; END Set; BEGIN Set (g, 5, 15); ASSERT (g[5] = 15); END Test. positive: writing global array MODULE Test; VAR g: ARRAY 10 OF INTEGER; PROCEDURE Get (CONST p: ARRAY OF INTEGER; index: INTEGER): INTEGER; BEGIN RETURN p[index]; END Get; BEGIN g[5] := 15; ASSERT (Get (g, 5) = 15); END Test. positive: reading two-dimensional global array MODULE Test; VAR g: ARRAY 10, 20 OF INTEGER; PROCEDURE Set (VAR p: ARRAY OF ARRAY OF INTEGER; index1, index2, value: INTEGER); BEGIN p[index1, index2] := value; END Set; BEGIN Set (g, 5, 6, 15); ASSERT (g[5, 6] = 15); END Test. positive: writing two-dimensional global array MODULE Test; VAR g: ARRAY 10, 20 OF INTEGER; PROCEDURE Get (CONST p: ARRAY OF ARRAY OF INTEGER; index1, index2: INTEGER): INTEGER; BEGIN RETURN p[index1, index2]; END Get; BEGIN g[5, 6] := 15; ASSERT (Get (g, 5, 6) = 15); END Test. positive: indexing local array MODULE Test; PROCEDURE Procedure; VAR l: ARRAY 10 OF INTEGER; BEGIN l[0] := 1; l[1] := 2; l[2] := LEN (l); ASSERT (l[0] = 1); ASSERT (l[1] = 2); ASSERT (l[l[0]] = 2); ASSERT (l[l[l[0]]] = 10); END Procedure; BEGIN Procedure; END Test. negative: negative index into local array MODULE Test; PROCEDURE Procedure; VAR l: ARRAY 10 OF INTEGER; index: LONGINT; BEGIN index := -1; l[index] := 0; END Procedure; BEGIN Procedure; END Test. negative: too large index into local array MODULE Test; PROCEDURE Procedure; VAR l: ARRAY 10 OF INTEGER; index: LONGINT; BEGIN index := LEN (l); l[index] := 0; END Procedure; BEGIN Procedure; END Test. positive: reading local array MODULE Test; PROCEDURE Procedure; VAR l: ARRAY 10 OF INTEGER; BEGIN Set (l, 5, 15); ASSERT (l[5] = 15); END Procedure; PROCEDURE Set (VAR p: ARRAY OF INTEGER; index, value: INTEGER); BEGIN p[index] := value; END Set; BEGIN Procedure; END Test. positive: writing local array MODULE Test; PROCEDURE Procedure; VAR l: ARRAY 10 OF INTEGER; BEGIN l[5] := 15; ASSERT (Get (l, 5) = 15); END Procedure; PROCEDURE Get (CONST p: ARRAY OF INTEGER; index: INTEGER): INTEGER; BEGIN RETURN p[index]; END Get; BEGIN Procedure; END Test. positive: reading two-dimensional local array MODULE Test; PROCEDURE Procedure; VAR l: ARRAY 10, 20 OF INTEGER; BEGIN Set (l, 5, 6, 15); ASSERT (l[5, 6] = 15); END Procedure; PROCEDURE Set (VAR p: ARRAY OF ARRAY OF INTEGER; index1, index2, value: INTEGER); BEGIN p[index1, index2] := value; END Set; BEGIN Procedure; END Test. positive: writing two-dimensional local array MODULE Test; PROCEDURE Procedure; VAR l: ARRAY 10, 20 OF INTEGER; BEGIN l[5, 6] := 15; ASSERT (Get (l, 5, 6) = 15); END Procedure; PROCEDURE Get (CONST p: ARRAY OF ARRAY OF INTEGER; index1, index2: INTEGER): INTEGER; BEGIN RETURN p[index1, index2]; END Get; BEGIN Procedure; END Test. positive: indexing parameter array MODULE Test; VAR g: ARRAY 10 OF INTEGER; PROCEDURE Procedure (p: ARRAY 10 OF INTEGER); BEGIN p[1] := 2; p[2] := LEN (p); ASSERT (p[0] = 1); ASSERT (p[1] = 2); ASSERT (p[p[0]] = 2); ASSERT (p[p[p[0]]] = 10); END Procedure; BEGIN g[0] := 1; Procedure (g); END Test. negative: negative index into parameter array MODULE Test; VAR g: ARRAY 10 OF INTEGER; index: LONGINT; PROCEDURE Procedure (p: ARRAY 10 OF INTEGER); BEGIN index := -1; p[index] := 0; END Procedure; BEGIN Procedure (g); END Test. negative: too large index into parameter array MODULE Test; VAR g: ARRAY 10 OF INTEGER; index: LONGINT; PROCEDURE Procedure (p: ARRAY 10 OF INTEGER); BEGIN index := LEN (p); p[index] := 0; END Procedure; BEGIN Procedure (g); END Test. positive: reading parameter array MODULE Test; VAR g: ARRAY 10 OF INTEGER; PROCEDURE Procedure (p: ARRAY 10 OF INTEGER); BEGIN Set (p, 5, 15); ASSERT (p[5] = 15); END Procedure; PROCEDURE Set (VAR p: ARRAY OF INTEGER; index, value: INTEGER); BEGIN p[index] := value; END Set; BEGIN Procedure (g); END Test. positive: writing parameter array MODULE Test; VAR g: ARRAY 10 OF INTEGER; PROCEDURE Procedure (p: ARRAY 10 OF INTEGER); BEGIN p[5] := 15; ASSERT (Get (p, 5) = 15); END Procedure; PROCEDURE Get (CONST p: ARRAY OF INTEGER; index: INTEGER): INTEGER; BEGIN RETURN p[index]; END Get; BEGIN Procedure (g); END Test. positive: reading two-dimensional parameter array MODULE Test; VAR g: ARRAY 10, 20 OF INTEGER; PROCEDURE Procedure (p: ARRAY 10, 20 OF INTEGER); BEGIN Set (p, 5, 6, 15); ASSERT (p[5, 6] = 15); END Procedure; PROCEDURE Set (VAR p: ARRAY OF ARRAY OF INTEGER; index1, index2, value: INTEGER); BEGIN p[index1, index2] := value; END Set; BEGIN Procedure (g); END Test. positive: writing two-dimensional parameter array MODULE Test; VAR g: ARRAY 10, 20 OF INTEGER; PROCEDURE Procedure (p: ARRAY 10, 20 OF INTEGER); BEGIN p[5, 6] := 15; ASSERT (Get (p, 5, 6) = 15); END Procedure; PROCEDURE Get (CONST p: ARRAY OF ARRAY OF INTEGER; index1, index2: INTEGER): INTEGER; BEGIN RETURN p[index1, index2]; END Get; BEGIN Procedure (g); END Test. positive: indexing variable parameter array MODULE Test; VAR g: ARRAY 10 OF INTEGER; PROCEDURE Procedure (VAR p: ARRAY 10 OF INTEGER); BEGIN p[1] := 2; p[2] := LEN (p); ASSERT (p[0] = 1); ASSERT (p[1] = 2); ASSERT (p[p[0]] = 2); ASSERT (p[p[p[0]]] = 10); END Procedure; BEGIN g[0] := 1; Procedure (g); ASSERT (g[0] = 1); ASSERT (g[1] = 2); ASSERT (g[g[0]] = 2); ASSERT (g[g[g[0]]] = 10); END Test. negative: negative index into variable parameter array MODULE Test; VAR g: ARRAY 10 OF INTEGER; index: LONGINT; PROCEDURE Procedure (VAR p: ARRAY 10 OF INTEGER); BEGIN index := -1; p[index] := 0; END Procedure; BEGIN Procedure (g); END Test. negative: too large index into variable parameter array MODULE Test; VAR g: ARRAY 10 OF INTEGER; index: LONGINT; PROCEDURE Procedure (VAR p: ARRAY 10 OF INTEGER); BEGIN index := LEN (p); p[index] := 0; END Procedure; BEGIN Procedure (g); END Test. positive: reading variable parameter array MODULE Test; VAR g: ARRAY 10 OF INTEGER; PROCEDURE Procedure (VAR p: ARRAY 10 OF INTEGER); BEGIN Set (p, 5, 15); ASSERT (p[5] = 15); END Procedure; PROCEDURE Set (VAR p: ARRAY OF INTEGER; index, value: INTEGER); BEGIN p[index] := value; END Set; BEGIN Procedure (g); ASSERT (g[5] = 15); END Test. positive: writing variable parameter array MODULE Test; VAR g: ARRAY 10 OF INTEGER; PROCEDURE Procedure (VAR p: ARRAY 10 OF INTEGER); BEGIN p[5] := 15; ASSERT (Get (p, 5) = 15); END Procedure; PROCEDURE Get (CONST p: ARRAY OF INTEGER; index: INTEGER): INTEGER; BEGIN RETURN p[index]; END Get; BEGIN Procedure (g); ASSERT (Get (g, 5) = 15); ASSERT (g[5] = 15); END Test. positive: reading two-dimensional variable parameter array MODULE Test; VAR g: ARRAY 10, 20 OF INTEGER; PROCEDURE Procedure (VAR p: ARRAY 10, 20 OF INTEGER); BEGIN Set (p, 5, 6, 15); ASSERT (p[5, 6] = 15); END Procedure; PROCEDURE Set (VAR p: ARRAY OF ARRAY OF INTEGER; index1, index2, value: INTEGER); BEGIN p[index1, index2] := value; END Set; BEGIN Procedure (g); ASSERT (g[5, 6] = 15); END Test. positive: writing two-dimensional variable parameter array MODULE Test; VAR g: ARRAY 10, 20 OF INTEGER; PROCEDURE Procedure (VAR p: ARRAY 10, 20 OF INTEGER); BEGIN p[5, 6] := 15; ASSERT (Get (p, 5, 6) = 15); END Procedure; PROCEDURE Get (CONST p: ARRAY OF ARRAY OF INTEGER; index1, index2: INTEGER): INTEGER; BEGIN RETURN p[index1, index2]; END Get; BEGIN Procedure (g); ASSERT (Get (g, 5, 6) = 15); ASSERT (g[5, 6] = 15); END Test. positive: indexing constant parameter array MODULE Test; VAR g: ARRAY 10 OF INTEGER; PROCEDURE Procedure (CONST p: ARRAY 10 OF INTEGER); BEGIN ASSERT (p[0] = 1); ASSERT (p[1] = 2); ASSERT (p[p[0]] = 2); ASSERT (p[p[p[0]]] = 10); END Procedure; BEGIN g[0] := 1; g[1] := 2; g[2] := LEN (g); Procedure (g); END Test. negative: negative index into constant parameter array MODULE Test; VAR g: ARRAY 10 OF INTEGER; index: LONGINT; PROCEDURE Procedure (CONST p: ARRAY 10 OF INTEGER); BEGIN index := -1; index := p[index]; END Procedure; BEGIN Procedure (g); END Test. negative: too large index into constant parameter array MODULE Test; VAR g: ARRAY 10 OF INTEGER; index: LONGINT; PROCEDURE Procedure (CONST p: ARRAY 10 OF INTEGER); BEGIN index := LEN (p); index := p[index]; END Procedure; BEGIN Procedure (g); END Test. positive: indexing open array MODULE Test; VAR g: ARRAY 10 OF INTEGER; PROCEDURE Procedure (p: ARRAY OF INTEGER); BEGIN p[1] := 2; p[2] := SHORT (LEN (p)); ASSERT (p[0] = 1); ASSERT (p[1] = 2); ASSERT (p[p[0]] = 2); ASSERT (p[p[p[0]]] = 10); END Procedure; BEGIN g[0] := 1; Procedure (g); END Test. negative: negative index into open array MODULE Test; VAR g: ARRAY 10 OF INTEGER; index: LONGINT; PROCEDURE Procedure (p: ARRAY OF INTEGER); BEGIN index := -1; p[index] := 0; END Procedure; BEGIN Procedure (g); END Test. negative: too large index into open array MODULE Test; VAR g: ARRAY 10 OF INTEGER; index: LONGINT; PROCEDURE Procedure (p: ARRAY OF INTEGER); BEGIN index := LEN (p); p[index] := 0; END Procedure; BEGIN Procedure (g); END Test. positive: reading open array MODULE Test; VAR g: ARRAY 10 OF INTEGER; PROCEDURE Procedure (p: ARRAY OF INTEGER); BEGIN Set (p, 5, 15); ASSERT (p[5] = 15); END Procedure; PROCEDURE Set (VAR p: ARRAY OF INTEGER; index, value: INTEGER); BEGIN p[index] := value; END Set; BEGIN Procedure (g); END Test. positive: writing open array MODULE Test; VAR g: ARRAY 10 OF INTEGER; PROCEDURE Procedure (p: ARRAY OF INTEGER); BEGIN p[5] := 15; ASSERT (Get (p, 5) = 15); END Procedure; PROCEDURE Get (CONST p: ARRAY OF INTEGER; index: INTEGER): INTEGER; BEGIN RETURN p[index]; END Get; BEGIN Procedure (g); END Test. positive: reading two-dimensional open array MODULE Test; VAR g: ARRAY 10, 20 OF INTEGER; PROCEDURE Procedure (p: ARRAY OF ARRAY OF INTEGER); BEGIN Set (p, 5, 6, 15); ASSERT (p[5, 6] = 15); END Procedure; PROCEDURE Set (VAR p: ARRAY OF ARRAY OF INTEGER; index1, index2, value: INTEGER); BEGIN p[index1, index2] := value; END Set; BEGIN Procedure (g); END Test. positive: writing two-dimensional open array MODULE Test; VAR g: ARRAY 10, 20 OF INTEGER; PROCEDURE Procedure (p: ARRAY OF ARRAY OF INTEGER); BEGIN p[5, 6] := 15; ASSERT (Get (p, 5, 6) = 15); END Procedure; PROCEDURE Get (CONST p: ARRAY OF ARRAY OF INTEGER; index1, index2: INTEGER): INTEGER; BEGIN RETURN p[index1, index2]; END Get; BEGIN Procedure (g); END Test. positive: indexing variable open array MODULE Test; VAR g: ARRAY 10 OF INTEGER; PROCEDURE Procedure (VAR p: ARRAY OF INTEGER); BEGIN p[1] := 2; p[2] := SHORT (LEN (p)); ASSERT (p[0] = 1); ASSERT (p[1] = 2); ASSERT (p[p[0]] = 2); ASSERT (p[p[p[0]]] = 10); END Procedure; BEGIN g[0] := 1; Procedure (g); ASSERT (g[0] = 1); ASSERT (g[1] = 2); ASSERT (g[g[0]] = 2); ASSERT (g[g[g[0]]] = 10); END Test. negative: negative index into variable open array MODULE Test; VAR g: ARRAY 10 OF INTEGER; index: LONGINT; PROCEDURE Procedure (VAR p: ARRAY OF INTEGER); BEGIN index := -1; p[index] := 0; END Procedure; BEGIN Procedure (g); END Test. negative: too large index into variable open array MODULE Test; VAR g: ARRAY 10 OF INTEGER; index: LONGINT; PROCEDURE Procedure (VAR p: ARRAY OF INTEGER); BEGIN index := LEN (p); p[index] := 0; END Procedure; BEGIN Procedure (g); END Test. positive: reading variable open array MODULE Test; VAR g: ARRAY 10 OF INTEGER; PROCEDURE Procedure (VAR p: ARRAY OF INTEGER); BEGIN Set (p, 5, 15); ASSERT (p[5] = 15); END Procedure; PROCEDURE Set (VAR p: ARRAY OF INTEGER; index, value: INTEGER); BEGIN p[index] := value; END Set; BEGIN Procedure (g); ASSERT (g[5] = 15); END Test. positive: writing variable open array MODULE Test; VAR g: ARRAY 10 OF INTEGER; PROCEDURE Procedure (VAR p: ARRAY OF INTEGER); BEGIN p[5] := 15; ASSERT (Get (p, 5) = 15); END Procedure; PROCEDURE Get (CONST p: ARRAY OF INTEGER; index: INTEGER): INTEGER; BEGIN RETURN p[index]; END Get; BEGIN Procedure (g); ASSERT (Get (g, 5) = 15); ASSERT (g[5] = 15); END Test. positive: reading two-dimensional variable open array MODULE Test; VAR g: ARRAY 10, 20 OF INTEGER; PROCEDURE Procedure (VAR p: ARRAY OF ARRAY OF INTEGER); BEGIN Set (p, 5, 6, 15); ASSERT (p[5, 6] = 15); END Procedure; PROCEDURE Set (VAR p: ARRAY OF ARRAY OF INTEGER; index1, index2, value: INTEGER); BEGIN p[index1, index2] := value; END Set; BEGIN Procedure (g); ASSERT (g[5, 6] = 15); END Test. positive: writing two-dimensional variable open array MODULE Test; VAR g: ARRAY 10, 20 OF INTEGER; PROCEDURE Procedure (VAR p: ARRAY OF ARRAY OF INTEGER); BEGIN p[5, 6] := 15; ASSERT (Get (p, 5, 6) = 15); END Procedure; PROCEDURE Get (CONST p: ARRAY OF ARRAY OF INTEGER; index1, index2: INTEGER): INTEGER; BEGIN RETURN p[index1, index2]; END Get; BEGIN Procedure (g); ASSERT (Get (g, 5, 6) = 15); ASSERT (g[5, 6] = 15); END Test. positive: indexing constant open array MODULE Test; VAR g: ARRAY 10 OF INTEGER; PROCEDURE Procedure (CONST p: ARRAY OF INTEGER); BEGIN ASSERT (p[0] = 1); ASSERT (p[1] = 2); ASSERT (p[p[0]] = 2); ASSERT (p[p[p[0]]] = 10); END Procedure; BEGIN g[0] := 1; g[1] := 2; g[2] := LEN (g); Procedure (g); END Test. negative: negative index into constant open array MODULE Test; VAR g: ARRAY 10 OF INTEGER; index: LONGINT; PROCEDURE Procedure (p: ARRAY OF INTEGER); BEGIN index := -1; p[index] := 0; END Procedure; BEGIN Procedure (g); END Test. negative: too large index into constant open array MODULE Test; VAR g: ARRAY 10 OF INTEGER; index: LONGINT; PROCEDURE Procedure (p: ARRAY OF INTEGER); BEGIN index := LEN (p); p[index] := 0; END Procedure; BEGIN Procedure (g); END Test. positive: indexing pointer to array MODULE Test; VAR g: POINTER TO ARRAY 10 OF INTEGER; BEGIN NEW (g); g[0] := 1; g[1] := 2; g[2] := LEN (g^); ASSERT (g[0] = 1); ASSERT (g[1] = 2); ASSERT (g[g[0]] = 2); ASSERT (g[g[g[0]]] = 10); END Test. negative: negative index into pointer to array MODULE Test; VAR g: POINTER TO ARRAY 10 OF INTEGER; index: LONGINT; BEGIN NEW (g); index := -1; g[index] := 0; END Test. negative: too large index into pointer to array MODULE Test; VAR g: POINTER TO ARRAY 10 OF INTEGER; index: LONGINT; BEGIN NEW (g); index := LEN (g^); g[index] := 0; END Test. positive: reading pointer to array MODULE Test; VAR g: POINTER TO ARRAY 10 OF INTEGER; PROCEDURE Set (VAR p: ARRAY OF INTEGER; index, value: INTEGER); BEGIN p[index] := value; END Set; BEGIN NEW (g); Set (g^, 5, 15); ASSERT (g[5] = 15); END Test. positive: writing pointer to array MODULE Test; VAR g: POINTER TO ARRAY 10 OF INTEGER; PROCEDURE Get (CONST p: ARRAY OF INTEGER; index: INTEGER): INTEGER; BEGIN RETURN p[index]; END Get; BEGIN NEW (g); g[5] := 15; ASSERT (Get (g^, 5) = 15); END Test. positive: reading two-dimensional pointer to array MODULE Test; VAR g: POINTER TO ARRAY 10, 20 OF INTEGER; PROCEDURE Set (VAR p: ARRAY OF ARRAY OF INTEGER; index1, index2, value: INTEGER); BEGIN p[index1, index2] := value; END Set; BEGIN NEW (g); Set (g^, 5, 6, 15); ASSERT (g[5, 6] = 15); END Test. positive: writing two-dimensional pointer to array MODULE Test; VAR g: POINTER TO ARRAY 10, 20 OF INTEGER; PROCEDURE Get (CONST p: ARRAY OF ARRAY OF INTEGER; index1, index2: INTEGER): INTEGER; BEGIN RETURN p[index1, index2]; END Get; BEGIN NEW (g); g[5, 6] := 15; ASSERT (Get (g^, 5, 6) = 15); END Test. positive: indexing pointer to open array MODULE Test; VAR g: POINTER TO ARRAY OF INTEGER; BEGIN NEW (g, 10); g[0] := 1; g[1] := 2; g[2] := SHORT (LEN (g^)); ASSERT (g[0] = 1); ASSERT (g[1] = 2); ASSERT (g[g[0]] = 2); ASSERT (g[g[g[0]]] = 10); END Test. negative: negative index into pointer to open array MODULE Test; VAR g: POINTER TO ARRAY OF INTEGER; index: LONGINT; BEGIN NEW (g, 10); index := -1; g[index] := 0; END Test. negative: too large index into pointer to open array MODULE Test; VAR g: POINTER TO ARRAY OF INTEGER; index: LONGINT; BEGIN NEW (g, 10); index := LEN (g^); g[index] := 0; END Test. positive: reading pointer to open array MODULE Test; VAR g: POINTER TO ARRAY OF INTEGER; PROCEDURE Set (VAR p: ARRAY OF INTEGER; index, value: INTEGER); BEGIN p[index] := value; END Set; BEGIN NEW (g, 10); Set (g^, 5, 15); ASSERT (g[5] = 15); END Test. positive: writing pointer to open array MODULE Test; VAR g: POINTER TO ARRAY OF INTEGER; PROCEDURE Get (CONST p: ARRAY OF INTEGER; index: INTEGER): INTEGER; BEGIN RETURN p[index]; END Get; BEGIN NEW (g, 10); g[5] := 15; ASSERT (Get (g^, 5) = 15); END Test. positive: reading two-dimensional pointer to open array MODULE Test; VAR g: POINTER TO ARRAY OF ARRAY OF INTEGER; PROCEDURE Set (VAR p: ARRAY OF ARRAY OF INTEGER; index1, index2, value: INTEGER); BEGIN p[index1, index2] := value; END Set; BEGIN NEW (g, 10, 20); Set (g^, 5, 6, 15); ASSERT (g[5, 6] = 15); END Test. positive: writing two-dimensional pointer to open array MODULE Test; VAR g: POINTER TO ARRAY OF ARRAY OF INTEGER; PROCEDURE Get (CONST p: ARRAY OF ARRAY OF INTEGER; index1, index2: INTEGER): INTEGER; BEGIN RETURN p[index1, index2]; END Get; BEGIN NEW (g, 10, 20); g[5, 6] := 15; ASSERT (Get (g^, 5, 6) = 15); END Test. # modifying parameters positive: modifying boolean parameter MODULE Test; VAR g: BOOLEAN; PROCEDURE Procedure (p: BOOLEAN); BEGIN ASSERT (p); p := FALSE; ASSERT (~p); ASSERT (g); END Procedure; BEGIN g := TRUE; Procedure (g); ASSERT (g); END Test. positive: modifying character parameter MODULE Test; VAR g: CHAR; PROCEDURE Procedure (p: CHAR); BEGIN ASSERT (p = 'c'); p := 'Z'; ASSERT (p = 'Z'); ASSERT (g = 'c'); END Procedure; BEGIN g := 'c'; Procedure (g); ASSERT (g = 'c'); END Test. positive: modifying integer parameter MODULE Test; VAR g: INTEGER; PROCEDURE Procedure (p: INTEGER); BEGIN ASSERT (p = 2); INC (p); ASSERT (p = 3); ASSERT (g = 2); END Procedure; BEGIN g := 2; Procedure (g); ASSERT (g = 2); END Test. positive: modifying real parameter MODULE Test; VAR g: REAL; PROCEDURE Procedure (p: REAL); BEGIN ASSERT (p = 2.5); p := p * 2; ASSERT (p = 5); ASSERT (g = 2.5); END Procedure; BEGIN g := 2.5; Procedure (g); ASSERT (g = 2.5); END Test. positive: modifying set parameter MODULE Test; VAR g: SET; PROCEDURE Procedure (p: SET); BEGIN ASSERT (p = {3}); INCL (p, 2); INCL (p, 4); ASSERT (p = {2 .. 4}); ASSERT (g = {3}); END Procedure; BEGIN g := {3}; Procedure (g); ASSERT (g = {3}); END Test. positive: modifying array parameter MODULE Test; VAR g: ARRAY 10 OF INTEGER; PROCEDURE Procedure (p: ARRAY 10 OF INTEGER); BEGIN ASSERT (p[1] = 23); ASSERT (p[8] = 91); p[8] := 19; p[1] := 32; ASSERT (p[1] = 32); ASSERT (p[8] = 19); ASSERT (g[1] = 23); ASSERT (g[8] = 91); END Procedure; BEGIN g[1] := 23; g[8] := 91; Procedure (g); ASSERT (g[1] = 23); ASSERT (g[8] = 91); END Test. positive: modifying open array parameter MODULE Test; VAR g: ARRAY 10 OF INTEGER; PROCEDURE Procedure (p: ARRAY OF INTEGER); BEGIN ASSERT (p[1] = 23); ASSERT (p[8] = 91); p[8] := 19; p[1] := 32; ASSERT (p[1] = 32); ASSERT (p[8] = 19); ASSERT (g[1] = 23); ASSERT (g[8] = 91); END Procedure; BEGIN g[1] := 23; g[8] := 91; Procedure (g); ASSERT (g[1] = 23); ASSERT (g[8] = 91); END Test. positive: modifying character array parameter MODULE Test; VAR g: ARRAY 10 OF CHAR; PROCEDURE Procedure (p: ARRAY 10 OF CHAR); BEGIN ASSERT (p = "value"); p := "modified"; ASSERT (p = "modified"); ASSERT (g = "value"); END Procedure; BEGIN g := "value"; Procedure (g); ASSERT (g = "value"); END Test. positive: modifying open character array parameter MODULE Test; VAR g: ARRAY 10 OF CHAR; PROCEDURE Procedure (p: ARRAY OF CHAR); BEGIN ASSERT (p = "value"); p := "modified"; ASSERT (p = "modified"); ASSERT (g = "value"); END Procedure; BEGIN g := "value"; Procedure (g); ASSERT (g = "value"); END Test. positive: modifying record parameter MODULE Test; TYPE Record = RECORD x: INTEGER END; VAR g: Record; PROCEDURE Procedure (p: Record); BEGIN ASSERT (p.x = 15); p.x := p.x * 3; ASSERT (p.x = 45); ASSERT (g.x = 15); END Procedure; BEGIN g.x := 15; Procedure (g); ASSERT (g.x = 15); END Test. positive: modifying object parameter MODULE Test; TYPE Object = OBJECT VAR x: INTEGER END Object; VAR g: Object; PROCEDURE Procedure (p: Object); BEGIN ASSERT (p.x = 20); p.x := 10; ASSERT (p.x = 10); ASSERT (g.x = 10); END Procedure; BEGIN NEW (g); g.x := 20; Procedure (g); ASSERT (g.x = 10); END Test. positive: modifying object reference parameter MODULE Test; TYPE Object = OBJECT END Object; VAR g: Object; PROCEDURE Procedure (p: Object); BEGIN ASSERT (p # NIL); p := NIL; ASSERT (p = NIL); ASSERT (g # NIL); END Procedure; BEGIN NEW (g); Procedure (g); ASSERT (g # NIL); END Test. positive: modifying pointer to array parameter MODULE Test; VAR g: POINTER TO ARRAY 10 OF INTEGER; PROCEDURE Procedure (p: POINTER TO ARRAY 10 OF INTEGER); BEGIN ASSERT (p[1] = 23); ASSERT (p[8] = 91); p[8] := 19; p[1] := 32; ASSERT (p[1] = 32); ASSERT (p[8] = 19); ASSERT (g[1] = 32); ASSERT (g[8] = 19); END Procedure; BEGIN NEW (g); g[1] := 23; g[8] := 91; Procedure (g); ASSERT (g[1] = 32); ASSERT (g[8] = 19); END Test. positive: modifying pointer to open array parameter MODULE Test; VAR g: POINTER TO ARRAY OF INTEGER; PROCEDURE Procedure (p: POINTER TO ARRAY OF INTEGER); BEGIN ASSERT (p[1] = 23); ASSERT (p[8] = 91); p[8] := 19; p[1] := 32; ASSERT (p[1] = 32); ASSERT (p[8] = 19); ASSERT (g[1] = 32); ASSERT (g[8] = 19); END Procedure; BEGIN NEW (g, 10); g[1] := 23; g[8] := 91; Procedure (g); ASSERT (g[1] = 32); ASSERT (g[8] = 19); END Test. positive: modifying pointer to character array parameter MODULE Test; VAR g: POINTER TO ARRAY 10 OF CHAR; PROCEDURE Procedure (p: POINTER TO ARRAY 10 OF CHAR); BEGIN ASSERT (p^ = "value"); p^ := "modified"; ASSERT (p^ = "modified"); ASSERT (g^ = "modified"); END Procedure; BEGIN NEW (g); g^ := "value"; Procedure (g); ASSERT (g^ = "modified"); END Test. positive: modifying pointer to open character array parameter MODULE Test; VAR g: POINTER TO ARRAY OF CHAR; PROCEDURE Procedure (p: POINTER TO ARRAY OF CHAR); BEGIN ASSERT (p^ = "value"); p^ := "modified"; ASSERT (p^ = "modified"); ASSERT (g^ = "modified"); END Procedure; BEGIN NEW (g, 10); g^ := "value"; Procedure (g); ASSERT (g^ = "modified"); END Test. positive: modifying pointer to array reference parameter MODULE Test; VAR g: POINTER TO ARRAY 10 OF INTEGER; PROCEDURE Procedure (p: POINTER TO ARRAY 10 OF INTEGER); BEGIN ASSERT (p # NIL); p := NIL; ASSERT (p = NIL); ASSERT (g # NIL); END Procedure; BEGIN NEW (g); Procedure (g); ASSERT (g # NIL); END Test. positive: modifying pointer to record parameter MODULE Test; TYPE Record = RECORD x: INTEGER END; VAR g: POINTER TO Record; PROCEDURE Procedure (p: POINTER TO Record); BEGIN ASSERT (p.x = 15); p.x := p.x * 3; ASSERT (p.x = 45); ASSERT (g.x = 45); END Procedure; BEGIN NEW (g); g.x := 15; Procedure (g); ASSERT (g.x = 45); END Test. positive: modifying pointer to record reference parameter MODULE Test; TYPE Record = RECORD END; VAR g: POINTER TO Record; PROCEDURE Procedure (p: POINTER TO Record); BEGIN ASSERT (p # NIL); p := NIL; ASSERT (p = NIL); ASSERT (g # NIL); END Procedure; BEGIN NEW (g); Procedure (g); ASSERT (g # NIL); END Test. positive: modifying procedure parameter MODULE Test; TYPE P = PROCEDURE (p: P); VAR g: P; PROCEDURE Procedure (p: P); BEGIN ASSERT (p # NIL); p := NIL; ASSERT (p = NIL); ASSERT (g # NIL); END Procedure; BEGIN g := Procedure; Procedure (g); ASSERT (g # NIL); END Test. positive: modifying variable boolean parameter MODULE Test; VAR g: BOOLEAN; PROCEDURE Procedure (VAR p: BOOLEAN); BEGIN ASSERT (p); p := FALSE; ASSERT (~p); ASSERT (~g); END Procedure; BEGIN g := TRUE; Procedure (g); ASSERT (~g); END Test. positive: modifying variable character parameter MODULE Test; VAR g: CHAR; PROCEDURE Procedure (VAR p: CHAR); BEGIN ASSERT (p = 'c'); p := 'Z'; ASSERT (p = 'Z'); ASSERT (g = 'Z'); END Procedure; BEGIN g := 'c'; Procedure (g); ASSERT (g = 'Z'); END Test. positive: modifying variable integer parameter MODULE Test; VAR g: INTEGER; PROCEDURE Procedure (VAR p: INTEGER); BEGIN ASSERT (p = 2); INC (p); ASSERT (p = 3); ASSERT (g = 3); END Procedure; BEGIN g := 2; Procedure (g); ASSERT (g = 3); END Test. positive: modifying variable real parameter MODULE Test; VAR g: REAL; PROCEDURE Procedure (VAR p: REAL); BEGIN ASSERT (p = 2.5); p := p * 2; ASSERT (p = 5); ASSERT (g = 5); END Procedure; BEGIN g := 2.5; Procedure (g); ASSERT (g = 5); END Test. positive: modifying variable set parameter MODULE Test; VAR g: SET; PROCEDURE Procedure (VAR p: SET); BEGIN ASSERT (p = {3}); INCL (p, 2); INCL (p, 4); ASSERT (p = {2 .. 4}); ASSERT (g = {2 .. 4}); END Procedure; BEGIN g := {3}; Procedure (g); ASSERT (g = {2 .. 4}); END Test. positive: modifying variable array parameter MODULE Test; VAR g: ARRAY 10 OF INTEGER; PROCEDURE Procedure (VAR p: ARRAY 10 OF INTEGER); BEGIN ASSERT (p[1] = 23); ASSERT (p[8] = 91); p[8] := 19; p[1] := 32; ASSERT (p[1] = 32); ASSERT (p[8] = 19); ASSERT (g[1] = 32); ASSERT (g[8] = 19); END Procedure; BEGIN g[1] := 23; g[8] := 91; Procedure (g); ASSERT (g[1] = 32); ASSERT (g[8] = 19); END Test. positive: modifying variable open array parameter MODULE Test; VAR g: ARRAY 10 OF INTEGER; PROCEDURE Procedure (VAR p: ARRAY OF INTEGER); BEGIN ASSERT (p[1] = 23); ASSERT (p[8] = 91); p[8] := 19; p[1] := 32; ASSERT (p[1] = 32); ASSERT (p[8] = 19); ASSERT (g[1] = 32); ASSERT (g[8] = 19); END Procedure; BEGIN g[1] := 23; g[8] := 91; Procedure (g); ASSERT (g[1] = 32); ASSERT (g[8] = 19); END Test. positive: modifying variable character array parameter MODULE Test; VAR g: ARRAY 10 OF CHAR; PROCEDURE Procedure (VAR p: ARRAY 10 OF CHAR); BEGIN ASSERT (p = "value"); p := "modified"; ASSERT (p = "modified"); ASSERT (g = "modified"); END Procedure; BEGIN g := "value"; Procedure (g); ASSERT (g = "modified"); END Test. positive: modifying variable open character array parameter MODULE Test; VAR g: ARRAY 10 OF CHAR; PROCEDURE Procedure (VAR p: ARRAY OF CHAR); BEGIN ASSERT (p = "value"); p := "modified"; ASSERT (p = "modified"); ASSERT (g = "modified"); END Procedure; BEGIN g := "value"; Procedure (g); ASSERT (g = "modified"); END Test. positive: modifying variable record parameter MODULE Test; TYPE Record = RECORD x: INTEGER END; VAR g: Record; PROCEDURE Procedure (VAR p: Record); BEGIN ASSERT (p.x = 15); p.x := p.x * 3; ASSERT (p.x = 45); ASSERT (g.x = 45); END Procedure; BEGIN g.x := 15; Procedure (g); ASSERT (g.x = 45); END Test. positive: modifying variable object parameter MODULE Test; TYPE Object = OBJECT VAR x: INTEGER END Object; VAR g: Object; PROCEDURE Procedure (VAR p: Object); BEGIN ASSERT (p.x = 20); p.x := 10; ASSERT (p.x = 10); ASSERT (g.x = 10); END Procedure; BEGIN NEW (g); g.x := 20; Procedure (g); ASSERT (g.x = 10); END Test. positive: modifying variable object reference parameter MODULE Test; TYPE Object = OBJECT END Object; VAR g: Object; PROCEDURE Procedure (VAR p: Object); BEGIN ASSERT (p # NIL); p := NIL; ASSERT (p = NIL); ASSERT (g = NIL); END Procedure; BEGIN NEW (g); Procedure (g); ASSERT (g = NIL); END Test. positive: modifying variable pointer to array parameter MODULE Test; VAR g: POINTER TO ARRAY 10 OF INTEGER; PROCEDURE Procedure (VAR p: POINTER TO ARRAY 10 OF INTEGER); BEGIN ASSERT (p[1] = 23); ASSERT (p[8] = 91); p[8] := 19; p[1] := 32; ASSERT (p[1] = 32); ASSERT (p[8] = 19); ASSERT (g[1] = 32); ASSERT (g[8] = 19); END Procedure; BEGIN NEW (g); g[1] := 23; g[8] := 91; Procedure (g); ASSERT (g[1] = 32); ASSERT (g[8] = 19); END Test. positive: modifying variable pointer to open array parameter MODULE Test; VAR g: POINTER TO ARRAY OF INTEGER; PROCEDURE Procedure (VAR p: POINTER TO ARRAY OF INTEGER); BEGIN ASSERT (p[1] = 23); ASSERT (p[8] = 91); p[8] := 19; p[1] := 32; ASSERT (p[1] = 32); ASSERT (p[8] = 19); ASSERT (g[1] = 32); ASSERT (g[8] = 19); END Procedure; BEGIN NEW (g, 10); g[1] := 23; g[8] := 91; Procedure (g); ASSERT (g[1] = 32); ASSERT (g[8] = 19); END Test. positive: modifying variable pointer to character array parameter MODULE Test; VAR g: POINTER TO ARRAY 10 OF CHAR; PROCEDURE Procedure (VAR p: POINTER TO ARRAY 10 OF CHAR); BEGIN ASSERT (p^ = "value"); p^ := "modified"; ASSERT (p^ = "modified"); ASSERT (g^ = "modified"); END Procedure; BEGIN NEW (g); g^ := "value"; Procedure (g); ASSERT (g^ = "modified"); END Test. positive: modifying variable pointer to open character array parameter MODULE Test; VAR g: POINTER TO ARRAY OF CHAR; PROCEDURE Procedure (VAR p: POINTER TO ARRAY OF CHAR); BEGIN ASSERT (p^ = "value"); p^ := "modified"; ASSERT (p^ = "modified"); ASSERT (g^ = "modified"); END Procedure; BEGIN NEW (g, 10); g^ := "value"; Procedure (g); ASSERT (g^ = "modified"); END Test. positive: modifying variable pointer to array reference parameter MODULE Test; VAR g: POINTER TO ARRAY 10 OF INTEGER; PROCEDURE Procedure (VAR p: POINTER TO ARRAY 10 OF INTEGER); BEGIN ASSERT (p # NIL); p := NIL; ASSERT (p = NIL); ASSERT (g = NIL); END Procedure; BEGIN NEW (g); Procedure (g); ASSERT (g = NIL); END Test. positive: modifying variable pointer to record parameter MODULE Test; TYPE Record = RECORD x: INTEGER END; VAR g: POINTER TO Record; PROCEDURE Procedure (VAR p: POINTER TO Record); BEGIN ASSERT (p.x = 15); p.x := p.x * 3; ASSERT (p.x = 45); ASSERT (g.x = 45); END Procedure; BEGIN NEW (g); g.x := 15; Procedure (g); ASSERT (g.x = 45); END Test. positive: modifying variable pointer to record reference parameter MODULE Test; TYPE Record = RECORD END; VAR g: POINTER TO Record; PROCEDURE Procedure (VAR p: POINTER TO Record); BEGIN ASSERT (p # NIL); p := NIL; ASSERT (p = NIL); ASSERT (g = NIL); END Procedure; BEGIN NEW (g); Procedure (g); ASSERT (g = NIL); END Test. positive: modifying variable procedure parameter MODULE Test; TYPE P = PROCEDURE (VAR p: P); VAR g: P; PROCEDURE Procedure (VAR p: P); BEGIN ASSERT (p # NIL); p := NIL; ASSERT (p = NIL); ASSERT (g = NIL); END Procedure; BEGIN g := Procedure; Procedure (g); ASSERT (g = NIL); END Test. # if statement positive: if statement with satisfied condition MODULE Test; VAR i: INTEGER; BEGIN i := 0; IF i = 0 THEN ELSIF i = 1 THEN HALT (1234) ELSIF i = 2 THEN HALT (1234) ELSE HALT (1234) END; IF i = 0 THEN RETURN ELSIF i = 1 THEN ELSIF i = 2 THEN ELSE END; HALT (1234); END Test. positive: if statement with unsatisfied condition MODULE Test; VAR i: INTEGER; BEGIN i := 2; IF i = 0 THEN HALT (1234) ELSIF i = 1 THEN HALT (1234) ELSIF i = 2 THEN ELSE HALT (1234) END; IF i = 0 THEN ELSIF i = 1 THEN ELSIF i = 2 THEN RETURN ELSE END; HALT (1234); END Test. positive: else if statement with unsatisfied condition MODULE Test; VAR i: INTEGER; BEGIN i := 4; IF i = 0 THEN HALT (1234) ELSIF i = 1 THEN HALT (1234) ELSIF i = 2 THEN HALT (1234) ELSE END; IF i = 0 THEN ELSIF i = 1 THEN ELSIF i = 2 THEN ELSE RETURN END; HALT (1234); END Test. # exit statement positive: unconditional exit statement MODULE Test; BEGIN LOOP EXIT; HALT (1234) END; END Test. positive: nested unconditional exit statement MODULE Test; BEGIN LOOP LOOP EXIT; HALT (1234) END; EXIT; HALT (1234) END; END Test. positive: conditional exit statement MODULE Test; VAR i: INTEGER; BEGIN i := 0; LOOP IF i = 0 THEN EXIT END; HALT (1234) END; END Test. positive: nested conditional exit statement MODULE Test; VAR i: INTEGER; BEGIN i := 0; LOOP LOOP IF i = 0 THEN EXIT END; HALT (1234) END; EXIT; HALT (1234) END; END Test. # case statement positive: case statement with character value MODULE Test; PROCEDURE Case (c: CHAR): INTEGER; BEGIN CASE c OF | 'a', 't', 'j': RETURN 0 | 'l'..'o': RETURN 1 | 'r', 'b', 10X: RETURN 2 ELSE RETURN 3; END; HALT (1234); END Case; BEGIN ASSERT (Case ('a') = 0); ASSERT (Case ('b') = 2); ASSERT (Case ('c') = 3); ASSERT (Case ('j') = 0); ASSERT (Case ('n') = 1); ASSERT (Case ('o') = 1); ASSERT (Case ('r') = 2); ASSERT (Case ('t') = 0); ASSERT (Case ('z') = 3); ASSERT (Case (10X) = 2); END Test. negative: case statement with too low character value MODULE Test; VAR c: CHAR; BEGIN c := 'a'; CASE c OF | 'b'..'g': | 's', 'r': | 'u', 'v': END; END Test. negative: case statement with too high character value MODULE Test; VAR c: CHAR; BEGIN c := 'w'; CASE c OF | 'b'..'g': | 's', 'r': | 'u', 'v': END; END Test. negative: case statement with unmatched character value MODULE Test; VAR c: CHAR; BEGIN c := 't'; CASE c OF | 'b'..'g': | 's', 'r': | 'u', 'v': END; END Test. positive: case statement with integer value MODULE Test; PROCEDURE Case (i: INTEGER): INTEGER; BEGIN CASE i OF | 1, 3, 9: RETURN 0 | 4..6: RETURN 1 | 8, 2: RETURN 2 ELSE RETURN 3; END; HALT (1234); END Case; BEGIN ASSERT (Case (0) = 3); ASSERT (Case (1) = 0); ASSERT (Case (2) = 2); ASSERT (Case (3) = 0); ASSERT (Case (4) = 1); ASSERT (Case (5) = 1); ASSERT (Case (6) = 1); ASSERT (Case (7) = 3); ASSERT (Case (8) = 2); ASSERT (Case (9) = 0); END Test. negative: case statement with too low integer value MODULE Test; VAR i: INTEGER; BEGIN i := 0; CASE i OF | 1, 3, 9: | 4..6: | 8, 2: END; END Test. negative: case statement with too high integer value MODULE Test; VAR i: INTEGER; BEGIN i := 10; CASE i OF | 1, 3, 9: | 4..6: | 8, 2: END; END Test. negative: case statement with unmatched integer value MODULE Test; VAR i: INTEGER; BEGIN i := 7; CASE i OF | 1, 3, 9: | 4..6: | 8, 2: END; END Test. # for statement positive: for statement with positive step sizes MODULE Test; VAR i, steps: INTEGER; BEGIN steps := 0; FOR i := 0 TO 10 DO INC (steps) END; ASSERT (steps = 11); steps := 0; FOR i := 0 TO 10 BY 1 DO INC (steps) END; ASSERT (steps = 11); steps := 0; FOR i := 0 TO 10 BY 2 DO INC (steps) END; ASSERT (steps = 6); steps := 0; FOR i := 0 TO 10 BY 3 DO INC (steps) END; ASSERT (steps = 4); steps := 0; FOR i := 0 TO 10 BY 4 DO INC (steps) END; ASSERT (steps = 3); END Test. positive: for statement with negative step sizes MODULE Test; VAR i, steps: INTEGER; BEGIN steps := 0; FOR i := 10 TO 0 DO INC (steps) END; ASSERT (steps = 0); steps := 0; FOR i := 10 TO 0 BY -1 DO INC (steps) END; ASSERT (steps = 11); steps := 0; FOR i := 10 TO 0 BY -2 DO INC (steps) END; ASSERT (steps = 6); steps := 0; FOR i := 10 TO 0 BY -3 DO INC (steps) END; ASSERT (steps = 4); steps := 0; FOR i := 10 TO 0 BY -4 DO INC (steps) END; ASSERT (steps = 3); END Test. positive: modifying start counter in for statement MODULE Test; VAR i, steps, start: INTEGER; BEGIN steps := 0; start := 0; FOR i := start TO 10 DO start := i; INC (steps) END; ASSERT (steps = 11); END Test. positive: modifying end counter in for statement MODULE Test; VAR i, steps, end: INTEGER; BEGIN steps := 0; end := 10; FOR i := 0 TO end DO end := i; INC (steps) END; ASSERT (steps = 11); END Test. positive: using counter as end counter for statement MODULE Test; VAR i, steps: INTEGER; BEGIN steps := 0; i := 10; FOR i := 0 TO i DO INC (steps) END; ASSERT (steps = 1); END Test. # new statement positive: new statement on pointer to record MODULE Test; VAR p: POINTER TO RECORD a, b: INTEGER END; BEGIN NEW (p); p.a := 3; p.b := p.a; ASSERT (p.b = 3); END Test. positive: new statement on pointer to too large record MODULE Test; VAR p: POINTER TO RECORD data*: ARRAY MAX (LONGINT) DIV 16 - 1000 OF INTEGER END; BEGIN (*! NEW (p); ASSERT (p = NIL); *) END Test. positive: new statement on pointer to array MODULE Test; VAR p: POINTER TO ARRAY 10 OF INTEGER; BEGIN NEW (p); p[2] := 3; p[1] := p[2]; ASSERT (p[2] = 3); END Test. positive: new statement on pointer to too large array MODULE Test; VAR r: POINTER TO ARRAY MAX (LONGINT) DIV 16 - 1000 OF INTEGER; BEGIN (*! NEW (r); ASSERT (r = NIL); *) END Test. positive: new statement on pointer to open array MODULE Test; VAR p: POINTER TO ARRAY OF INTEGER; BEGIN NEW (p, 10); p[2] := 3; p[1] := p[2]; ASSERT (p[2] = 3); END Test. negative: new statement on pointer to open array with negative size MODULE Test; VAR p: POINTER TO ARRAY OF INTEGER; size: INTEGER; BEGIN size := -10; NEW (p, size); END Test. positive: new statement on pointer to too large open array MODULE Test; VAR r: POINTER TO ARRAY OF INTEGER; BEGIN (*! NEW (r, MAX (LONGINT) DIV 2 - 1000); ASSERT (r = NIL); *) END Test. positive: new statement on object MODULE Test; VAR o: OBJECT VAR a, b: INTEGER END; BEGIN NEW (o); o.a := 3; o.b := o.a; ASSERT (o.b = 3); END Test. positive: new statement on too large object MODULE Test; VAR o: OBJECT VAR data*: ARRAY MAX (LONGINT) DIV 16 - 1000 OF INTEGER END; BEGIN (*! NEW (o); ASSERT (o = NIL); *) END Test. positive: new statement modifying designator after object body MODULE Test; VAR o: OBJECT PROCEDURE &Init; BEGIN ASSERT (o = NIL); END Init; BEGIN ASSERT (o # NIL); END; BEGIN o := NIL; NEW (o); ASSERT (o # NIL); END Test. # with statement positive: with statement with same global record MODULE Test; TYPE R = RECORD b: BOOLEAN END; VAR r: R; BEGIN r.b := TRUE; WITH r : R DO ASSERT (r.b) END; END Test. positive: with statement with same local record MODULE Test; PROCEDURE Procedure; TYPE R = RECORD b: BOOLEAN END; VAR r: R; BEGIN r.b := TRUE; WITH r : R DO ASSERT (r.b) END; END Procedure; BEGIN Procedure; END Test. positive: with statement with same parameter record MODULE Test; TYPE R = RECORD b: BOOLEAN END; VAR r: R; PROCEDURE Procedure (r: R); BEGIN WITH r : R DO ASSERT (r.b); END; END Procedure; BEGIN r.b := TRUE; Procedure (r); END Test. positive: with statement with same variable parameter record MODULE Test; TYPE R = RECORD b: BOOLEAN END; VAR r: R; PROCEDURE Procedure (VAR r: R); BEGIN WITH r : R DO ASSERT (r.b); END; END Procedure; BEGIN r.b := TRUE; Procedure (r); END Test. positive: with statement with same constant parameter record MODULE Test; TYPE R = RECORD b: BOOLEAN END; VAR r: R; PROCEDURE Procedure (CONST r: R); BEGIN WITH r : R DO ASSERT (r.b); END; END Procedure; BEGIN r.b := TRUE; Procedure (r); END Test. positive: with statement with variable parameter record MODULE Test; TYPE R0 = RECORD END; R1 = RECORD (R0) b: BOOLEAN END; VAR r: R1; PROCEDURE Procedure (VAR r: R0); BEGIN WITH r : R1 DO ASSERT (r.b); END; END Procedure; BEGIN r.b := TRUE; Procedure (r); END Test. negative: unsatisfied with statement with variable parameter record MODULE Test; TYPE R0 = RECORD END; R1 = RECORD (R0) END; VAR r: R0; PROCEDURE Procedure (VAR r: R0); BEGIN WITH r : R1 DO END; END Procedure; BEGIN Procedure (r); END Test. positive: with statement with constant parameter record MODULE Test; TYPE R0 = RECORD END; R1 = RECORD (R0) b: BOOLEAN END; VAR r: R1; PROCEDURE Procedure (CONST r: R0); BEGIN WITH r : R1 DO ASSERT (r.b); END; END Procedure; BEGIN r.b := TRUE; Procedure (r); END Test. negative: unsatisfied with statement with constant parameter record MODULE Test; TYPE R0 = RECORD END; R1 = RECORD (R0) END; VAR r: R0; PROCEDURE Procedure (CONST r: R0); BEGIN WITH r : R1 DO END; END Procedure; BEGIN Procedure (r); END Test. positive: with statement with same pointer to record MODULE Test; TYPE R = RECORD b: BOOLEAN END; P = POINTER TO R; VAR p: P; BEGIN NEW (p); p.b := TRUE; WITH p : P DO ASSERT (p.b); END; END Test. positive: with statement with pointer to record MODULE Test; TYPE R0 = RECORD END; P0 = POINTER TO R0 TYPE R1 = RECORD (R0) b: BOOLEAN END; P1 = POINTER TO R1; VAR p0: P0; p1: P1; BEGIN NEW (p1); p1.b := TRUE; p0 := p1; WITH p0 : P1 DO ASSERT (p0.b); END; END Test. negative: with statement with reassigned pointer to record MODULE Test; TYPE R0 = RECORD END; P0 = POINTER TO R0 TYPE R1 = RECORD (R0) END; P1 = POINTER TO R1; VAR p0: P0; p1: P1; PROCEDURE Reassign; BEGIN NEW (p0); END Reassign; BEGIN NEW (p1); p0 := p1; WITH p0 : P1 DO Reassign; p1 := p0; END; END Test. negative: unsatisfied with statement with pointer to record MODULE Test; TYPE R0 = RECORD END; P0 = POINTER TO R0; TYPE R1 = RECORD (R0) END; P1 = POINTER TO R1; VAR p0: P0; BEGIN NEW (p0); WITH p0 : P1 DO END; END Test. negative: with statement with nil pointer to same record MODULE Test; TYPE R = RECORD END; P = POINTER TO R; VAR p: P; BEGIN p := NIL; WITH p : P DO END; END Test. negative: with statement with nil pointer to record MODULE Test; TYPE R0 = RECORD END; P0 = POINTER TO R0; TYPE R1 = RECORD (R0) END; P1 = POINTER TO R1; VAR p0: P0; BEGIN p0 := NIL; WITH p0 : P1 DO END; END Test. positive: with statement with same object MODULE Test; TYPE O = OBJECT VAR b: BOOLEAN END O; VAR o: O; BEGIN NEW (o); o.b := TRUE; WITH o : O DO ASSERT (o.b); END; END Test. positive: with statement with object MODULE Test; TYPE O0 = OBJECT END O0; TYPE O1 = OBJECT (O0) VAR b: BOOLEAN END O1; VAR o0: O0; o1: O1; BEGIN NEW (o1); o1.b := TRUE; o0 := o1; WITH o0 : O1 DO ASSERT (o0.b); END; END Test. negative: with statement with reassigned object MODULE Test; TYPE O0 = OBJECT END O0; TYPE O1 = OBJECT (O0) END O1; VAR o0: O0; o1: O1; PROCEDURE Reassign; BEGIN NEW (o0); END Reassign; BEGIN NEW (o1); o0 := o1; WITH o0 : O1 DO Reassign; o1 := o0; END; END Test. negative: unsatisfied with statement with object MODULE Test; TYPE O0 = OBJECT END O0; TYPE O1 = OBJECT (O0) END O1; VAR o0: O0; BEGIN NEW (o0); WITH o0 : O1 DO END; END Test. negative: with statement with same nil object MODULE Test; TYPE O = OBJECT END O; VAR o: O; BEGIN o := NIL; WITH o : O DO END; END Test. negative: with statement with nil object MODULE Test; TYPE O0 = OBJECT END O0; TYPE O1 = OBJECT (O0) END O1; VAR o0: O0; BEGIN o0 := NIL; WITH o0 : O1 DO END; END Test. positive: with statement with base object MODULE Test; TYPE O0 = OBJECT; TYPE O1 = OBJECT (O0) VAR b: BOOLEAN END O1; VAR o0: O0; o1: O1; BEGIN NEW (o1); o1.b := TRUE; o0 := o1; WITH o0 : O1 DO ASSERT (o0.b); END; END Test. negative: with statement with nil base object MODULE Test; TYPE O0 = OBJECT; TYPE O1 = OBJECT (O0) END O1; VAR o0: O0; BEGIN o0 := NIL; WITH o0 : O1 DO END; END Test. # nested procedures positive: access to global variable within nested procedure MODULE Test; VAR g: INTEGER; PROCEDURE Procedure; PROCEDURE Nested; BEGIN g := 45; END Nested; BEGIN Nested; END Procedure; BEGIN g := 0; Procedure; ASSERT (g = 45); END Test. positive: access to global variable within nested procedure called from nested procedure MODULE Test; VAR g: INTEGER; PROCEDURE Procedure; PROCEDURE Nested0; BEGIN Nested1; END Nested0; PROCEDURE Nested1; BEGIN g := 45; END Nested1; BEGIN Nested0; END Procedure; BEGIN g := 0; Procedure; ASSERT (g = 45); END Test. positive: access to object variable within nested procedure MODULE Test; VAR o: OBJECT VAR f: INTEGER; PROCEDURE Procedure; PROCEDURE Nested; BEGIN f := 45; END Nested; BEGIN Nested; END Procedure; BEGIN f := 0; Procedure; ASSERT (f = 45); END; BEGIN NEW (o); END Test. positive: access to object variable within nested procedure called from nested procedure MODULE Test; VAR o: OBJECT VAR f: INTEGER; PROCEDURE Procedure; PROCEDURE Nested0; BEGIN Nested1; END Nested0; PROCEDURE Nested1; BEGIN f := 45; END Nested1; BEGIN Nested0; END Procedure; BEGIN f := 0; Procedure; ASSERT (f = 45); END; BEGIN NEW (o); END Test. positive: access to local variable within nested procedure MODULE Test; PROCEDURE Procedure; VAR l: INTEGER; PROCEDURE Nested; BEGIN l := 45; END Nested; BEGIN l := 0; Nested; ASSERT (l = 45); END Procedure; BEGIN Procedure; END Test. positive: access to local variable within nested procedure called from nested procedure MODULE Test; PROCEDURE Procedure; VAR l: INTEGER; PROCEDURE Nested0; BEGIN Nested1; END Nested0; PROCEDURE Nested1; BEGIN l := 45; END Nested1; BEGIN l := 0; Nested0; ASSERT (l = 45); END Procedure; BEGIN Procedure; END Test. positive: access to parameter within nested procedure MODULE Test; PROCEDURE Procedure (p: INTEGER); PROCEDURE Nested; BEGIN p := 45; END Nested; BEGIN Nested; ASSERT (p = 45); END Procedure; BEGIN Procedure (0); END Test. positive: access to parameter within nested procedure called from nested procedure MODULE Test; PROCEDURE Procedure (p: INTEGER); PROCEDURE Nested0; BEGIN Nested1; END Nested0; PROCEDURE Nested1; BEGIN p := 45; END Nested1; BEGIN Nested0; ASSERT (p = 45); END Procedure; BEGIN Procedure (0); END Test. # methods positive: single method call MODULE Test; VAR object: OBJECT PROCEDURE Method; BEGIN ASSERT (i = 0); i := 1; END Method; END; i: INTEGER; BEGIN i := 0; NEW (object); object.Method; ASSERT (i = 1); END Test. positive: single super call MODULE Test; TYPE Object0 = OBJECT PROCEDURE Method; BEGIN ASSERT (i = 1); i := 2; END Method; END Object0; TYPE Object1 = OBJECT (Object0) PROCEDURE Method; BEGIN ASSERT (i = 0); i := 1; Method^; END Method; END Object1; VAR object: Object1; i: INTEGER; BEGIN i := 0; NEW (object); object.Method; ASSERT (i = 2); END Test. positive: double method call MODULE Test; VAR object: OBJECT PROCEDURE Method0; BEGIN ASSERT (i = 0); i := 1; Method1; END Method0; PROCEDURE Method1; BEGIN ASSERT (i = 1); i := 2; END Method1; END; i: INTEGER; BEGIN i := 0; NEW (object); object.Method0; ASSERT (i = 2); END Test. positive: double super call MODULE Test; TYPE Object0 = OBJECT PROCEDURE Method0; BEGIN ASSERT (i = 1); i := 2; Method1; END Method0; PROCEDURE Method1; BEGIN ASSERT (i = 3); i := 4; END Method1; END Object0; TYPE Object1 = OBJECT (Object0) PROCEDURE Method0; BEGIN ASSERT (i = 0); i := 1; Method0^; END Method0; PROCEDURE Method1; BEGIN ASSERT (i = 2); i := 3; Method1^; END Method1; END Object1; VAR object: Object1; i: INTEGER; BEGIN i := 0; NEW (object); object.Method0; ASSERT (i = 4); END Test. positive: single method call with initializer MODULE Test; VAR object: OBJECT VAR i: INTEGER; PROCEDURE &Init (i: INTEGER); BEGIN SELF.i := i; END Init; PROCEDURE Method; BEGIN ASSERT (i = 0); i := 1; END Method; END; BEGIN NEW (object, 0); object.Method; ASSERT (object.i = 1); END Test. positive: single super call with initializer MODULE Test; TYPE Object0 = OBJECT VAR i: INTEGER; PROCEDURE &Init (i: INTEGER); BEGIN SELF.i := i; END Init; PROCEDURE Method; BEGIN ASSERT (i = 1); i := 2; END Method; END Object0; TYPE Object1 = OBJECT (Object0) PROCEDURE &Init (i: INTEGER); BEGIN Init^ (i); END Init; PROCEDURE Method; BEGIN ASSERT (i = 0); i := 1; Method^; END Method; END Object1; VAR object: Object1; BEGIN NEW (object, 0); object.Method; ASSERT (object.i = 2); END Test. positive: double method call with initializer MODULE Test; VAR object: OBJECT VAR i: INTEGER; PROCEDURE &Init (i: INTEGER); BEGIN SELF.i := i; END Init; PROCEDURE Method0; BEGIN ASSERT (i = 0); i := 1; Method1; END Method0; PROCEDURE Method1; BEGIN ASSERT (i = 1); i := 2; END Method1; END; BEGIN NEW (object, 0); object.Method0; ASSERT (object.i = 2); END Test. positive: double super call with initializer MODULE Test; TYPE Object0 = OBJECT VAR i: INTEGER; PROCEDURE &Init (i: INTEGER); BEGIN SELF.i := i; END Init; PROCEDURE Method0; BEGIN ASSERT (i = 1); i := 2; Method1; END Method0; PROCEDURE Method1; BEGIN ASSERT (i = 3); i := 4; END Method1; END Object0; TYPE Object1 = OBJECT (Object0) PROCEDURE &Init (i: INTEGER); BEGIN Init^ (i); END Init; PROCEDURE Method0; BEGIN ASSERT (i = 0); i := 1; Method0^; END Method0; PROCEDURE Method1; BEGIN ASSERT (i = 2); i := 3; Method1^; END Method1; END Object1; VAR object: Object1; BEGIN NEW (object, 0); object.Method0; ASSERT (object.i = 4); END Test. positive: single method call with initializer and body MODULE Test; VAR object: OBJECT VAR i: INTEGER; PROCEDURE &Init (i: INTEGER); BEGIN SELF.i := i; END Init; PROCEDURE Method; BEGIN ASSERT (i = 1); i := 2; END Method; BEGIN ASSERT (i = 0); i := 1; END; BEGIN NEW (object, 0); object.Method; ASSERT (object.i = 2); END Test. positive: single super call with initializer and body MODULE Test; TYPE Object0 = OBJECT VAR i: INTEGER; PROCEDURE &Init (i: INTEGER); BEGIN SELF.i := i; END Init; PROCEDURE Method; BEGIN ASSERT (i = 3); i := 4; END Method; BEGIN ASSERT (i = 0); i := 1; END Object0; TYPE Object1 = OBJECT (Object0) PROCEDURE &Init (i: INTEGER); BEGIN Init^ (i); END Init; PROCEDURE Method; BEGIN ASSERT (i = 2); i := 3; Method^; END Method; BEGIN ASSERT (i = 1); i := 2; END Object1; VAR object: Object1; BEGIN NEW (object, 0); object.Method; ASSERT (object.i = 4); END Test. positive: double method call with initializer and body MODULE Test; VAR object: OBJECT VAR i: INTEGER; PROCEDURE &Init (i: INTEGER); BEGIN SELF.i := i; END Init; PROCEDURE Method0; BEGIN ASSERT (i = 1); i := 2; Method1; END Method0; PROCEDURE Method1; BEGIN ASSERT (i = 2); i := 3; END Method1; BEGIN ASSERT (i = 0); i := 1; END; BEGIN NEW (object, 0); object.Method0; ASSERT (object.i = 3); END Test. positive: double super call with initializer and body MODULE Test; TYPE Object0 = OBJECT VAR i: INTEGER; PROCEDURE &Init (i: INTEGER); BEGIN SELF.i := i; END Init; PROCEDURE Method0; BEGIN ASSERT (i = 3); i := 4; Method1; END Method0; PROCEDURE Method1; BEGIN ASSERT (i = 5); i := 6; END Method1; BEGIN ASSERT (i = 0); i := 1; END Object0; TYPE Object1 = OBJECT (Object0) PROCEDURE &Init (i: INTEGER); BEGIN Init^ (i); END Init; PROCEDURE Method0; BEGIN ASSERT (i = 2); i := 3; Method0^; END Method0; PROCEDURE Method1; BEGIN ASSERT (i = 4); i := 5; Method1^; END Method1; BEGIN ASSERT (i = 1); i := 2; END Object1; VAR object: Object1; BEGIN NEW (object, 0); object.Method0; ASSERT (object.i = 6); END Test. positive: call of object body MODULE Test; VAR o: OBJECT BEGIN b := TRUE END; VAR b: BOOLEAN; BEGIN b := FALSE; NEW(o); ASSERT(b); END Test. positive: call of object body chains MODULE Test; TYPE O = OBJECT BEGIN b1 := TRUE END O; O2=OBJECT(O) BEGIN b2 := b1 END O2; O3=OBJECT(O2) BEGIN b3 := b2 END O3; VAR b1,b2,b3: BOOLEAN; o: O3; BEGIN b1 := FALSE; b2 := FALSE; b3 := FALSE; NEW(o); ASSERT(b1); ASSERT(b2); ASSERT(b3); END Test. positive: call of object body chains with initializer MODULE Test; TYPE O = OBJECT BEGIN b1 := b0 END O; O2=OBJECT(O) BEGIN b2 := b1 END O2; O3=OBJECT(O2) PROCEDURE &Init; BEGIN b0 := TRUE END Init; BEGIN b3 := b2 END O3; VAR b0,b1,b2,b3: BOOLEAN; o: O3; BEGIN b0 := FALSE; b1 := FALSE; b2 := FALSE; b3 := FALSE; NEW(o); ASSERT(b0); ASSERT(b1); ASSERT(b2); ASSERT(b3); END Test. # copy statement positive: copy statement on array of character MODULE Test; VAR source, dest: ARRAY 20 OF CHAR; BEGIN source := "source"; COPY (source, dest); ASSERT (dest = "source"); END Test. positive: copy statement on array of character and longer array of character MODULE Test; VAR source: ARRAY 20 OF CHAR; dest: ARRAY 30 OF CHAR; BEGIN source := "source"; COPY (source, dest); ASSERT (dest = "source"); END Test. positive: copy statement on array of character and shorter array of character MODULE Test; VAR source: ARRAY 30 OF CHAR; dest: ARRAY 20 OF CHAR; BEGIN source := "source"; COPY (source, dest); ASSERT (dest = "source"); END Test. positive: copy statement on string and longer array of character MODULE Test; CONST Source = "source"; VAR dest: ARRAY 20 OF CHAR; BEGIN COPY (Source, dest); ASSERT (dest = Source); END Test. positive: copy statement on empty string and array of character MODULE Test; CONST Source = ""; VAR dest: ARRAY 20 OF CHAR; BEGIN COPY (Source, dest); ASSERT (dest = Source); ASSERT (dest[0] = 0X); END Test. positive: copy statement with array of character parameter as source MODULE Test; PROCEDURE Procedure (source: ARRAY 20 OF CHAR); VAR dest: ARRAY 20 OF CHAR; BEGIN COPY (source, dest); ASSERT (dest = "source"); END Procedure; BEGIN Procedure ("source"); END Test. positive: copy statement with variable array of character parameter as source MODULE Test; VAR source: ARRAY 20 OF CHAR; PROCEDURE Procedure (VAR source: ARRAY 20 OF CHAR); VAR dest: ARRAY 20 OF CHAR; BEGIN COPY (source, dest); ASSERT (dest = "source"); END Procedure; BEGIN source := "source"; Procedure (source); END Test. positive: copy statement with constant array of character parameter as source MODULE Test; PROCEDURE Procedure (CONST source: ARRAY 20 OF CHAR); VAR dest: ARRAY 20 OF CHAR; BEGIN COPY (source, dest); ASSERT (dest = "source"); END Procedure; BEGIN Procedure ("source"); END Test. positive: copy statement with open array of character parameter as source MODULE Test; PROCEDURE Procedure (source: ARRAY OF CHAR); VAR dest: ARRAY 20 OF CHAR; BEGIN COPY (source, dest); ASSERT (dest = "source"); END Procedure; BEGIN Procedure ("source"); END Test. positive: copy statement with too long open array of character parameter as source (truncate) MODULE Test; PROCEDURE Procedure (source: ARRAY OF CHAR); VAR dest: ARRAY 2 OF CHAR; BEGIN COPY (source, dest); ASSERT(dest="s"); END Procedure; BEGIN Procedure ("source"); END Test. positive: copy statement with open variable array of character parameter as source MODULE Test; VAR source: ARRAY 20 OF CHAR; PROCEDURE Procedure (VAR source: ARRAY OF CHAR); VAR dest: ARRAY 20 OF CHAR; BEGIN COPY (source, dest); ASSERT (dest = "source"); END Procedure; BEGIN source := "source"; Procedure (source); END Test. positive: copy statement with too long open variable array of character parameter as source (truncate) MODULE Test; VAR source: ARRAY 20 OF CHAR; PROCEDURE Procedure (VAR source: ARRAY OF CHAR); VAR dest: ARRAY 2 OF CHAR; BEGIN COPY (source, dest);ASSERT(dest="s"); END Procedure; BEGIN source := "source"; Procedure (source); END Test. positive: copy statement with open constant array of character parameter as source MODULE Test; PROCEDURE Procedure (CONST source: ARRAY OF CHAR); VAR dest: ARRAY 20 OF CHAR; BEGIN COPY (source, dest); ASSERT (dest = "source"); END Procedure; BEGIN Procedure ("source"); END Test. positive: copy statement with too long open constant array of character parameter as source (truncate) MODULE Test; PROCEDURE Procedure (CONST source: ARRAY OF CHAR); VAR dest: ARRAY 2 OF CHAR; BEGIN COPY (source, dest); ASSERT(dest="s"); END Procedure; BEGIN Procedure ("source"); END Test. positive: copy statement with array of character parameter as destination MODULE Test; PROCEDURE Procedure (dest: ARRAY 20 OF CHAR); VAR source: ARRAY 20 OF CHAR; BEGIN source := "source"; COPY (source, dest); ASSERT (dest = "source"); END Procedure; BEGIN Procedure ("destination"); END Test. positive: copy statement with variable array of character parameter as destination MODULE Test; VAR dest: ARRAY 20 OF CHAR; PROCEDURE Procedure (VAR dest: ARRAY 20 OF CHAR); VAR source: ARRAY 20 OF CHAR; BEGIN source := "source"; COPY (source, dest); END Procedure; BEGIN Procedure (dest); ASSERT (dest = "source"); END Test. positive: copy statement with open array of character parameter as destination MODULE Test; PROCEDURE Procedure (dest: ARRAY OF CHAR); VAR source: ARRAY 20 OF CHAR; BEGIN source := "source"; COPY (source, dest); ASSERT (dest = "source"); END Procedure; BEGIN Procedure ("destination"); END Test. positive: copy statement with too short open array of character parameter as destination (truncate) MODULE Test; PROCEDURE Procedure (dest: ARRAY OF CHAR); VAR source: ARRAY 20 OF CHAR; BEGIN source := "source"; COPY (source, dest); ASSERT(dest=""); END Procedure; BEGIN Procedure (""); END Test. positive: copy statement with open variable array of character parameter as destination MODULE Test; VAR dest: ARRAY 20 OF CHAR; PROCEDURE Procedure (VAR dest: ARRAY OF CHAR); VAR source: ARRAY 20 OF CHAR; BEGIN source := "source"; COPY (source, dest); END Procedure; BEGIN Procedure (dest); ASSERT (dest = "source"); END Test. positive: copy statement with too short open variable array of character parameter as destination (truncate) MODULE Test; VAR dest: ARRAY 2 OF CHAR; PROCEDURE Procedure (VAR dest: ARRAY OF CHAR); VAR source: ARRAY 20 OF CHAR; BEGIN source := "source"; COPY (source, dest); ASSERT(dest="s"); END Procedure; BEGIN Procedure (dest); END Test. positive: copy statement with string as source and array of character parameter as destination MODULE Test; CONST Source = "source"; PROCEDURE Procedure (dest: ARRAY 20 OF CHAR); BEGIN COPY (Source, dest); ASSERT (dest = Source); END Procedure; BEGIN Procedure ("destination"); END Test. positive: copy statement with empty string as source and array of character parameter as destination MODULE Test; CONST Source = ""; PROCEDURE Procedure (dest: ARRAY 20 OF CHAR); BEGIN COPY (Source, dest); ASSERT (dest = Source); ASSERT (dest[0] = 0X); END Procedure; BEGIN Procedure ("destination"); END Test. positive: copy statement with string as source and variable array of character parameter as destination MODULE Test; CONST Source = "source"; VAR dest: ARRAY 20 OF CHAR; PROCEDURE Procedure (VAR dest: ARRAY 20 OF CHAR); BEGIN COPY (Source, dest); END Procedure; BEGIN Procedure (dest); ASSERT (dest = Source); END Test. positive: copy statement with empty string as source and variable array of character parameter as destination MODULE Test; CONST Source = ""; VAR dest: ARRAY 20 OF CHAR; PROCEDURE Procedure (VAR dest: ARRAY 20 OF CHAR); BEGIN COPY (Source, dest); END Procedure; BEGIN Procedure (dest); ASSERT (dest = Source); ASSERT (dest[0] = 0X); END Test. positive: copy statement with string as source and open array of character parameter as destination MODULE Test; CONST Source = "source"; PROCEDURE Procedure (dest: ARRAY OF CHAR); BEGIN COPY (Source, dest); ASSERT (dest = Source); END Procedure; BEGIN Procedure ("destination"); END Test. positive: copy statement with empty string as source and open array of character parameter as destination MODULE Test; CONST Source = ""; PROCEDURE Procedure (dest: ARRAY OF CHAR); BEGIN COPY (Source, dest); ASSERT (dest = Source); ASSERT (dest[0] = 0X); END Procedure; BEGIN Procedure ("destination"); END Test. positive: copy statement with string as source and too short open array of character parameter as destination (truncate) MODULE Test; CONST Source = "source"; PROCEDURE Procedure (dest: ARRAY OF CHAR); BEGIN COPY (Source, dest); ASSERT (dest = ""); END Procedure; BEGIN Procedure (""); END Test. positive: copy statement with string as source and open variable array of character parameter as destination MODULE Test; CONST Source = "source"; VAR dest: ARRAY 20 OF CHAR; PROCEDURE Procedure (VAR dest: ARRAY OF CHAR); BEGIN COPY (Source, dest); END Procedure; BEGIN Procedure (dest); ASSERT (dest = Source); END Test. positive: copy statement with empty string as source and open variable array of character parameter as destination MODULE Test; CONST Source = ""; VAR dest: ARRAY 20 OF CHAR; PROCEDURE Procedure (VAR dest: ARRAY OF CHAR); BEGIN COPY (Source, dest); END Procedure; BEGIN Procedure (dest); ASSERT (dest = Source); ASSERT (dest[0] = 0X); END Test. positive: copy statement with string as source and too short open variable array of character parameter as destination (truncate) MODULE Test; CONST Source = "source"; VAR dest: ARRAY 2 OF CHAR; PROCEDURE Procedure (VAR dest: ARRAY OF CHAR); BEGIN COPY (Source, dest); END Procedure; BEGIN Procedure (dest); ASSERT(dest="s"); END Test. # string assignment positive: string assignment on array of character MODULE Test; CONST Source = "source"; VAR dest: ARRAY 20 OF CHAR; BEGIN dest := Source; ASSERT (dest = Source); END Test. positive: string assignment on array of character parameter MODULE Test; CONST Source = "source"; PROCEDURE Procedure (dest: ARRAY 20 OF CHAR); BEGIN dest := Source; ASSERT (dest = Source); END Procedure; BEGIN Procedure ("destination"); END Test. positive: string assignment on variable array of character parameter MODULE Test; CONST Source = "source"; VAR dest: ARRAY 20 OF CHAR; PROCEDURE Procedure (VAR dest: ARRAY 20 OF CHAR); BEGIN dest := Source; END Procedure; BEGIN Procedure (dest); ASSERT (dest = Source); END Test. positive: string assignment on open array of character parameter MODULE Test; CONST Source = "source"; PROCEDURE Procedure (dest: ARRAY OF CHAR); BEGIN dest := Source; ASSERT (dest = Source); END Procedure; BEGIN Procedure ("destination"); END Test. negative: string assignment on too short open array of character parameter MODULE Test; CONST Source = "source"; PROCEDURE Procedure (dest: ARRAY OF CHAR); BEGIN dest := Source; ASSERT (dest = Source); END Procedure; BEGIN Procedure (""); END Test. positive: string assignment on open variable array of character parameter MODULE Test; CONST Source = "source"; VAR dest: ARRAY 20 OF CHAR; PROCEDURE Procedure (VAR dest: ARRAY OF CHAR); BEGIN dest := Source; END Procedure; BEGIN Procedure (dest); ASSERT (dest = Source); END Test. positive: string assignment on too short open variable array of character parameter (truncate) MODULE Test; CONST Source = "source"; VAR dest: ARRAY 2 OF CHAR; PROCEDURE Procedure (VAR dest: ARRAY OF CHAR); BEGIN dest := Source; END Procedure; BEGIN Procedure (dest); ASSERT(dest="s"); END Test. # increment statement positive: increment statement with short integers MODULE Test; VAR a, b, c: SHORTINT; BEGIN a := 0; b := 3; c := -4; INC (a); ASSERT (a = 1); DEC (a); ASSERT (a = 0); INC (a, 2); ASSERT (a = 2); INC (a, -2); ASSERT (a = 0); INC (a, b); ASSERT (a = b); INC (a, -b); ASSERT (a = 0); INC (a, c); ASSERT (a = c); INC (a, -c); ASSERT (a = 0); END Test. positive: increment statement with integers MODULE Test; VAR a, b: INTEGER; c: SHORTINT; BEGIN a := 0; b := 3; c := -4; INC (a); ASSERT (a = 1); DEC (a); ASSERT (a = 0); INC (a, 2); ASSERT (a = 2); INC (a, -2); ASSERT (a = 0); INC (a, b); ASSERT (a = b); INC (a, -b); ASSERT (a = 0); INC (a, c); ASSERT (a = c); INC (a, -c); ASSERT (a = 0); END Test. positive: increment statement with long integers MODULE Test; VAR a, b: LONGINT; c: INTEGER; d: SHORTINT; BEGIN a := 0; b := 3; c := -4; d := 5; INC (a); ASSERT (a = 1); DEC (a); ASSERT (a = 0); INC (a, 2); ASSERT (a = 2); INC (a, -2); ASSERT (a = 0); INC (a, b); ASSERT (a = b); INC (a, -b); ASSERT (a = 0); INC (a, c); ASSERT (a = c); INC (a, -c); ASSERT (a = 0); INC (a, d); ASSERT (a = d); INC (a, -d); ASSERT (a = 0); END Test. positive: increment statement with huge integers MODULE Test; VAR a, b: HUGEINT; c: LONGINT; d: INTEGER; e: SHORTINT; BEGIN a := 0; b := 3; c := -4; d := 5; e := -6; INC (a); ASSERT (a = 1); DEC (a); ASSERT (a = 0); INC (a, 2); ASSERT (a = 2); INC (a, -2); ASSERT (a = 0); INC (a, b); ASSERT (a = b); INC (a, -b); ASSERT (a = 0); INC (a, c); ASSERT (a = c); INC (a, -c); ASSERT (a = 0); INC (a, d); ASSERT (a = d); INC (a, -d); ASSERT (a = 0); INC (a, e); ASSERT (a = e); INC (a, -e); ASSERT (a = 0); END Test. # decrement statement positive: decrement statement with short integers MODULE Test; VAR a, b, c: SHORTINT; BEGIN a := 0; b := 3; c := -4; DEC (a); ASSERT (a = -1); INC (a); ASSERT (a = 0); DEC (a, 2); ASSERT (a = -2); DEC (a, -2); ASSERT (a = 0); DEC (a, b); ASSERT (a = -b); DEC (a, -b); ASSERT (a = 0); DEC (a, c); ASSERT (a = -c); DEC (a, -c); ASSERT (a = 0); END Test. positive: decrement statement with integers MODULE Test; VAR a, b: INTEGER; c: SHORTINT; BEGIN a := 0; b := 3; c := -4; DEC (a); ASSERT (a = -1); INC (a); ASSERT (a = 0); DEC (a, 2); ASSERT (a = -2); DEC (a, -2); ASSERT (a = 0); DEC (a, b); ASSERT (a = -b); DEC (a, -b); ASSERT (a = 0); DEC (a, c); ASSERT (a = -c); DEC (a, -c); ASSERT (a = 0); END Test. positive: decrement statement with long integers MODULE Test; VAR a, b: LONGINT; c: INTEGER; d: SHORTINT; BEGIN a := 0; b := 3; c := -4; d := 5; DEC (a); ASSERT (a = -1); INC (a); ASSERT (a = 0); DEC (a, 2); ASSERT (a = -2); DEC (a, -2); ASSERT (a = 0); DEC (a, b); ASSERT (a = -b); DEC (a, -b); ASSERT (a = 0); DEC (a, c); ASSERT (a = -c); DEC (a, -c); ASSERT (a = 0); DEC (a, d); ASSERT (a = -d); DEC (a, -d); ASSERT (a = 0); END Test. positive: decrement statement with huge integers MODULE Test; VAR a, b: HUGEINT; c: LONGINT; d: INTEGER; e: SHORTINT; BEGIN a := 0; b := 3; c := -4; d := 5; e := -6; DEC (a); ASSERT (a = -1); INC (a); ASSERT (a = 0); DEC (a, 2); ASSERT (a = -2); DEC (a, -2); ASSERT (a = 0); DEC (a, b); ASSERT (a = -b); DEC (a, -b); ASSERT (a = 0); DEC (a, c); ASSERT (a = -c); DEC (a, -c); ASSERT (a = 0); DEC (a, d); ASSERT (a = -d); DEC (a, -d); ASSERT (a = 0); DEC (a, e); ASSERT (a = -e); DEC (a, -e); ASSERT (a = 0); END Test. # include statement positive: include statement with short integer as set element MODULE Test; VAR set: SET; element: SHORTINT; BEGIN set := {}; element := MIN (SET); INCL (set, element); ASSERT (set = {element}); ASSERT (set = {MIN (SET)}); ASSERT (element IN set); set := {}; element := MAX (SET); INCL (set, element); ASSERT (set = {element}); ASSERT (set = {MAX (SET)}); ASSERT (element IN set); element := MIN (SET); set := {element}; INCL (set, element); ASSERT (set = {element}); ASSERT (set = {MIN (SET)}); ASSERT (element IN set); element := MAX (SET); set := {element}; INCL (set, element); ASSERT (set = {element}); ASSERT (set = {MAX (SET)}); ASSERT (element IN set); END Test. negative: include statement with too small short integer as set element MODULE Test; VAR set: SET; element: SHORTINT; BEGIN set := {}; element := MIN (SET) - 1; INCL (set, element); END Test. negative: include statement with too large short integer as set element MODULE Test; VAR set: SET; element: SHORTINT; BEGIN set := {}; element := MAX (SET) + 1; INCL (set, element); END Test. positive: include statement with integer as set element MODULE Test; VAR set: SET; element: INTEGER; BEGIN set := {}; element := MIN (SET); INCL (set, element); ASSERT (set = {element}); ASSERT (set = {MIN (SET)}); ASSERT (element IN set); set := {}; element := MAX (SET); INCL (set, element); ASSERT (set = {element}); ASSERT (set = {MAX (SET)}); ASSERT (element IN set); element := MIN (SET); set := {element}; INCL (set, element); ASSERT (set = {element}); ASSERT (set = {MIN (SET)}); ASSERT (element IN set); element := MAX (SET); set := {element}; INCL (set, element); ASSERT (set = {element}); ASSERT (set = {MAX (SET)}); ASSERT (element IN set); END Test. negative: include statement with too small integer as set element MODULE Test; VAR set: SET; element: INTEGER; BEGIN set := {}; element := MIN (SET) - 1; INCL (set, element); END Test. negative: include statement with too large integer as set element MODULE Test; VAR set: SET; element: INTEGER; BEGIN set := {}; element := MAX (SET) + 1; INCL (set, element); END Test. positive: include statement with long integer as set element MODULE Test; VAR set: SET; element: LONGINT; BEGIN set := {}; element := MIN (SET); INCL (set, element); ASSERT (set = {element}); ASSERT (set = {MIN (SET)}); ASSERT (element IN set); set := {}; element := MAX (SET); INCL (set, element); ASSERT (set = {element}); ASSERT (set = {MAX (SET)}); ASSERT (element IN set); element := MIN (SET); set := {element}; INCL (set, element); ASSERT (set = {element}); ASSERT (set = {MIN (SET)}); ASSERT (element IN set); element := MAX (SET); set := {element}; INCL (set, element); ASSERT (set = {element}); ASSERT (set = {MAX (SET)}); ASSERT (element IN set); END Test. negative: include statement with too small long integer as set element MODULE Test; VAR set: SET; element: LONGINT; BEGIN set := {}; element := MIN (SET) - 1; INCL (set, element); END Test. negative: include statement with too large long integer as set element MODULE Test; VAR set: SET; element: LONGINT; BEGIN set := {}; element := MAX (SET) + 1; INCL (set, element); END Test. positive: include statement with huge integer as set element MODULE Test; VAR set: SET; element: HUGEINT; BEGIN set := {}; element := MIN (SET); INCL (set, element); ASSERT (set = {element}); ASSERT (set = {MIN (SET)}); ASSERT (element IN set); set := {}; element := MAX (SET); INCL (set, element); ASSERT (set = {element}); ASSERT (set = {MAX (SET)}); ASSERT (element IN set); element := MIN (SET); set := {element}; INCL (set, element); ASSERT (set = {element}); ASSERT (set = {MIN (SET)}); ASSERT (element IN set); element := MAX (SET); set := {element}; INCL (set, element); ASSERT (set = {element}); ASSERT (set = {MAX (SET)}); ASSERT (element IN set); END Test. negative: include statement with too small huge integer as set element MODULE Test; VAR set: SET; element: HUGEINT; BEGIN set := {}; element := MIN (SET) - 1; INCL (set, element); END Test. negative: include statement with too large huge integer as set element MODULE Test; VAR set: SET; element: HUGEINT; BEGIN set := {}; element := MAX (SET) + 1; INCL (set, element); END Test. # exclude statement positive: exclude statement with short integer as set element MODULE Test; VAR set: SET; element: SHORTINT; BEGIN set := {}; element := MIN (SET); EXCL (set, element); ASSERT (set = {}); ASSERT (~(element IN set)); set := {}; element := MAX (SET); EXCL (set, element); ASSERT (set = {}); ASSERT (~(element IN set)); element := MIN (SET); set := {element}; EXCL (set, element); ASSERT (set = {}); ASSERT (~(element IN set)); element := MAX (SET); set := {element}; EXCL (set, element); ASSERT (set = {}); ASSERT (~(element IN set)); END Test. negative: exclude statement with too small short integer as set element MODULE Test; VAR set: SET; element: SHORTINT; BEGIN set := {}; element := MIN (SET) - 1; EXCL (set, element); END Test. negative: exclude statement with too large short integer as set element MODULE Test; VAR set: SET; element: SHORTINT; BEGIN set := {}; element := MAX (SET) + 1; EXCL (set, element); END Test. positive: exclude statement with integer as set element MODULE Test; VAR set: SET; element: INTEGER; BEGIN set := {}; element := MIN (SET); EXCL (set, element); ASSERT (set = {}); ASSERT (~(element IN set)); set := {}; element := MAX (SET); EXCL (set, element); ASSERT (set = {}); ASSERT (~(element IN set)); element := MIN (SET); set := {element}; EXCL (set, element); ASSERT (set = {}); ASSERT (~(element IN set)); element := MAX (SET); set := {element}; EXCL (set, element); ASSERT (set = {}); ASSERT (~(element IN set)); END Test. negative: exclude statement with too small integer as set element MODULE Test; VAR set: SET; element: INTEGER; BEGIN set := {}; element := MIN (SET) - 1; EXCL (set, element); END Test. negative: exclude statement with too large integer as set element MODULE Test; VAR set: SET; element: INTEGER; BEGIN set := {}; element := MAX (SET) + 1; EXCL (set, element); END Test. positive: exclude statement with long integer as set element MODULE Test; VAR set: SET; element: LONGINT; BEGIN set := {}; element := MIN (SET); EXCL (set, element); ASSERT (set = {}); ASSERT (~(element IN set)); set := {}; element := MAX (SET); EXCL (set, element); ASSERT (set = {}); ASSERT (~(element IN set)); element := MIN (SET); set := {element}; EXCL (set, element); ASSERT (set = {}); ASSERT (~(element IN set)); element := MAX (SET); set := {element}; EXCL (set, element); ASSERT (set = {}); ASSERT (~(element IN set)); END Test. negative: exclude statement with too small long integer as set element MODULE Test; VAR set: SET; element: LONGINT; BEGIN set := {}; element := MIN (SET) - 1; EXCL (set, element); END Test. negative: exclude statement with too large long integer as set element MODULE Test; VAR set: SET; element: LONGINT; BEGIN set := {}; element := MAX (SET) + 1; EXCL (set, element); END Test. positive: exclude statement with huge integer as set element MODULE Test; VAR set: SET; element: HUGEINT; BEGIN set := {}; element := MIN (SET); EXCL (set, element); ASSERT (set = {}); ASSERT (~(element IN set)); set := {}; element := MAX (SET); EXCL (set, element); ASSERT (set = {}); ASSERT (~(element IN set)); element := MIN (SET); set := {element}; EXCL (set, element); ASSERT (set = {}); ASSERT (~(element IN set)); element := MAX (SET); set := {element}; EXCL (set, element); ASSERT (set = {}); ASSERT (~(element IN set)); END Test. negative: exclude statement with too small huge integer as set element MODULE Test; VAR set: SET; element: HUGEINT; BEGIN set := {}; element := MIN (SET) - 1; EXCL (set, element); END Test. negative: exclude statement with too large huge integer as set element MODULE Test; VAR set: SET; element: HUGEINT; BEGIN set := {}; element := MAX (SET) + 1; EXCL (set, element); END Test. # await statement positive: await statement in exclusive block MODULE Test; VAR condition: BOOLEAN; PROCEDURE Await; BEGIN AWAIT (condition) END Await; BEGIN {EXCLUSIVE} condition := TRUE; Await; END Test. negative: await statement in non-exclusive block MODULE Test; VAR condition: BOOLEAN; PROCEDURE Await; BEGIN AWAIT (condition) END Await; BEGIN condition := FALSE; Await; END Test. positive: await statement satisfied by active object MODULE Test; VAR done: BOOLEAN; VAR o: OBJECT BEGIN{ACTIVE} Done; END; PROCEDURE Done; BEGIN{EXCLUSIVE} done := TRUE; END Done; PROCEDURE P; BEGIN{EXCLUSIVE} AWAIT(done) END P; BEGIN done := FALSE; NEW(o); P; END Test. negative: await statement after exit statement in exclusive block MODULE Test; VAR condition: BOOLEAN; BEGIN condition := FALSE; LOOP BEGIN {EXCLUSIVE} EXIT; END; END; AWAIT (condition); END Test. # procedure variables positive: calling global procedure variable MODULE Test; VAR p: PROCEDURE (VAR x: INTEGER); i: INTEGER; PROCEDURE P (VAR x: INTEGER); BEGIN x := 4; END P; BEGIN i := 2; p := P; p (i); ASSERT (i = 4); END Test. negative: calling global nil procedure variable MODULE Test; VAR p: PROCEDURE; BEGIN p := NIL; p; END Test. positive: calling global procedure variable in array MODULE Test; VAR p: ARRAY 10 OF PROCEDURE (VAR x: INTEGER); i: INTEGER; PROCEDURE P (VAR x: INTEGER); BEGIN x := 4; END P; BEGIN i := 2; p[i] := P; p[i](i); ASSERT (i = 4); END Test. negative: calling global nil procedure variable in array MODULE Test; VAR p: ARRAY 10 OF PROCEDURE; i: INTEGER; BEGIN i := 2; p[i] := NIL; p[i]; END Test. positive: calling local procedure variable MODULE Test; PROCEDURE P (VAR x: INTEGER); BEGIN x := 4; END P; PROCEDURE Procedure; VAR p: PROCEDURE (VAR x: INTEGER); i: INTEGER; BEGIN i := 2; p := P; p (i); ASSERT (i = 4); END Procedure; BEGIN Procedure; END Test. negative: calling local nil procedure variable MODULE Test; PROCEDURE Procedure; VAR p: PROCEDURE; BEGIN p := NIL; p; END Procedure; BEGIN Procedure; END Test. positive: calling local procedure variable in array MODULE Test; PROCEDURE P (VAR x: INTEGER); BEGIN x := 4; END P; PROCEDURE Procedure; VAR p: ARRAY 10 OF PROCEDURE (VAR x: INTEGER); i: INTEGER; BEGIN i := 2; p[i] := P; p[i](i); ASSERT (i = 4); END Procedure; BEGIN Procedure; END Test. negative: calling local nil procedure variable in array MODULE Test; PROCEDURE Procedure; VAR p: ARRAY 10 OF PROCEDURE; i: INTEGER; BEGIN i := 2; p[i] := NIL; p[i]; END Procedure; BEGIN Procedure; END Test. positive: calling parameter procedure variable MODULE Test; PROCEDURE P (VAR x: INTEGER); BEGIN x := 4; END P; PROCEDURE Procedure (p: PROCEDURE (VAR x: INTEGER)); VAR i: INTEGER; BEGIN i := 2; p := P; p (i); ASSERT (i = 4); END Procedure; BEGIN Procedure (P); END Test. negative: calling parameter nil procedure variable MODULE Test; PROCEDURE Procedure (p: PROCEDURE); BEGIN p; END Procedure; BEGIN Procedure (NIL); END Test. positive: calling variable parameter procedure variable MODULE Test; VAR p: PROCEDURE (VAR x: INTEGER); PROCEDURE P (VAR x: INTEGER); BEGIN x := 4; END P; PROCEDURE Procedure (VAR p: PROCEDURE (VAR x: INTEGER)); VAR i: INTEGER; BEGIN i := 2; p := P; p (i); ASSERT (i = 4); END Procedure; BEGIN p := P; Procedure (p); END Test. negative: calling variable parameter nil procedure variable MODULE Test; VAR p: PROCEDURE; PROCEDURE Procedure (VAR p: PROCEDURE); BEGIN p; END Procedure; BEGIN p := NIL; Procedure (p); END Test. positive: calling parameter procedure variable of object MODULE Test; VAR i: INTEGER; o: OBJECT VAR p: PROCEDURE (VAR x: INTEGER); END; PROCEDURE P (VAR x: INTEGER); BEGIN x := 4; END P; BEGIN i := 2; NEW (o); o.p := P; o.p (i); ASSERT (i = 4); END Test. negative: calling parameter nil procedure variable of object MODULE Test; VAR o: OBJECT VAR p: PROCEDURE; END; BEGIN NEW (o); o.p := NIL; o.p; END Test. positive: calling parameter procedure variable within object MODULE Test; VAR o: OBJECT VAR p: PROCEDURE (VAR x: INTEGER); PROCEDURE &Procedure; VAR i: INTEGER; BEGIN i := 2; p := P; p (i); ASSERT (i = 4); END Procedure; END; PROCEDURE P (VAR x: INTEGER); BEGIN x := 4; END P; BEGIN NEW (o); END Test. negative: calling parameter nil procedure variable within object MODULE Test; VAR o: OBJECT VAR p: PROCEDURE; PROCEDURE &Procedure; BEGIN p := NIL; p; END Procedure; END; BEGIN NEW (o); END Test. # concurrency positive: exclusive section in procedure in module scope MODULE Test; PROCEDURE P; BEGIN{EXCLUSIVE} END P; BEGIN P END Test. positive: exclusive section in procedure in object scope MODULE Test; VAR a: OBJECT PROCEDURE P; BEGIN{EXCLUSIVE} END P; END; BEGIN NEW(a); a.P END Test. positive: positive await statement in procedure in module scope MODULE Test; VAR done: BOOLEAN; PROCEDURE P; BEGIN{EXCLUSIVE} AWAIT(done) END P; BEGIN done := TRUE; P END Test. negative: active body MODULE Test; VAR start,called: BOOLEAN; VAR o:OBJECT VAR i: LONGINT; BEGIN{ACTIVE} WHILE ~start DO END; called := TRUE END; BEGIN start := FALSE; called := FALSE; NEW(o); start := TRUE; WHILE ~called DO END; HALT(100); END Test. positive: negative await statement in procedure in module scope MODULE Test; VAR done: BOOLEAN; VAR o:OBJECT VAR i: LONGINT; BEGIN{ACTIVE} FOR i := 0 TO 10000 DO END; Done END; PROCEDURE Done; BEGIN{EXCLUSIVE} done := TRUE END Done; PROCEDURE P; BEGIN{EXCLUSIVE} AWAIT(done) END P; BEGIN done := FALSE; NEW(o); P END Test. positive: positive await statement in procedure in object scope MODULE Test; VAR o:OBJECT VAR done: BOOLEAN; PROCEDURE P; BEGIN{EXCLUSIVE} AWAIT(done) END P; BEGIN done := TRUE; END; BEGIN NEW(o); o.P; END Test. positive: negative await statement in procedure in object scope MODULE Test; VAR o:OBJECT VAR done: BOOLEAN; i: LONGINT; PROCEDURE & Init; BEGIN done := FALSE END Init; PROCEDURE P; BEGIN{EXCLUSIVE} AWAIT(done) END P; PROCEDURE Done; BEGIN{EXCLUSIVE} done := TRUE END Done; BEGIN{ACTIVE} FOR i := 0 TO 10000 DO END; Done END; BEGIN NEW(o); o.P; END Test. # programs positive: Gaussian natural sum using arrays MODULE Test; CONST Count = 100; VAR i, sum: LONGINT; a: ARRAY Count OF LONGINT; BEGIN FOR i := 0 TO Count - 1 DO a[i] := i; END; i := 0; sum := 0; WHILE i < Count DO INC (sum, a[i]); INC (i); END; ASSERT (sum = Count * (Count-1) DIV 2); END Test. positive: natural sum with several synchronous concurrent accumulators MODULE Test; TYPE Accumulator = OBJECT VAR i: INTEGER; done: BOOLEAN; PROCEDURE &Init; BEGIN done := FALSE; END Init; PROCEDURE Await; BEGIN {EXCLUSIVE} AWAIT (done); END Await; BEGIN {ACTIVE, EXCLUSIVE} FOR i := 1 TO 100 DO Add END; done := TRUE; END Accumulator; VAR acc0, acc1, acc2: Accumulator; sum: INTEGER; PROCEDURE Busy; VAR i: INTEGER; BEGIN FOR i := 1 TO 100 DO END; END Busy; PROCEDURE Add; VAR temp: INTEGER; BEGIN {EXCLUSIVE} temp := sum; Busy; sum := temp + 1 END Add; BEGIN sum := 0; NEW (acc0); NEW (acc1); NEW (acc2); acc0.Await; acc1.Await; acc2.Await; ASSERT (sum = 300); END Test. positive: dining philosophers MODULE Test; CONST Forks = 5; TYPE Fork = OBJECT VAR taken: BOOLEAN; PROCEDURE &Init; BEGIN taken := FALSE; END Init; PROCEDURE PickUp; BEGIN {EXCLUSIVE} AWAIT (~taken); taken := TRUE; END PickUp; PROCEDURE PutDown; BEGIN {EXCLUSIVE} taken := FALSE; END PutDown; END Fork; TYPE Philosopher = OBJECT VAR first, second, i: INTEGER; done: BOOLEAN PROCEDURE &Init (id: INTEGER); BEGIN IF id # Forks - 1 THEN first := id; second := id + 1; ELSE first := 0; second := Forks - 1 END; done := FALSE; END Init; PROCEDURE Await; BEGIN {EXCLUSIVE} AWAIT (done); END Await; BEGIN {EXCLUSIVE, ACTIVE} FOR i := 1 TO 10 DO Think; fork[first].PickUp; fork[second].PickUp; Eat; fork[second].PutDown; fork[first].PutDown; END; done := TRUE; END Philosopher; VAR fork: ARRAY Forks OF Fork; philosopher: ARRAY Forks OF Philosopher; id: INTEGER; PROCEDURE Think; VAR i: INTEGER; BEGIN FOR i := 1 TO 100 DO END; END Think; PROCEDURE Eat; VAR i: INTEGER; BEGIN FOR i := 1 TO 1000 DO END; END Eat; BEGIN FOR id := 0 TO Forks - 1 DO NEW (fork[id]) END; FOR id := 0 TO Forks - 1 DO NEW (philosopher[id], id) END; FOR id := 0 TO Forks - 1 DO philosopher[id].Await END; END Test. positive: bounded buffer MODULE Test; TYPE Buffer = OBJECT VAR in, out, size: LONGINT; VAR data: POINTER TO ARRAY OF INTEGER; PROCEDURE &Init (len: LONGINT); BEGIN in := 0; out := 0; size := 0; NEW (data, len); END Init; PROCEDURE Put (item: INTEGER); BEGIN {EXCLUSIVE} AWAIT (size # LEN (data)); data[in] := item; in := (in + 1) MOD LEN (data); INC (size) END Put; PROCEDURE Get (VAR item: INTEGER); BEGIN {EXCLUSIVE} AWAIT (size # 0); item := data[out]; out := (out + 1) MOD LEN (data); DEC (size) END Get; END Buffer; TYPE Process = OBJECT VAR count: INTEGER; buffer: Buffer; done: BOOLEAN; PROCEDURE &Init (count: INTEGER; buffer: Buffer); BEGIN SELF.count := count; SELF.buffer := buffer; done := FALSE; END Init; PROCEDURE Await; BEGIN {EXCLUSIVE} AWAIT (done); END Await; PROCEDURE Handle; END Handle; BEGIN {EXCLUSIVE, ACTIVE} Handle; done := TRUE; END Process; TYPE Producer = OBJECT (Process) PROCEDURE Handle; VAR i: INTEGER; BEGIN FOR i := 1 TO count DO buffer.Put (i); END; END Handle; END Producer; TYPE Consumer = OBJECT (Process) PROCEDURE Handle; VAR i, item: INTEGER; BEGIN FOR i := 1 TO count DO buffer.Get (item); ASSERT (item = i); END; END Handle; END Consumer; PROCEDURE Test (len, count: INTEGER); VAR buffer: Buffer; consumer: Consumer; producer: Producer; BEGIN NEW (buffer, len); NEW (consumer, count, buffer); NEW (producer, count, buffer); consumer.Await; producer.Await; END Test; BEGIN Test (1, 1000); Test (10, 1000); Test (1000, 1000); Test (1000, 100); END Test. positive: sudoku solver MODULE Test; CONST Empty = '0'; Blocks = 3; Columns = Blocks * Blocks; Cells = Columns * Columns; TYPE Cell = INTEGER; Value = CHAR; Game = ARRAY Cells + 1 OF Value; PROCEDURE IsValidCell (CONST game: Game; cell: Cell): BOOLEAN; VAR value: Value; VAR row, column: Cell; PROCEDURE Check (start, stride: Cell): BOOLEAN; VAR cells, count: Cell; BEGIN count := stride; FOR cells := 0 TO Columns - 1 DO IF (start # cell) & (game[start] = value) THEN RETURN FALSE END; DEC (count); IF count = 0 THEN count := stride; INC (start, Columns + 1 - stride) ELSE INC (start) END; END; RETURN TRUE; END Check; BEGIN value := game[cell]; IF value = Empty THEN RETURN TRUE END; row := cell DIV Columns; column := cell MOD Columns; RETURN Check (cell - column, Columns) & Check (column, 1) & Check (cell - row MOD Blocks * Columns - column MOD Blocks, Blocks); END IsValidCell; PROCEDURE IsValid (CONST game: Game): BOOLEAN; VAR cell: Cell; BEGIN FOR cell := 0 TO Cells - 1 DO IF ~IsValidCell (game, cell) THEN RETURN FALSE END END; RETURN TRUE; END IsValid; PROCEDURE Solve (VAR game: Game): BOOLEAN; VAR cell: Cell; value: SHORTINT; BEGIN FOR cell := 0 TO Cells - 1 DO IF game[cell] = Empty THEN FOR value := ORD (Empty) + 1 TO ORD (Empty) + Columns DO game[cell] := CHR (value); IF IsValidCell (game, cell) & Solve (game) THEN RETURN TRUE END; END; game[cell] := Empty; RETURN FALSE; END END; RETURN IsValid (game); END Solve; PROCEDURE Check (CONST problem, solution: Game); VAR game: Game; BEGIN ASSERT (IsValid (problem)); ASSERT (IsValid (solution)); game := problem; ASSERT (Solve (game)); ASSERT (game = solution); END Check; BEGIN Check ("003020080090500000018609074600047390080205040059160007930402760000006010040070900", "563724189794581236218639574621847395387295641459163827935412768872956413146378952"); END Test. # miscellaneous positive: SYSTEM.VAL on designator and non-designator expression MODULE Test; IMPORT SYSTEM; PROCEDURE P; VAR c1,c2,c3,c4: CHAR; BEGIN c1 := 0FFX; c2 := 0FFX; c3 := 0FFX; c4 := 0FFX; ASSERT(SYSTEM.VAL(LONGINT,c4) = -1); ASSERT(SYSTEM.VAL(LONGINT,ORD(c4)) = 255); END P; BEGIN P; END Test. positive: reimporting an object type with initializer MODULE A; TYPE D1*= OBJECT END D1; END A. MODULE B; IMPORT A; TYPE D1*= OBJECT (A.D1) PROCEDURE &Init*; BEGIN END Init; END D1; END B. MODULE Test; IMPORT B; PROCEDURE P*; VAR o: B.D1; BEGIN NEW(o); END P; BEGIN P; END Test. positive: reimporting objects and execute bodies MODULE A; TYPE O*= OBJECT VAR initZ-: LONGINT; BEGIN initZ := 999; END O; END A. MODULE B; IMPORT A; TYPE O*= OBJECT (A.O) VAR initY-: LONGINT; BEGIN initY := 998; END O; END B. MODULE Test; IMPORT B; TYPE O*=OBJECT (B.O) VAR initO: LONGINT; BEGIN initO := 997 END O; VAR o: O; BEGIN NEW(o); ASSERT(o.initO=997); ASSERT(o.initY =998); ASSERT(o.initZ=999); END Test. positive: importing protected object MODULE A; TYPE O*= OBJECT PROCEDURE P*; BEGIN{EXCLUSIVE} END P; END O; END A. MODULE Test; IMPORT A; VAR o: A.O; BEGIN NEW(o); o.P; END Test. positive: importing and extending protected object MODULE Test; IMPORT A; TYPE O*= OBJECT (A.O) VAR PROCEDURE Q*; BEGIN P; END Q; END O; VAR o: O; BEGIN NEW(o); o.Q; END Test. positive: passing string parameter to procedure returning pointer MODULE Test; TYPE String= POINTER TO ARRAY OF CHAR; PROCEDURE TestString*(CONST str: ARRAY OF CHAR): String; VAR ch: CHAR; BEGIN ch := str[0]; RETURN NIL END TestString; PROCEDURE Test*; VAR str: String; BEGIN str := TestString("TestStr"); END Test; BEGIN Test END Test. positive: passing array parameter to nested procedure MODULE Test; PROCEDURE Enum(); VAR name: ARRAY 256 OF CHAR; PROCEDURE GetNextSymbol(VAR s: ARRAY OF CHAR ); BEGIN s[0] := 0X; END GetNextSymbol; BEGIN GetNextSymbol(name); END Enum; BEGIN Enum(); END Test. positive: nested procedure calls itself with parameter MODULE Test; PROCEDURE Test; VAR k: LONGINT; PROCEDURE Test0(l: LONGINT); BEGIN ASSERT(l = 999); INC(k); IF k < 10 THEN Test0(l) END; END Test0; BEGIN k := 0; Test0(999); END Test; BEGIN Test; END Test. positive: object type declared in procedure scope MODULE Test; PROCEDURE Test; TYPE O=OBJECT VAR i:LONGINT; PROCEDURE &Init; BEGIN i := 999; END Init; PROCEDURE P; BEGIN ASSERT(i=999); END P; END O; VAR o:O; BEGIN NEW(o); o.P; END Test; BEGIN Test; END Test. positive: expression involving multiple register savings on stack MODULE Test; PROCEDURE Test; VAR a: POINTER TO ARRAY OF LONGINT; i : LONGINT; PROCEDURE Add(i: LONGINT): LONGINT; BEGIN RETURN i+10 END Add; BEGIN NEW(a,10); i := 5; a[i] := 10; a[i] := a[i]+Add(a[i]+Add(a[i] + Add(a[i]))); ASSERT(a[i] = 70); END Test; BEGIN Test; END Test. positive: GETPROCEDURE with procedure returning an object MODULE A; TYPE Object*=OBJECT VAR a-: LONGINT; END Object; PROCEDURE TheProcedure*(): Object; VAR o: Object; BEGIN NEW(o); o.a := 100; RETURN o; END TheProcedure; END A. MODULE Test; IMPORT A; PROCEDURE Test; VAR p: PROCEDURE(): A.Object; o: A.Object; BEGIN GETPROCEDURE("A","TheProcedure",p); o := p(); ASSERT(o.a = 100); END Test; BEGIN Test; END Test. positive: import object and use initializer on alias MODULE A; TYPE O*= OBJECT VAR a*: LONGINT; PROCEDURE &Init*; BEGIN END Init; END O; O2*=O; END A. MODULE Test; IMPORT X :=A; VAR o: X.O2; BEGIN NEW(o); o.a :=10; END Test. positive: procedure returning record MODULE Test; TYPE R= RECORD a,b: LONGINT END; VAR r: R; PROCEDURE P(b,a: LONGINT): R; VAR r: R; BEGIN r.a := a; r.b := b; RETURN r END P; BEGIN r := P(10,20); ASSERT(r.a =20); ASSERT(r.b = 10); END Test. positive: procedure returning static array MODULE Test; TYPE S= ARRAY 128 OF CHAR; VAR s:S; PROCEDURE Q(CONST name: ARRAY OF CHAR): S; VAR s:S; BEGIN COPY(name,s); RETURN s; END Q; BEGIN s := Q("TestText"); ASSERT(s= "TestText"); END Test. positive: assign static array of char to static VAR parameter arrray of char MODULE Test; TYPE String = ARRAY 1024 OF CHAR; VAR o:OBJECT VAR x,y,z: LONGINT; string:String; END; name: String; PROCEDURE P(VAR name: String); BEGIN name := o.string; END P; BEGIN NEW(o); o.string := "test"; P(name); ASSERT(name = "test"); END Test. positive: procedure returning record containing pointer MODULE Test; TYPE R= RECORD any: POINTER TO R; a,b: LONGINT END; VAR r: R; PROCEDURE P(b,a: LONGINT): R; VAR r: R; BEGIN r.a := a; r.b := b; RETURN r END P; BEGIN r := P(10,20); ASSERT(r.a =20); ASSERT(r.b = 10); END Test. positive: pass record by value, variable and as a constant MODULE Test; TYPE Record= RECORD min,max: LONGINT END; PROCEDURE P(x: Record); BEGIN ASSERT(x.min = -123); ASSERT(x.max = 123); END P; PROCEDURE Q(VAR x: Record); BEGIN ASSERT(x.min = -123); ASSERT(x.max = 123); END Q; PROCEDURE R(CONST x: Record); BEGIN ASSERT(x.min = -123); ASSERT(x.max = 123); END R; PROCEDURE T; VAR r: Record; BEGIN r.min := -123; r.max := 123; P(r); Q(r); R(r); END T; BEGIN T END Test. positive: procedure returning record called as parameter MODULE Test; TYPE Rectangle=RECORD l,t,r,b: LONGINT END; Object = OBJECT VAR w: LONGINT END Object; PROCEDURE Check(y: Object; r1: Rectangle; x: Object; CONST r2: Rectangle); BEGIN ASSERT(r1.l = r2.l); ASSERT(r1.t = r2.t); ASSERT(r1.r = 10); ASSERT(r1.b = 20); ASSERT(r2.r = 101); ASSERT(r2.b = 102); ASSERT(x.w = 10); END Check; PROCEDURE Q(l,t,r,b: LONGINT): Rectangle; VAR R: Rectangle; BEGIN R.l := l; R.t := t; R.r := r; R.b := b; RETURN R END Q; PROCEDURE P; VAR r1,r2: Rectangle; o: Object; BEGIN NEW(o); o.w := 10; r1.l := 0; r2.l := 0; r1.t := -100; r2.t := -100; r1.r := 10; r1.b := 20; r2.r := 101; r2.b := 102; Check(o,r1,o,r2); Check(o,Q(0,-100,10,20),o,Q(0,-100,101,102)); END P; BEGIN P END Test. positive: pass delegate as parameter MODULE Test; TYPE Procedure = PROCEDURE {DELEGATE}(): LONGINT; TYPE O= OBJECT VAR g: LONGINT; PROCEDURE Test; BEGIN CallProc(OProc); CallProc(GProc); END Test; PROCEDURE OProc(): LONGINT; BEGIN RETURN g END OProc; BEGIN g := 10; END O; PROCEDURE CallProc(p: Procedure); BEGIN ASSERT(p() = 10); END CallProc; PROCEDURE GProc(): LONGINT; BEGIN RETURN 10 END GProc; PROCEDURE P; VAR o: O; BEGIN NEW(o); o.Test; END P; BEGIN P END Test. positive: reimport indirectly published procedure MODULE A; TYPE AO*= OBJECT VAR called*: BOOLEAN; PROCEDURE P*; BEGIN called := TRUE; END P; BEGIN called := FALSE; END AO; AO2*= OBJECT(AO); PROCEDURE P; BEGIN P^ END P; END AO2; END A. MODULE B; IMPORT A; TYPE BO*= OBJECT(A.AO2); PROCEDURE P; BEGIN P^ END P; END BO; END B. MODULE Test; IMPORT B; TYPE O*= OBJECT(B.BO); PROCEDURE P; BEGIN P^; END P; END O; PROCEDURE P; VAR o:O; BEGIN NEW(o); o.P; ASSERT(o.called); END P; BEGIN P; END Test. positive: pass static array by value, reference and as constant MODULE Test; TYPE Array= ARRAY 10 OF LONGINT; PROCEDURE P(x: Array); BEGIN ASSERT(x[5] = -123); ASSERT(x[8] = 123); END P; PROCEDURE Q(VAR x: Array); BEGIN ASSERT(x[5] = -123); ASSERT(x[8] = 123); END Q; PROCEDURE R(CONST x: Array); BEGIN ASSERT(x[5] = -123); ASSERT(x[8] = 123); END R; PROCEDURE T; VAR r: Array; BEGIN r[5] := -123; r[8] := 123; P(r); Q(r); R(r); END T; BEGIN T END Test. positive: procedure returning static array called as parameter MODULE Test; TYPE Rectangle=ARRAY 10 OF LONGINT; Object = OBJECT VAR w: LONGINT END Object; PROCEDURE Check(y: Object; r1: Rectangle; x: Object; CONST r2: Rectangle); BEGIN ASSERT(r1[3] = r2[3]); ASSERT(r1[5] = r2[5]); ASSERT(r1[6] = 10); ASSERT(r1[7] = 20); ASSERT(r2[6] = 101); ASSERT(r2[7] = 102); ASSERT(x.w = 10); END Check; PROCEDURE Q(l,t,r,b: LONGINT): Rectangle; VAR R: Rectangle; BEGIN R[3] := l; R[5] := t; R[6] := r; R[7] := b; RETURN R END Q; PROCEDURE P; VAR r1,r2: Rectangle; o: Object; BEGIN NEW(o); o.w := 10; r1[3] := 0; r2[3] := 0; r1[5] := -100; r2[5] := -100; r1[6] := 10; r1[7] := 20; r2[6] := 101; r2[7] := 102; Check(o,r1,o,r2); Check(o,Q(0,-100,10,20),o,Q(0,-100,101,102)); END P; BEGIN P END Test. positive: new on var parameter object MODULE Test; TYPE O = OBJECT VAR x: LONGINT; PROCEDURE &init; BEGIN x := 10; END init; END O; PROCEDURE Q(VAR o: O); BEGIN NEW(o); ASSERT(o # NIL,101); ASSERT(o.x = 10,102); END Q; PROCEDURE P; VAR o: O; BEGIN Q(o); ASSERT(o.x = 10,103); END P; BEGIN P END Test. positive: new on var parameter array MODULE Test; TYPE O=POINTER TO ARRAY OF INTEGER; PROCEDURE Q(VAR o: O); BEGIN NEW(o,10); o[5] := 10; END Q; PROCEDURE P; VAR o: O; BEGIN Q(o); ASSERT(o[5] = 10); ASSERT(LEN(o)=10); END P; BEGIN P END Test. positive: call procedure returning a basic type within an exclusive section MODULE Test; TYPE O= OBJECT PROCEDURE P(): LONGINT; VAR a: LONGINT; BEGIN{EXCLUSIVE} a := 4; RETURN a*a END P; END O; PROCEDURE P; VAR o: O; BEGIN NEW(o); ASSERT(o.P() = 16); END P; BEGIN P END Test. positive: pass Delegate nil value MODULE Test; TYPE Delegate= PROCEDURE{DELEGATE}; PROCEDURE P(p: Delegate); BEGIN ASSERT(p=NIL); END P; BEGIN P(NIL); (* if incorrect then stack will be invalid => hard brakedown *) END Test. positive: type tests and guards on records and pointers on direct and indirect parameters MODULE Test; TYPE R0=RECORD END; R1=RECORD(R0) v: LONGINT END; R2=RECORD(R0) END; P0=POINTER TO RECORD END; P1=POINTER TO RECORD(P0) v: LONGINT; END; P2=POINTER TO RECORD(P1) END; PROCEDURE R(VAR r: R0); BEGIN ASSERT(r IS R1); ASSERT(~(r IS R2)); WITH r: R1 DO r.v := 10; END; r(R1).v := 10; END R; PROCEDURE S(VAR r: R0); BEGIN R(r); END S; PROCEDURE RC(CONST r: R0); VAR i: LONGINT; BEGIN ASSERT(r IS R1); ASSERT(~(r IS R2)); WITH r: R1 DO i := r.v END; i := r(R1).v; END RC; PROCEDURE SC(CONST r: R0); BEGIN RC(r); END SC; PROCEDURE P(p: P0); BEGIN ASSERT(p IS P1); ASSERT(~(p IS P2)); WITH p: P1 DO p.v := 10; END; p(P1).v := 10; END P; PROCEDURE PV(VAR p: P0); BEGIN ASSERT(p IS P1); ASSERT(~(p IS P2)); WITH p: P1 DO p.v := 10; END; p(P1).v := 10; END PV; PROCEDURE PC(CONST p: P0); BEGIN ASSERT(p IS P1); ASSERT(~(p IS P2)); WITH p: P1 DO p.v := 10; END; p(P1).v := 10; END PC; PROCEDURE Test; VAR r: R1; p: P1; p0: P0; BEGIN R(r); S(r); RC(r); SC(r); NEW(p); p0 := p; P(p); PC(p); PV(p0); END Test; BEGIN Test; END Test. positive: inline procedure with fixups MODULE Test; IMPORT SYSTEM; CONST const = 123; VAR a, b: LONGINT; PROCEDURE -P(): LONGINT; CODE{SYSTEM.i386} MOV EAX,b MOV a,const JMP end MOV EAX,10 end: END P; PROCEDURE Q; VAR b: LONGINT; BEGIN b := P(); ASSERT(a=123); ASSERT(b=1234); END Q; BEGIN b := 1234; Q; a := P(); ASSERT(a=1234); END Test. positive: import inline assembler procedure MODULE A; IMPORT SYSTEM; PROCEDURE -P*(a: LONGINT): LONGINT; CODE{SYSTEM.i386} POP EAX ADD EAX,10 END P; BEGIN ASSERT(P(10) = 20); END A. MODULE Test; IMPORT A; BEGIN ASSERT(A.P(10)=20) END Test. positive: call a winapi procedure with an array of system byte MODULE Test; IMPORT SYSTEM; PROCEDURE{WINAPI} ReadFile (VAR lpBuffer: ARRAY OF SYSTEM.BYTE); BEGIN ASSERT(SYSTEM.VAL(CHAR,lpBuffer[0]) = 'A'); END ReadFile; PROCEDURE P; VAR a: ARRAY 2 OF CHAR; BEGIN a[0] := 'A'; ReadFile(a); END P; BEGIN P END Test. positive: unlock with or without return statements MODULE Test; VAR q: LONGINT; PROCEDURE P; BEGIN{EXCLUSIVE} END P; PROCEDURE P2; BEGIN{EXCLUSIVE} RETURN END P2; PROCEDURE Q(): LONGINT; BEGIN{EXCLUSIVE} RETURN 0 END Q; BEGIN P; P2; P; q := Q(); P; END Test. positive: conversion to 32 bit in ash MODULE Test; PROCEDURE P; VAR l: LONGINT; ch: CHAR; BEGIN ch := CHR(237); l := 8; l := ASH(ORD(ch),l); ASSERT(l=60672); END P; BEGIN P END Test. positive: pass delegate as variable or value parameter MODULE Test; TYPE Array = POINTER TO ARRAY OF CHAR; Delegate = PROCEDURE{DELEGATE}(): LONGINT; O= OBJECT VAR a: Array; PROCEDURE P(): LONGINT; BEGIN ASSERT(a # NIL); RETURN LEN(a); END P; PROCEDURE &Init(a: Array); BEGIN SELF.a := a; END Init; END O; VAR dd: Delegate; o: O; a: Array; PROCEDURE SetDelegate(d: Delegate); BEGIN dd := d; END SetDelegate; PROCEDURE GetDelegate(VAR d: Delegate); BEGIN d := o.P; END GetDelegate; PROCEDURE P; VAR d: Delegate; BEGIN GetDelegate(d); SetDelegate(d); ASSERT(dd() = 123); END P; BEGIN NEW(a,123); NEW(o,a); P; END Test. positive: import same module with different aliases MODULE A; PROCEDURE P*; BEGIN END P; END A. MODULE Test; IMPORT A,B := A; PROCEDURE P; BEGIN A.P; B.P; END P; BEGIN P END Test. positive: procedures returning a record (checks correct return parameter size) MODULE Test; TYPE Rectangle=RECORD t,l,r,b: LONGINT END; Container= POINTER TO RECORD r: Rectangle END; PROCEDURE GetWMCoordinates(VAR r : Rectangle) : Rectangle; VAR rect : Rectangle; BEGIN rect.l := r.l+1; rect.r := r.r+2; rect.t := r.t+3; rect.b := r.b+4; RETURN rect; END GetWMCoordinates; PROCEDURE GetWMCoordinates2() : Rectangle; VAR rect : Rectangle; BEGIN rect.l := 1; rect.r := 2; rect.t := 3; rect.b := 4; RETURN rect; END GetWMCoordinates2; PROCEDURE P1; VAR r2: Rectangle; BEGIN r2 := GetWMCoordinates2(); ASSERT(r2.l = 1,101); ASSERT(r2.r = 2,102); ASSERT(r2.t = 3,103); ASSERT(r2.b = 4,104); END P1; PROCEDURE P2; VAR r1,r2: Rectangle; BEGIN r1.l := 1; r1.r := 2; r1.t := 3; r1.b := 4; r2 := GetWMCoordinates(r1); ASSERT(r2.l = 2,201); ASSERT(r2.r = 4,202); ASSERT(r2.t = 6,203); ASSERT(r2.b = 8,204); END P2; PROCEDURE P3; VAR c1,c2: Container; BEGIN NEW(c1); NEW(c2); c1.r.l := 1; c1.r.r := 2; c1.r.t := 3; c1.r.b := 4; c2.r := GetWMCoordinates(c1.r); ASSERT(c2.r.l = 2); ASSERT(c2.r.r = 4); ASSERT(c2.r.t = 6); ASSERT(c2.r.b = 8); END P3; BEGIN P1;P2;P3; END Test. positive: conversion on return types MODULE Test; PROCEDURE GetInt () : LONGINT; VAR integer: INTEGER; BEGIN integer := -56; RETURN integer END GetInt; PROCEDURE GetShortint () : LONGINT; VAR integer: INTEGER; BEGIN integer := -56; RETURN integer END GetShortint; PROCEDURE P; VAR i: LONGINT; BEGIN i := GetInt(); ASSERT(i=-56); i := GetShortint(); ASSERT(i=-56); END P; BEGIN P; END Test. positive: allocate imported variable MODULE A; TYPE Record*= RECORD a*: LONGINT; p*: POINTER TO ARRAY OF CHAR; c*: LONGINT; END; VAR a*: Record; END A. MODULE Test; IMPORT A; PROCEDURE P; BEGIN NEW(A.a.p,10); ASSERT(A.a.p # NIL,101); END P; BEGIN P; END Test. positive: bitwise rotate MODULE Test; IMPORT SYSTEM; PROCEDURE P; VAR val,rot: SET; by: LONGINT; BEGIN val := {1,2,3,30,31}; rot := SYSTEM.VAL(SET,ROT(SYSTEM.VAL(LONGINT,val),7)); ASSERT(rot ={5..6,8..10}); rot := SYSTEM.VAL(SET,ROT(SYSTEM.VAL(LONGINT,val),-7)); ASSERT(rot={23..24,26..28}); val := {1,2,3,30,31}; by := 7; rot := SYSTEM.VAL(SET,ROT(SYSTEM.VAL(LONGINT,val),by)); ASSERT(rot ={5..6,8..10}); by := -7; rot := SYSTEM.VAL(SET,ROT(SYSTEM.VAL(LONGINT,val),by)); ASSERT(rot={23..24,26..28}); END P; BEGIN P; END Test. positive: huge stack frames to check for ensured stack allocation MODULE Test; PROCEDURE P(count: LONGINT); VAR x: ARRAY 16000 OF CHAR; BEGIN IF count > 5 THEN RETURN END; P(count+1); END P; BEGIN P(0); END Test. positive: finally statement, direct and indirect MODULE Test; VAR b: BOOLEAN; PROCEDURE P; BEGIN HALT(100); RETURN FINALLY b := TRUE END P; PROCEDURE R; BEGIN HALT(100); END R; PROCEDURE Q; BEGIN R; RETURN FINALLY b := TRUE END Q; PROCEDURE S; PROCEDURE R; BEGIN HALT(100); END R; BEGIN R; RETURN FINALLY b := TRUE END S; BEGIN b := FALSE; P(); ASSERT(b=TRUE); b := FALSE; Q(); ASSERT(b=TRUE); b := FALSE; S(); ASSERT(b=TRUE); END Test. positive: negate hugeint zero MODULE Test; PROCEDURE Test; VAR x: INTEGER; h,j: HUGEINT; BEGIN h := 0; j := -h; ASSERT(j=0); END Test; BEGIN Test END Test. positive: allocation of a partially exported record type MODULE A; TYPE P*=POINTER TO Desc; Desc=RECORD a*,b: LONGINT END; END A. MODULE Test; IMPORT A; PROCEDURE Test; VAR a: A.P; BEGIN NEW(a); a.a := 10; ASSERT(a.a = 10); END Test; BEGIN Test END Test. positive: allocation of a partially exported record type in a multiply imported module MODULE A; TYPE P*=POINTER TO Desc; Desc=RECORD a*,b: LONGINT END; END A. MODULE B; END B. MODULE Test; IMPORT BB := B, BBB := B, AA := A, BBBB := B, AAA := A, B, A; PROCEDURE Test; VAR a: AAA.P; BEGIN NEW(a); a.a := 10; ASSERT(a.a = 10); END Test; BEGIN Test END Test. positive: pass sub-array (computation of address needs multiplication with base size) MODULE Test; VAR a: ARRAY 10 OF ARRAY 10 OF INTEGER; PROCEDURE Q(VAR a: ARRAY OF INTEGER; i: INTEGER); VAR j: INTEGER; BEGIN FOR j := 0 TO SHORT(LEN(a)-1 ) DO ASSERT(a[j] = i*10+j); END; END Q; PROCEDURE P(VAR a: ARRAY OF ARRAY OF INTEGER); VAR i,j: INTEGER; BEGIN FOR i := 0 TO SHORT(LEN(a,0)-1) DO FOR j := 0 TO SHORT(LEN(a,1)-1) DO a[i,j] := i*10+j; END; END; FOR i := 0 TO SHORT(LEN(a,0)-1) DO Q(a[i],i); END; END P; BEGIN P(a); END Test. positive: array length operator for static and dynamic arrays with static and dynamic dimension parameter MODULE Test; PROCEDURE Test; VAR a: ARRAY 1,2,3,4 OF LONGINT; b: POINTER TO ARRAY OF ARRAY OF ARRAY 3,4 OF LONGINT; c: POINTER TO ARRAY OF ARRAY OF ARRAY OF ARRAY OF LONGINT; l0,l1,l2,l3,lv,v: LONGINT; BEGIN v := 2; NEW(b,1,2); NEW(c,1,2,3,4); l0 := LEN(a,0); ASSERT(l0=1,1000); l1 := LEN(a,1); ASSERT(l1=2,1001); l2 := LEN(a,2); ASSERT(l2=3,1002); l3 := LEN(a,3); ASSERT(l3=4,1003); FOR v := 0 TO 3 DO lv := LEN(a,v); ASSERT(lv=v+1,1004); END; l0 := LEN(b,0); ASSERT(l0=1,2000); l1 := LEN(b,1); ASSERT(l1=2,2001); l2 := LEN(b,2); ASSERT(l2=3,2002); l3 := LEN(b,3); ASSERT(l3=4,2003); FOR v := 0 TO 3 DO lv := LEN(b,v); ASSERT(lv=v+1,2004); END; l0 := LEN(c,0); ASSERT(l0=1,3000); l1 := LEN(c,1); ASSERT(l1=2,3001); l2 := LEN(c,2); ASSERT(l2=3,3002); l3 := LEN(c,3); ASSERT(l3=4,3003); FOR v := 0 TO 3 DO lv := LEN(c,v); ASSERT(lv=v+1,3004); END; END Test; BEGIN Test END Test. positive: assignment of extended record type to base type (check destination size) MODULE Test; TYPE R= RECORD a,b,c: LONGINT END; S= RECORD (R) d,e: LONGINT END; PROCEDURE Test; VAR a0,a1,a2: LONGINT; b: R; c: LONGINT; d: S; BEGIN a0 := 0; a1 := 0; a2 := 0; c := 0; d.a := MAX(LONGINT); d.b := MAX(LONGINT); d.c := MAX(LONGINT); d.d := MAX(LONGINT); d.e := MAX(LONGINT); b := d; ASSERT(c=0); ASSERT(a0=0); ASSERT(a1=0); ASSERT(a2=0); ASSERT(b.a = MAX(LONGINT)); ASSERT(b.b = MAX(LONGINT)); ASSERT(b.c = MAX(LONGINT)); END Test; BEGIN Test END Test. positive: return of real number (was: problem in AMD float stack) MODULE Test; (** AUTHOR ""; PURPOSE ""; *) VAR r: LONGREAL; PROCEDURE P(): LONGREAL; VAR x,y : LONGREAL; BEGIN x := 10; y := 20; x := x*x; RETURN y END P; BEGIN ASSERT(P()=20); END Test. positive: multiplication with 8-bit number (was: problem in AMD backend register reuse) MODULE Test; VAR longint: LONGINT; PROCEDURE Mul16(ch1,ch2: CHAR; VAR long:LONGINT); VAR int1,int0: INTEGER; BEGIN int1 := ORD(ch1); int0 := ORD(ch2); long := 256 * LONG(int1) + int0; END Mul16; BEGIN Mul16(10X,20X,longint); ASSERT(longint = 256*10H+20H); END Test. positive: test for correct use of SYSTEM.VAL (without conversion) MODULE Test; IMPORT SYSTEM; VAR r: REAL; x: LONGREAL; l: LONGINT; h: HUGEINT; PROCEDURE Real(): LONGINT; VAR r: REAL; l: LONGINT; BEGIN r := 10; (* trick to store real value in original format in longint variable wihout using SYSTEM.VAL, for testing SYSTEM.VAL ! *) SYSTEM.MOVE(SYSTEM.ADR(r),SYSTEM.ADR(l),SIZEOF(REAL)); RETURN l; END Real; PROCEDURE Longreal(): HUGEINT; VAR r: LONGREAL; l: HUGEINT; BEGIN r := 10; (* trick to store real value in original format in longint variable wihout using SYSTEM.VAL, for testing SYSTEM.VAL ! *) SYSTEM.MOVE(SYSTEM.ADR(r),SYSTEM.ADR(l),SIZEOF(HUGEINT)); RETURN l; END Longreal; PROCEDURE Longint(): REAL; VAR r: REAL; l: LONGINT; BEGIN l := 10; (* trick to store real value in original format in longint variable wihout using SYSTEM.VAL, for testing SYSTEM.VAL ! *) SYSTEM.MOVE(SYSTEM.ADR(l),SYSTEM.ADR(r),SIZEOF(REAL)); RETURN r; END Longint; PROCEDURE Hugeint(): LONGREAL; VAR r: LONGREAL; l: HUGEINT; BEGIN l := 10; (* trick to store real value in original format in longint variable wihout using SYSTEM.VAL, for testing SYSTEM.VAL ! *) SYSTEM.MOVE(SYSTEM.ADR(l),SYSTEM.ADR(r),SIZEOF(LONGREAL)); RETURN r; END Hugeint; BEGIN r := SYSTEM.VAL(REAL,Real()); ASSERT(r = 10); x := SYSTEM.VAL(LONGREAL,Longreal()); ASSERT(x = 10); l := SYSTEM.VAL(LONGINT, Longint()); ASSERT(l=10); h := SYSTEM.VAL(HUGEINT, Hugeint()); ASSERT(h=10); END Test. positive: correct use of indexers for (static) array of array MODULE Test; TYPE Elem = ARRAY 4 OF LONGINT; PROCEDURE P; VAR a: ARRAY 8 OF Elem; x: Elem; i: LONGINT; BEGIN FOR i := 0 TO LEN(a)-1 DO a[i,0] := i*1; a[i,1] := i*2; a[i,2] := i*3; a[i,3] := i*4; END; x := a[2]; ASSERT(x[0] = 2); ASSERT(x[1] = 2*2); ASSERT(x[2] = 3*2); ASSERT(x[3] = 4*2); END P; BEGIN P END Test. positive: testing calling convention, in particular return of complex types MODULE Test; TYPE Object = OBJECT VAR a,b,c: INTEGER END Object; Record = RECORD a,b,c: INTEGER END; StaticArray=ARRAY 6 OF INTEGER; DynamicArray = POINTER TO ARRAY OF INTEGER; StaticMathArray= ARRAY [7] OF INTEGER; DynamicMathArray= ARRAY [*] OF INTEGER; TensorMathArray = ARRAY [?] OF INTEGER; PROCEDURE O(a,b,c: INTEGER): Object; VAR o: Object; BEGIN NEW(o); o.a := a; o.b := b; o.c := c; RETURN o; END O; PROCEDURE RO(a,b,c: INTEGER): Object; BEGIN IF RESULT = NIL THEN NEW(RESULT) END; RESULT.a := a; RESULT.b := b; RESULT.c := c; RETURN RESULT; END RO; PROCEDURE R(a,b,c: INTEGER): Record; VAR r: Record BEGIN r.a := a; r.b := b; r.c := c; RETURN r END R; PROCEDURE A(x,y,z: INTEGER): StaticArray; VAR a: StaticArray; BEGIN a[0] := x; a[1] := y; a[2] := z; RETURN a; END A; PROCEDURE RA(x,y,z: INTEGER): StaticArray; BEGIN RESULT[0] := x; RESULT[1] := y; RESULT[2] := z; RETURN RESULT; END RA; PROCEDURE DA(x,y,z: INTEGER): DynamicArray; VAR a: DynamicArray; BEGIN NEW(a,3); a[0] := x; a[1] := y; a[2] := z; RETURN a END DA; PROCEDURE RDA(x,y,z: INTEGER): DynamicArray; BEGIN IF RESULT = NIL THEN NEW(RESULT,3) END; RESULT[0] := x; RESULT[1] := y; RESULT[2] := z; RETURN RESULT END RDA; PROCEDURE MA(x,y,z: INTEGER): StaticMathArray; VAR a: StaticMathArray; BEGIN a[0] := x; a[1] := y; a[2] := z; RETURN a; END MA; PROCEDURE RMA(x,y,z: INTEGER): StaticMathArray; BEGIN RESULT[0] := x; RESULT[1] := y; RESULT[2] := z; RETURN RESULT; END RMA; PROCEDURE DMA(x,y,z: INTEGER): DynamicMathArray; VAR a: DynamicMathArray; BEGIN NEW(a,3); a[0] := x; a[1] := y; a[2] := z; RETURN a; END DMA; PROCEDURE RDMA(x,y,z: INTEGER): DynamicMathArray; BEGIN IF LEN(RESULT) < 3 THEN NEW(RESULT,3) END; RESULT[0] := x; RESULT[1] := y; RESULT[2] := z; RETURN RESULT; END RDMA; PROCEDURE TA(x,y,z: INTEGER): TensorMathArray; VAR a: TensorMathArray; BEGIN NEW(a,3); a[0] := x; a[1] := y; a[2] := z; RETURN a; END TA; PROCEDURE RTA(x,y,z: INTEGER): TensorMathArray; BEGIN IF (DIM(RESULT)# 1) OR (LEN(RESULT,0) < 3) THEN NEW(RESULT,3) END; RESULT[0] := x; RESULT[1] := y; RESULT[2] := z; RETURN RESULT; END RTA; PROCEDURE S(r: Record; a,b,c: INTEGER); BEGIN ASSERT(r.a=a); ASSERT(r.b = b); ASSERT(r.c = c); END S; PROCEDURE T(CONST r: Record; a,b,c: INTEGER); BEGIN ASSERT(r.a=a); ASSERT(r.b = b); ASSERT(r.c = c); END T; PROCEDURE U(o: Object; a,b,c: INTEGER); BEGIN ASSERT(o.a=a); ASSERT(o.b = b); ASSERT(o.c = c); END U; PROCEDURE V(a: StaticArray; x,y,z: INTEGER); BEGIN ASSERT(a[0]=x); ASSERT(a[1] = y); ASSERT(a[2] =z); END V; PROCEDURE W(CONST a: StaticArray; x,y,z: INTEGER); BEGIN ASSERT(a[0]=x); ASSERT(a[1] = y); ASSERT(a[2] =z); END W; PROCEDURE WM(CONST a: StaticMathArray; x,y,z: INTEGER); BEGIN ASSERT(a[0]=x); ASSERT(a[1] = y); ASSERT(a[2] =z); END WM; PROCEDURE WVM(CONST a: StaticMathArray; x,y,z: INTEGER); BEGIN ASSERT(a[0]=x); ASSERT(a[1] = y); ASSERT(a[2] =z); END WVM; PROCEDURE WDM(CONST a: DynamicMathArray; x,y,z: INTEGER); BEGIN ASSERT(a[0]=x); ASSERT(a[1] = y); ASSERT(a[2] =z); END WDM; PROCEDURE WDVM(CONST a: DynamicMathArray; x,y,z: INTEGER); BEGIN ASSERT(a[0]=x); ASSERT(a[1] = y); ASSERT(a[2] =z); END WDVM; PROCEDURE WTM(CONST a: TensorMathArray; x,y,z: INTEGER); BEGIN ASSERT(a[0]=x); ASSERT(a[1] = y); ASSERT(a[2] =z); END WTM; PROCEDURE WTVM(CONST a: TensorMathArray; x,y,z: INTEGER); BEGIN ASSERT(a[0]=x); ASSERT(a[1] = y); ASSERT(a[2] =z); END WTVM; PROCEDURE P; VAR o: Object; r: Record; a: StaticArray; d: DynamicArray; ma: StaticMathArray; dma: DynamicMathArray; tma: TensorMathArray; BEGIN o := O(1,2,3); U(o,1,2,3); o := RO(10,20,30); U(o,10,20,30); o := NIL; o := RO(11,22,33); U(o,11,22,33); r := R(10,20,30); ASSERT(r.a = 10); ASSERT(r.b = 20); ASSERT(r.c = 30); S(R(10,20,30),10,20,30); T(R(10,20,30),10,20,30); U(O(10,20,30),10,20,30); a := A(10,20,30); V(a,10,20,30); V(A(10,20,30),10,20,30); W(A(10,20,30),10,20,30); ma := MA(10,20,30); WM(ma,10,20,30); WM(MA(1,2,3),1,2,3); WVM(MA(2,3,4),2,3,4); dma := DMA(10,20,30); WDM(dma,10,20,30); WDM(DMA(1,2,3),1,2,3); WDVM(DMA(1,2,3),1,2,3); dma := RDMA(10,20,30); WDM(dma,10,20,30); WDM(RDMA(1,2,3),1,2,3); WDVM(RDMA(1,2,3),1,2,3); tma := TA(4,5,6); WTM(tma,4,5,6); WTM(TA(2,3,4),2,3,4); WTVM(TA(3,4,5),3,4,5); tma := RTA(4,5,6); WTM(tma,4,5,6); WTM(RTA(2,3,4),2,3,4); WTVM(RTA(3,4,5),3,4,5); END P; BEGIN P; END Test. positive: simple calling convention test (c and winapi returning pointer) MODULE Test; TYPE Pointer = POINTER TO RECORD x,y: LONGINT END; PROCEDURE {C} P(x,y: LONGINT): Pointer; VAR p: Pointer; BEGIN NEW(p); p.x := x; p.y := y; RETURN p END P; PROCEDURE {WINAPI} Q(x,y: LONGINT): Pointer; VAR p: Pointer; BEGIN NEW(p); p.x := x; p.y := y; RETURN p END Q; PROCEDURE R(x,y: LONGINT): Pointer; VAR p: Pointer; BEGIN NEW(p); p.x := x; p.y := y; RETURN p END R; PROCEDURE Test*; VAR p,q,r: Pointer; BEGIN p := P(1,2); ASSERT(p.x = 1); ASSERT(p.y = 2); q := Q(1,2); ASSERT(q.x = 1); ASSERT(q.y = 2); r := R(1,2); ASSERT(r.x = 1); ASSERT(r.y = 2); END Test; BEGIN Test END Test. positive: use local variable as value and as reference (optimizer test) MODULE Test; PROCEDURE P(VAR x: LONGINT); BEGIN x := 20; END P; PROCEDURE T; VAR x: LONGINT; BEGIN x := 10; P(x); ASSERT(x=20); END T; BEGIN T; END Test. positive: pass record size to array of system.byte with dynamic dize for varpars and dereferences MODULE Test; IMPORT SYSTEM; TYPE Base = RECORD END; TYPE Record = RECORD(Base) a,b,c: LONGINT END PROCEDURE TestS(VAR a: ARRAY OF SYSTEM.BYTE); BEGIN ASSERT(LEN(a) = SIZEOF(Record)); END TestS; PROCEDURE TestI(VAR a: Base); BEGIN TestS(a); END TestI; VAR a: POINTER TO Base; b: POINTER TO Record; c: Record; BEGIN NEW(b); a := b; TestS(a^); TestI(a^); TestI(c); END Test. positive: pass variables and values to array of byte MODULE Test; IMPORT SYSTEM; PROCEDURE Pass(CONST a: ARRAY OF SYSTEM.BYTE; len: LONGINT); VAR i: LONGINT; BEGIN ASSERT(LEN(a) = len); END Pass; PROCEDURE Test; VAR i: LONGINT; BEGIN Pass(3,1); Pass(i,4); Pass(3+i,4); Pass(65000, 2); END Test; BEGIN Test; END Test. positive: pass three-dimensional arrays A[x,y,z] with missing dimensions, e.g. A[x] MODULE Test; IMPORT SYSTEM; PROCEDURE Pass(CONST a: ARRAY OF SYSTEM.BYTE; adr, len: ADDRESS); VAR i: LONGINT; BEGIN ASSERT(ADDRESS OF a[0] = adr); ASSERT(LEN(a) = len); END Pass; PROCEDURE Test; TYPE R= RECORD a,b,c: LONGINT END; S= ARRAY 3 OF LONGINT; VAR b: POINTER TO ARRAY OF ARRAY OF ARRAY OF LONGINT; c: POINTER TO ARRAY OF ARRAY OF ARRAY OF R; d: POINTER TO ARRAY OF ARRAY OF ARRAY OF S; BEGIN NEW(b,7,8,9); Pass(b^, ADDRESS OF b[0,0,0], LEN(b,0)*LEN(b,1)*LEN(b,2)*SIZEOF(LONGINT)); Pass(b[1], ADDRESS OF b[1,0,0], LEN(b,1)*LEN(b,2)*SIZEOF(LONGINT)); Pass(b[1,2], ADDRESS OF b[1,2,0], LEN(b,2)*SIZEOF(LONGINT)); Pass(b[1,2,3], ADDRESS OF b[1,2,3], SIZEOF(LONGINT)); NEW(c,7,8,9); Pass(c^, ADDRESS OF c[0,0,0], LEN(c,0)*LEN(c,1)*LEN(c,2)*SIZEOF(R)); Pass(c[1], ADDRESS OF c[1,0,0], LEN(c,1)*LEN(c,2)*SIZEOF(R)); Pass(c[1,2], ADDRESS OF c[1,2,0], LEN(c,2)*SIZEOF(R)); Pass(c[1,2,3], ADDRESS OF c[1,2,3], SIZEOF(R)); NEW(d,7,8,9); Pass(d^, ADDRESS OF d[0,0,0], LEN(d,0)*LEN(d,1)*LEN(d,2)*SIZEOF(S)); Pass(d[1], ADDRESS OF d[1,0,0], LEN(d,1)*LEN(d,2)*SIZEOF(S)); Pass(d[1,2], ADDRESS OF d[1,2,0], LEN(d,2)*SIZEOF(S)); Pass(d[1,2,3], ADDRESS OF d[1,2,3], SIZEOF(S)); END Test; BEGIN Test; END Test.