|
|
@@ -0,0 +1,109 @@
|
|
|
+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.
|