MODULE CoroutineTest; FROM SYSTEM IMPORT ADDRESS, NEWPROCESS, TRANSFER; FROM Storage IMPORT ALLOCATE; FROM Terminal IMPORT ClrScreen; FROM InOut IMPORT WriteString, WriteCard, WriteLn, Read; CONST WorkSize = 500; (* number of words of workspace *) Blank = ' '; (* blank character *) VAR MainProcess: ADDRESS; CoroutineProcessA: ADDRESS; CoroutineProcessB: ADDRESS; wsA, wsB: ADDRESS; ch: CHAR; PROCEDURE CoroutineA; VAR Odd: CARDINAL; (* Natural Numbers *) BEGIN Odd := 1; LOOP WriteLn; WriteString ("Coroutine A: "); WriteCard (Odd, 5); WriteLn; Odd := Odd + 2; TRANSFER (CoroutineProcessA, CoroutineProcessB); (* note that both Couritine Processes have been initialized before use *) END; (* LOOP *) END CoroutineA; PROCEDURE CoroutineB; VAR Even: CARDINAL; (* Natural Numbers *) BEGIN Even := 2; LOOP WriteLn; WriteString ("Coroutine B: "); WriteCard (Even, 5); WriteLn; Even := Even + 2; WriteString ("Press to end this, to continue ..."); WriteLn; Read(ch); IF ch <> Blank THEN TRANSFER (CoroutineProcessB, CoroutineProcessA); ELSE TRANSFER (CoroutineProcessB, MainProcess); (* note that MainProcess has not been initialized; since it is the main program this is normal *) END; (* IF *) END; (* LOOP *) END CoroutineB; BEGIN (* MainProcess *) ClrScreen; WriteString("MainProces"); WriteLn; WriteString("Initializing two Coroutine Processes"); ALLOCATE (wsA, WorkSize); ALLOCATE (wsB, WorkSize); NEWPROCESS(CoroutineA, wsA, WorkSize, CoroutineProcessA); NEWPROCESS(CoroutineB, wsB, WorkSize, CoroutineProcessB); (* note - Main process is not initialized before use *) WriteLn; TRANSFER(MainProcess, CoroutineProcessA); WriteString ("Main process is terminating ..."); END CoroutineTest.