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] = { 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] = { action: SymTab.EachPairAction = { 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 { 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. ~EvalQuoteImpl.mesa Copyright c 1984 by Xerox Corporation. All rights reserved. Russ Atkinson, July 16, 1984 2:31:07 pm PDT finds the named EvalQuoteProc (if any), returns [NIL, NIL] if no such proc enumerates the registered EvalQuote procs [key: Key, val: Val] RETURNS [quit: BOOL]; [head: EvalHead, tree: Tree, target: Type _ nullType, data: REF _ NIL] RETURNS [return: TV] ʘšœ™Jšœ Ïmœ1™