MODULE Showcase22; // Tour of this step's additions: // // * forward module-level variables — the procedures below use // `total`, `done` and `label`, all declared after them; // * expression result suffixes — GetRec()^.a, GetArr()^[i]; // * the channel/time wrapper library — StdChans (current output // channel), wrapclock (opaque timespec), wraptime (timeval/tm), // wrapc (rand/signbit/isfinite) and TimeString. // // Writes "showcase22 total=42"; expected ExitCode: 42. IMPORT IOChan, StdChans, TimeString, wrapclock, wraptime, wrapc; FROM SYSTEM IMPORT ADDRESS; TYPE Rec = RECORD a, b : INTEGER END; RecPtr = POINTER TO Rec; Arr = ARRAY [0..3] OF INTEGER; ArrPtr = POINTER TO Arr; VAR ExitCode : INTEGER; VAR r : RecPtr; VAR s : ArrPtr; VAR ok : INTEGER; VAR out : IOChan.ChanId; VAR stamp : ARRAY [0..63] OF CHAR; (* --- forward references: these globals are declared further down --- *) PROCEDURE Bump; BEGIN total := total + 1; IF total >= 3 THEN done := TRUE END END Bump; (* ------------------------------------------------------------------ *) PROCEDURE GetRec () : RecPtr; BEGIN RETURN r END GetRec; PROCEDURE GetArr () : ArrPtr; BEGIN RETURN s END GetArr; VAR total : INTEGER; VAR done : BOOLEAN; VAR label : ARRAY [0..15] OF CHAR; PROCEDURE SetLabel; BEGIN label[0] := "o"; label[1] := "k"; label[2] := CHR(0) END SetLabel; VAR ts : wrapclock.timespec; VAR tv : wraptime.timeval; VAR tm : wraptime.tm; VAR sec, nano : LONGCARD; VAR nrand : INTEGER; BEGIN ExitCode := 0; out := StdChans.OutChan(); (* --- forward variables: Bump uses total/done before their VAR --- *) NEW(r); NEW(s); r^.a := 40; r^.b := 2; s^[0] := 1; s^[1] := 2; s^[2] := 2; s^[3] := 4; Bump; (* total = 1 *) Bump; (* total = 2 *) Bump; (* total = 3, done = TRUE *) total := total + r^.a - r^.b; (* 3 + 40 - 2 = 41 *) SetLabel; (* --- expression result suffixes --- *) total := total + GetRec()^.b - GetArr()^[2]; (* 41 + 2 - 2 = 41 *) IF GetRec()^.a + GetRec()^.b = 42 THEN INC(ok) END; IF GetArr()^[1] + GetArr()^[2] = 4 THEN INC(ok) END; IF done AND (label[0] = "o") THEN total := total + 1 END; (* 42 *) (* --- wrappers --- *) ts := wrapclock.InitTimespec(); ok := ok + wrapclock.SetTimespec(ts, 42, 0); ok := ok + wrapclock.GetTimespec(ts, sec, nano); IF (sec = 42) AND (nano = 0) THEN INC(ok) END; ts := wrapclock.KillTimespec(ts); tv := wraptime.InitTimeval(); tm := wraptime.InitTM(); wraptime.SetTimeval(tv, 0, 0); IF wraptime.LocalTime(tv, tm) # NIL THEN INC(ok) END; tm := wraptime.KillTM(tm); tv := wraptime.KillTimeval(tv); nrand := wrapc.getrand(10); IF (nrand >= 0) AND (nrand < 10) THEN INC(ok) END; IF wrapc.signbit(-1.0) = 1 THEN INC(ok) END; IF wrapc.isfinite(1.0) = 1 THEN INC(ok) END; TimeString.GetTimeString(stamp); IF stamp[0] # CHR(0) THEN INC(ok) END; (* --- report --- *) IOChan.WriteString(out, "showcase22 total="); IOChan.WriteInt(out, total); IOChan.WriteLn(out); IF (total = 42) AND (ok >= 5) THEN ExitCode := 42 ELSE ExitCode := 1 END END Showcase22.