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.