InterpreterOps.mesa
Copyright © 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
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;
Basic interpreter operations
Eval: PROC[tree: Tree, head: EvalHead, target: Type ← nullType] RETURNS [TV];
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
ParseExpr: PROC [expr: ROPE, errout: IO.STREAMNIL] RETURNS [Tree];
returns a tree for the given expression
error output (if any) will go to errout
TreeToName: PROC [t: Tree] RETURNS [name: ROPE];
returns NIL if the tree is not simple enuff to yield a name
GetArg: PROC [tree: Tree, which: NAT] RETURNS [son: InterpreterOps.Tree ← NIL];
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
Tree: TYPE = PPTree.Link;
EvalHead: TYPE = REF EvalHeadRep;
EvalHeadRep: TYPE = RECORD
[context: AMModel.Context,
context # NIL.
AMModel.ContextClass[context]
= one of: world, prog(global frame), interface(ir), proc(local frame)
specials: SymTab.Ref,
abortClosure: AbortClosure,
helpFatalClosure: HelpFatalClosure,
helpWrongTypeClosure: HelpWrongTypeClosure,
helpIdClosure: HelpIdClosure,
helpSelectorClosure: HelpSelectorClosure,
helpDefaultClosure: HelpDefaultClosure
];
AbortClosure: TYPE = Interpreter.AbortClosure;
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: TYPE = PROC [data: REF, head: EvalHead, parent: Tree, msg: ROPE];
HelpFatalClosure: TYPE = RECORD[proc: HelpFatal, data: REFNIL];
HelpFatal is called when a non-recoverable error is found. parent is the offending tree, msg describes what went wrong
HelpWrongType: TYPE = PROC [data: REF, head: EvalHead, parent: Tree, value: TV, target: Type, msg: ROPE] RETURNS [correct: RopeOrTV];
HelpWrongTypeClosure: TYPE = RECORD[proc: HelpWrongType, data: REFNIL];
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: 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: REFNIL];
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: 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: REFNIL];
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: TYPE = PROC [data: REF, head: EvalHead, parent: Tree, type: Type, index: CARDINAL, msg: ROPE] RETURNS [correct: RopeOrTV];
HelpDefaultClosure: TYPE = RECORD[proc: HelpDefault, data: REFNIL];
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
RopeOrTV: TYPE = RECORD[
SELECT tag: * FROM
rope => [rope: ROPE],
tv => [tv: TV],
both => [rope: ROPE, tv: TV],
fail => [fail: ROPE],
ENDCASE
] ← [fail[NIL]];
EvalHead operations
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];
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
WorldFromHead: PROC [head: EvalHead] RETURNS [WorldVM.World];
Dealing with the interpreter's symbol tables
EnumerateSymbols: PROC [proc: Ruminant, data: REFNIL, symTab: SymTab.Ref ← NIL] RETURNS [stopped: BOOL];
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.
Ruminant: TYPE = PROC [name: ROPE, help: ROPE, tv: TV, data: REF] RETURNS [stop: BOOL];
... is the type of proc passed to EnumerateSymbols.
RegisterTV: PROC [name: ROPE, tv: TV, help: ROPENIL, symTab: SymTab.Ref];
Registers the TV under the given name in the specified SymTab. The name must start with the & character. tv = NIL is OK.
END.