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: REF ← NIL];
ROPE: TYPE = Rope.ROPE;
TV: TYPE = AMTypes.TV;
Register:
PUBLIC
PROC [
name: ROPE, --starting with &
proc: EvalQuoteProc,
symTab: SymTab.Ref,
data: REF ← NIL
] = {
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: REF ← NIL] = {
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: REF ← NIL]
RETURNS [return: TV]
arg: InterpreterOps.Tree ← InterpreterOps.GetArg[tree, 1];
tv: TV ← InterpreterOps.Eval[arg, head, target];
ref: REF ← NEW[TV ← tv];
RETURN [AMBridge.TVForReferent[ref]];
};
Register["&evq", EvalQ,
NIL,
NIL];
END.