MODULE Showcase; (* Tour of everything M2c + mcint can do so far (steps 1-6): scalars, control flow, procedures, composites, sets, pointers, strings, open arrays, I/O and a local MODULE. *) MODULE Stats EXPORT count, Bump, Limit; VAR count : INTEGER; CONST Limit = 100; PROCEDURE Bump; BEGIN count := count + 1 END Bump; END Stats; TYPE Color = (Red, Green, Blue); Inner = RECORD u, v : INTEGER END; Pair = RECORD a : INTEGER; b : Inner END; Node = RECORD val : INTEGER; next : POINTER TO Node END; PNode = POINTER TO Node; VAR total, x, y, i, f, w, k : INTEGER; flag : BOOLEAN; ch : CHAR; col : Color; r : REAL; a, b : ARRAY [1 .. 5] OF INTEGER; m1, m2, m3 : ARRAY [1 .. 2], [1 .. 2] OF INTEGER; rec : Pair; s1, s2, u, n, d : SET OF [0 .. 15]; head, spare : PNode; s, t, s1c : ARRAY [1 .. 10] OF CHAR; ExitCode : INTEGER; PROCEDURE Double(x : INTEGER) : INTEGER; BEGIN RETURN x * 2 END Double; PROCEDURE Incr(VAR x : INTEGER); BEGIN x := x + 1 END Incr; PROCEDURE Fact(n : INTEGER) : INTEGER; BEGIN IF n <= 1 THEN RETURN 1 ELSE RETURN n * Fact(n - 1) END END Fact; PROCEDURE IsEven(n : INTEGER) : BOOLEAN; FORWARD; PROCEDURE IsOdd(n : INTEGER) : BOOLEAN; BEGIN IF n = 0 THEN RETURN FALSE ELSE RETURN IsEven(n - 1) END END IsOdd; PROCEDURE IsEven(n : INTEGER) : BOOLEAN; BEGIN IF n = 0 THEN RETURN TRUE ELSE RETURN IsOdd(n - 1) END END IsEven; PROCEDURE Outer : INTEGER; PROCEDURE Inner : INTEGER; BEGIN RETURN 6 END Inner; BEGIN RETURN Inner() + 1 END Outer; PROCEDURE SumOpen(x : ARRAY OF INTEGER) : INTEGER; VAR i, s : INTEGER; BEGIN s := 0; FOR i := 0 TO HIGH(x) DO s := s + x[i] END; RETURN s END SumOpen; PROCEDURE Append(v : INTEGER); VAR q, r : PNode; BEGIN NEW(q); q^.val := v; q^.next := NIL; IF head = NIL THEN head := q ELSE r := head; WHILE r^.next # NIL DO r := r^.next END; r^.next := q END END Append; PROCEDURE ListSum(p : PNode) : INTEGER; BEGIN IF p = NIL THEN RETURN 0 ELSE RETURN p^.val + ListSum(p^.next) END END ListSum; BEGIN total := 0; WriteString("tour"); Stats.count := 0; Stats.Bump(); Stats.Bump(); Stats.Bump(); total := total + Stats.count; IF Stats.Limit = 100 THEN total := total + 1 END; x := 6 * 7 - 2; total := total + x DIV 10; y := x MOD 7; total := total + y; r := 3.5 + 2.25; IF (r > 5.0) AND (r < 6.0) THEN total := total + 2 END; ch := "A"; IF ch = "A" THEN total := total + 1 END; IF ch < "B" THEN total := total + 1 END; flag := (x > y) AND (y > 0); IF flag THEN total := total + 1 END; flag := NOT flag OR FALSE; IF ~flag THEN total := total + 1 END; col := Green; CASE col OF Red : total := total + 0 | Green : total := total + 3 | Blue : total := total + 5 END; k := 2; CASE k OF 1 : total := total + 0 | 2 : total := total + 4 ELSE total := total + 0 END; i := 0; w := 0; WHILE i < 4 DO i := i + 1; w := w + i END; total := total + w DIV 5; i := 0; REPEAT i := i + 1 UNTIL i >= 3; total := total + i; i := 0; LOOP i := i + 1; IF i = 3 THEN EXIT END END; total := total + i; f := 0; FOR i := 1 TO 5 DO f := f + i END; total := total + f MOD 10; IF x > 100 THEN total := total + 0 ELSIF x > 10 THEN total := total + 2 ELSE total := total + 0 END; total := total + Double(21) DIV 10; Incr(x); total := total + x MOD 10; total := total + Fact(5) DIV 100; IF IsEven(10) THEN total := total + 1 END; total := total + Outer(); a[1] := 5; a[2] := 4; a[3] := 3; a[4] := 2; a[5] := 1; b := a; total := total + b[1]; total := total + HIGH(a); total := total + SumOpen(a); m1[1,1] := 1; m1[1,2] := 2; m1[2,1] := 3; m1[2,2] := 4; m2[1,1] := 5; m2[1,2] := 6; m2[2,1] := 7; m2[2,2] := 8; m3[1,1] := m1[1,1]*m2[1,1] + m1[1,2]*m2[2,1]; m3[1,2] := m1[1,1]*m2[1,2] + m1[1,2]*m2[2,2]; m3[2,1] := m1[2,1]*m2[1,1] + m1[2,2]*m2[2,1]; m3[2,2] := m1[2,1]*m2[1,2] + m1[2,2]*m2[2,2]; total := total + (m3[1,1] + m3[2,2]) MOD 20; rec.a := 1; rec.b.u := 10; rec.b.v := 20; WITH rec DO a := a + 1; WITH b DO u := u + 2; v := v + 3 END END; total := total + rec.a + rec.b.u + rec.b.v; s1 := {1 .. 5}; s2 := {4 .. 8}; u := s1 + s2; n := s1 * s2; d := s1 - s2; IF (1 IN u) AND (5 IN n) AND (2 IN d) THEN total := total + 5 END; IF u = u THEN total := total + 1 END; head := NIL; Append(4); Append(7); Append(9); total := total + ListSum(head); NEW(spare); DISPOSE(spare); s := "ok"; t := "ok"; IF s = t THEN total := total + 2 END; WriteString(s); t := "abc"; IF t # s THEN total := total + 1 END; IF s > t THEN total := total + 1 END; s1c := "okx"; IF s1c > s THEN total := total + 1 END; WriteInt(total); ExitCode := total END Showcase.