DIRECTORY AMModel USING [Context], AMTypes USING [TV], Interpreter USING [AbortClosure], IO USING [STREAM], PPTree USING [Link], Rope USING [ROPE], SafeStorage USING [nullType, Type], SymTab USING [Ref], WorldVM USING [World]; InterpreterOps: CEDAR DEFINITIONS = BEGIN OPEN AMTypes, Rope, SafeStorage; Eval: PROC[tree: Tree, head: EvalHead, target: Type _ nullType] RETURNS [TV]; ParseExpr: PROC [expr: ROPE, errout: IO.STREAM _ NIL] RETURNS [Tree]; TreeToName: PROC [t: Tree] RETURNS [name: ROPE]; GetArg: PROC [tree: Tree, which: NAT] RETURNS [son: InterpreterOps.Tree _ NIL]; Tree: TYPE = PPTree.Link; EvalHead: TYPE = REF EvalHeadRep; EvalHeadRep: TYPE = RECORD [context: AMModel.Context, specials: SymTab.Ref, abortClosure: AbortClosure, helpFatalClosure: HelpFatalClosure, helpWrongTypeClosure: HelpWrongTypeClosure, helpIdClosure: HelpIdClosure, helpSelectorClosure: HelpSelectorClosure, helpDefaultClosure: HelpDefaultClosure ]; AbortClosure: TYPE = Interpreter.AbortClosure; HelpFatal: TYPE = PROC [data: REF, head: EvalHead, parent: Tree, msg: ROPE]; HelpFatalClosure: TYPE = RECORD[proc: HelpFatal, data: REF _ NIL]; HelpWrongType: TYPE = PROC [data: REF, head: EvalHead, parent: Tree, value: TV, target: Type, msg: ROPE] RETURNS [correct: RopeOrTV]; HelpWrongTypeClosure: TYPE = RECORD[proc: HelpWrongType, data: REF _ NIL]; HelpId: TYPE = PROC [data: REF, head: EvalHead, parent: Tree, id: ROPE, context: Type, target: Type, msg: ROPE] RETURNS [correct: RopeOrTV]; HelpIdClosure: TYPE = RECORD[proc: HelpId, data: REF _ NIL]; HelpSelector: TYPE = PROC [data: REF, head: EvalHead, parent: Tree, id: ROPE, context: TV, target: Type, msg: ROPE] RETURNS [correct: RopeOrTV]; HelpSelectorClosure: TYPE = RECORD[proc: HelpSelector, data: REF _ NIL]; HelpDefault: TYPE = PROC [data: REF, head: EvalHead, parent: Tree, type: Type, index: CARDINAL, msg: ROPE] RETURNS [correct: RopeOrTV]; HelpDefaultClosure: TYPE = RECORD[proc: HelpDefault, data: REF _ NIL]; RopeOrTV: TYPE = RECORD[ SELECT tag: * FROM rope => [rope: ROPE], tv => [tv: TV], both => [rope: ROPE, tv: TV], fail => [fail: ROPE], ENDCASE ] _ [fail[NIL]]; NewEvalHead: PROC [ context: AMModel.Context, specials: SymTab.Ref, -- non-NIL abortClosure: AbortClosure _ [NIL, NIL], helpFatalClosure: HelpFatalClosure _ [NIL, NIL], helpWrongTypeClosure: HelpWrongTypeClosure _ [NIL, NIL], helpIdClosure: HelpIdClosure _ [NIL, NIL], helpSelectorClosure: HelpSelectorClosure _ [NIL, NIL], helpDefaultClosure: HelpDefaultClosure _ [NIL, NIL] ] RETURNS [EvalHead]; WorldFromHead: PROC [head: EvalHead] RETURNS [WorldVM.World]; EnumerateSymbols: PROC [proc: Ruminant, data: REF _ NIL, symTab: SymTab.Ref _ NIL] RETURNS [stopped: BOOL]; Ruminant: TYPE = PROC [name: ROPE, help: ROPE, tv: TV, data: REF] RETURNS [stop: BOOL]; RegisterTV: PROC [name: ROPE, tv: TV, help: ROPE _ NIL, symTab: SymTab.Ref]; END. 2InterpreterOps.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Paul Rovner, July 26, 1983 2:23 pm Russ Atkinson (RRA) February 12, 1985 3:03:50 pm PST Basic interpreter operations evaluates the given tree using the given eval head the TV returned is the return record if multiple values are returned the TV = AMTypes.GetEmptyTV[] if no args are returned otherwise the appropriate single TV is returned returns a tree for the given expression error output (if any) will go to errout returns NIL if the tree is not simple enuff to yield a name tree must represent the tree for an application. GetArg returns NIL if there is no argument in the specified position. Args are numbered left to right, starting at 1. Types: Tree, EvalHead context # NIL. AMModel.ContextClass[context] = one of: world, prog(global frame), interface(ir), proc(local frame) This is called by Eval or ParseExpr at intervals to ask whether to abort the task and return. return TRUE to cause a call to helpFatal[data, head, tree, "aborted"] return FALSE to proceed normally Help closures HelpFatal is called when a non-recoverable error is found. parent is the offending tree, msg describes what went wrong HelpWrongType is called when the wrong type of TV is found the client should return the correct TV (which must be OK for the target) if a ROPE is returned, it replaces msg as the error message; if target = nullType, then the true target may not be known (this occurs for msg = "not applicable", for example); if target = CODE[PROC], then some procedure should be returned HelpId is called when the given id is not valid for the context; if the client returns a rope, the lookup will begin again with the new rope; if the client returns a TV, the lookup will return with that TV; if the client returns a fail, that will be the new msg for HelpFatal; if context = nullType, then the context is probably dynamic (this may occur for msg = "undefined", for example); if target = nullType, then the true target is not known HelpSelector is called when the given id is not valid for the context (note that the context is a TV); if the client returns a rope, the lookup will begin again with the new rope; if the client returns a TV, the lookup will return with that TV; if the client returns a fail, that will be the new msg for HelpFatal; if target = nullType, then the true target is not known HelpDefault is called when a default value is not present; if index = 0, then the default is missing for type; if index > 0, then the default is missing for that component of type; the client should return a TV to be used as the default value; the client may also return a new error message EvalHead operations context # NIL. AMModel.ContextClass[context] = one of: world, prog(global frame), interface(ir), proc(local frame) NewEvalHead returns a new evaluator head. note that most of the help routines are optional the client can supply special variables for lookup Dealing with the interpreter's symbol tables Enumerates the symbols in the specified table (in no particular order). IF symTab = NIL then the global SymTab is used. Returns TRUE if the client stopped the enumeration, FALSE if not. ... is the type of proc passed to EnumerateSymbols. Registers the TV under the given name in the specified SymTab. The name must start with the & character. tv = NIL is OK. Κ›– "cedar" style˜codešœ™Kšœ Οmœ1™