EvalQuoteImpl.mesa
Russ Atkinson, November 19, 1982 1:12 pm
Paul Rovner, July 26, 1983 1:06 pm
DIRECTORY
AMBridge USING [RefFromTV, TVForReferent],
AMTypes USING [TV],
EvalQuote USING [EvalQuoteProc, VisitProc],
InterpreterPrivate USING [GetGlobalSymTab],
Rope USING [ROPE, Fetch],
SymTab USING [Create, EachPairAction, Fetch, Pairs, Store, Ref];
EvalQuoteImpl: CEDAR PROGRAM
IMPORTS AMBridge, InterpreterPrivate, Rope, SymTab
EXPORTS EvalQuote
= BEGIN OPEN AMTypes, Rope, EvalQuote;
MyClosure: TYPE = REF MyClosureRep;
MyClosureRep: TYPE = RECORD [proc: EvalQuoteProc, data: REFNIL];
Register: PUBLIC PROC [
name: ROPE, --starting with &
proc: EvalQuoteProc,
symTab: SymTab.Ref,
data: REFNIL
] = {
closure: MyClosure ← NEW[MyClosureRep ← [proc: proc, data: data]];
found: BOOL;
sttv: TV;
IF symTab = NIL THEN symTab ← InterpreterPrivate.GetGlobalSymTab[];
[found, sttv] ← symTab.Fetch["&EvalQuoteSymTab"];
TRUSTED{
IF found THEN symTab ← LOOPHOLE[AMBridge.RefFromTV[sttv], SymTab.Ref]
ELSE {
newST: SymTab.Ref = SymTab.Create[];
[] ← symTab.Store["&EvalQuoteSymTab", AMBridge.TVForReferent[newST]];
symTab ← newST;
};
};
[] ← symTab.Store[name, closure];
};
Lookup: PUBLIC PROC
[symTab: SymTab.Ref, name: ROPE] RETURNS [proc: EvalQuoteProc ← NIL, data: REFNIL] = {
finds the named EvalQuoteProc (if any), returns [NIL, NIL] if no such proc
closure: MyClosure;
found: BOOL;
wasNilSymTab: BOOL = symTab = NIL;
sttv: TV;
IF name.Fetch[0] # '& THEN RETURN;
IF symTab = NIL THEN symTab ← InterpreterPrivate.GetGlobalSymTab[];
[found, sttv] ← symTab.Fetch["&EvalQuoteSymTab"];
IF NOT found THEN {
IF NOT wasNilSymTab THEN [proc, data] ← Lookup[NIL, name]; -- try the global one
RETURN;
};
TRUSTED{symTab ← LOOPHOLE[AMBridge.RefFromTV[sttv], SymTab.Ref]};
closure ← NARROW[symTab.Fetch[name].val];
IF closure = NIL
THEN {IF NOT wasNilSymTab THEN [proc, data] ← Lookup[NIL, name]}
ELSE {proc ← closure.proc; data ← closure.data};
};
Enumerate: PUBLIC PROC [symTab: SymTab.Ref, visit: VisitProc] = {
enumerates the registered EvalQuote procs
action: SymTab.EachPairAction = {
[key: Key, val: Val] RETURNS [quit: BOOL];
closure: MyClosure ← NARROW[val];
IF closure # NIL THEN
quit ← visit[key, closure.proc, closure.data];
};
found: BOOL;
sttv: TV;
IF symTab = NIL THEN symTab ← InterpreterPrivate.GetGlobalSymTab[];
[found, sttv] ← symTab.Fetch["&EvalQuoteSymTab"];
IF NOT found THEN RETURN;
TRUSTED{symTab ← LOOPHOLE[AMBridge.RefFromTV[sttv], SymTab.Ref]};
[] ← symTab.Pairs[action];
};
END.