EvalQuoteImpl.mesa
Copyright © 1984 by Xerox Corporation. All rights reserved.
Russ Atkinson, July 16, 1984 2:31:07 pm PDT
DIRECTORY
AMBridge USING [RefFromTV, TVForReferent],
AMTypes USING [TV],
EvalQuote USING [EvalQuoteProc, VisitProc],
InterpreterOps USING [Eval, GetArg, Tree],
InterpreterPrivate USING [GetGlobalSymTab],
Rope USING [ROPE, Fetch],
SymTab USING [Create, EachPairAction, Fetch, Pairs, Store, Ref];
EvalQuoteImpl: CEDAR PROGRAM
IMPORTS AMBridge, InterpreterOps, InterpreterPrivate, Rope, SymTab
EXPORTS EvalQuote
= BEGIN OPEN EvalQuote;
MyClosure: TYPE = REF MyClosureRep;
MyClosureRep: TYPE = RECORD [proc: EvalQuoteProc, data: REFNIL];
ROPE: TYPE = Rope.ROPE;
TV: TYPE = AMTypes.TV;
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];
};
EvalQ: EvalQuote.EvalQuoteProc = TRUSTED {
[head: EvalHead, tree: Tree, target: Type ← nullType, data: REFNIL]
RETURNS [return: TV]
arg: InterpreterOps.Tree ← InterpreterOps.GetArg[tree, 1];
tv: TV ← InterpreterOps.Eval[arg, head, target];
ref: REFNEW[TV ← tv];
RETURN [AMBridge.TVForReferent[ref]];
};
Register["&evq", EvalQ, NIL, NIL];
END.