MODULE Showcase21; // Tour of three features added this step: // // * result suffixes — components applied to a function-call result // (GetRec()^.field, GetArr()^[i]); // * PIM coroutines from SYSTEM — PROCESS / NEWPROCESS / TRANSFER, // two coroutines ping-pong five times and hand control back; // * ISO/gm2 standard library — RealStr (RealToFixed), LongMath // (sqrt/round), WholeStr (CardToStr) and DynamicStrings // (InitString/ConCat/CopyOut) build the output label. // // Writes "showcase21 total=42"; expected ExitCode: 42. IMPORT StrIO, WholeStr, RealStr, LongMath, DynamicStrings; FROM DynamicStrings IMPORT String; FROM SYSTEM IMPORT ADDRESS, PROCESS, NEWPROCESS, TRANSFER, ADR; 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 total : INTEGER; VAR x : REAL; VAR hits : CARDINAL; VAR ping, pong, exits : PROCESS; VAR ws1, ws2 : ARRAY [0..65535] OF CHAR; VAR num, label, out : ARRAY [0..63] OF CHAR; VAR ds : String; PROCEDURE GetRec () : RecPtr; BEGIN RETURN r END GetRec; PROCEDURE GetArr () : ArrPtr; BEGIN RETURN s END GetArr; PROCEDURE Ping; BEGIN LOOP TRANSFER(ping, pong) END END Ping; PROCEDURE Pong; BEGIN LOOP INC(hits); IF hits >= 5 THEN TRANSFER(pong, exits) END; TRANSFER(pong, ping) END END Pong; BEGIN ExitCode := 0; (* --- result suffixes --- *) NEW(r); NEW(s); r^.a := 40; r^.b := 2; s^[0] := 1; s^[1] := 2; s^[2] := 2; s^[3] := 4; IF GetRec()^.a + GetRec()^.b = 42 THEN ExitCode := ExitCode + 1 ELSE ExitCode := 100 END; IF GetArr()^[1] + GetArr()^[2] = 4 THEN ExitCode := ExitCode + 2 ELSE ExitCode := 100 END; total := 40; total := total + GetArr()^[1] + GetArr()^[2]; (* 44 *) total := total - GetRec()^.b; (* 42 *) (* --- ISO/gm2 library --- *) RealStr.RealToFixed(42.0, 0, num); (* "42" *) x := LongMath.sqrt(1764.0); (* 42.0 *) IF (num[0] = "4") AND (num[1] = "2") AND (LongMath.round(x) = 42) THEN ExitCode := ExitCode + 4 ELSE ExitCode := 100 END; (* --- coroutines --- *) NEWPROCESS(Ping, ADR(ws1), 65536, ping); NEWPROCESS(Pong, ADR(ws2), 65536, pong); TRANSFER(exits, ping); IF hits = 5 THEN ExitCode := ExitCode + 8 ELSE ExitCode := 100 END; (* --- output line via DynamicStrings + WholeStr --- *) WholeStr.CardToStr(VAL(CARDINAL, total), num); ds := DynamicStrings.InitString("showcase21 total="); ds := DynamicStrings.ConCat(ds, DynamicStrings.InitString(num)); DynamicStrings.CopyOut(out, ds); StrIO.WriteString(out); StrIO.WriteLn; IF ExitCode = 15 THEN ExitCode := 42 END END Showcase21.