LazyEvaluationImpl.mesa
Copyright Ó 1992 by Xerox Corporation. All rights reserved.
Created by Christian Jacobi, March 11, 1992
Christian Jacobi, May 27, 1992 11:29 am PDT
DIRECTORY LazyEvaluation;
LazyEvaluationImpl: CEDAR MONITOR
EXPORTS LazyEvaluation ~
BEGIN OPEN LazyEvaluation;
check: CONDITION;
Failed: PUBLIC ERROR = CODE;
ProcType: TYPE = PROC [REF] RETURNS [REF];
Ok: ProcType = {ERROR};
Crashed: ProcType = {ERROR};
WaitForOtherEvaluation: ProcType = {ERROR};
State: TYPE = {doit, waitForOtherEvaluation, done, crashed};
Test: ENTRY PROC [h: Handle] RETURNS [proc: ProcType, s: State] = {
IF h.evaluate=Ok THEN RETURN [NIL, done];
IF h.evaluate=WaitForOtherEvaluation THEN RETURN [NIL, waitForOtherEvaluation];
IF h.evaluate=Crashed THEN RETURN [NIL, crashed];
proc ¬ h.evaluate;
h.evaluate ¬ WaitForOtherEvaluation;
RETURN [proc, doit]
};
Notify: ENTRY PROC [] = {
BROADCAST check
};
Wait: ENTRY PROC [h: Handle] = {
IF h.evaluate=WaitForOtherEvaluation THEN WAIT check
};
Evaluate: PUBLIC PROC [h: Handle] RETURNS [REF] = {
proc: ProcType; s: State;
DO
IF h.evaluate=Ok THEN RETURN [h.data];
[proc, s] ¬ Test[h];
SELECT s FROM
done => RETURN [h.data];
doit => {
data: REF;
data ¬ proc[h.data ! UNWIND => {h.evaluate ¬ Crashed; Notify[]}];
SetResult[h, data];
};
waitForOtherEvaluation => Wait[h];
crashed => ERROR Failed;
ENDCASE;
ENDLOOP
};
SetResult: PUBLIC ENTRY PROC [h: Handle, result: REF] = {
IF h#NIL THEN {
h.data ¬ result;
h.evaluate ¬ Ok;
BROADCAST check
};
};
New: PUBLIC PROC [evaluate: PROC [data: REF] RETURNS [REF], data: REF ¬ NIL] RETURNS [Handle] = {
RETURN [ NEW[HandleRec ¬ [evaluate: evaluate, data: data]] ];
};
END.