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; HelpFatalClosure: TYPE = RECORD[proc: HelpFatal, data: REF _ NIL]; HelpFatal: TYPE = PROC [data: REF, head: EvalHead, parent: Tree, msg: ROPE]; HelpWrongTypeClosure: TYPE = RECORD[proc: HelpWrongType, data: REF _ NIL]; HelpWrongType: TYPE = PROC [data: REF, head: EvalHead, parent: Tree, value: TV, target: Type, msg: ROPE] RETURNS [correct: RopeOrTV]; HelpIdClosure: TYPE = RECORD[proc: HelpId, data: REF _ NIL]; HelpId: TYPE = PROC [data: REF, head: EvalHead, parent: Tree, id: ROPE, context: Type, target: Type, msg: ROPE] RETURNS [correct: RopeOrTV]; HelpSelectorClosure: TYPE = RECORD[proc: HelpSelector, data: REF _ NIL]; HelpSelector: TYPE = PROC [data: REF, head: EvalHead, parent: Tree, id: ROPE, context: TV, target: Type, msg: ROPE] RETURNS [correct: RopeOrTV]; HelpDefaultClosure: TYPE = RECORD[proc: HelpDefault, data: REF _ NIL]; HelpDefault: TYPE = PROC [data: REF, head: EvalHead, parent: Tree, type: Type, index: CARDINAL, msg: ROPE] RETURNS [correct: RopeOrTV]; 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. –InterpreterOps.mesa Lifted from BBEval.mesa by Russ Atkinson, December 7, 1982 11:40 am Paul Rovner, July 26, 1983 2:23 pm 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 This is called when a non-recoverable error is found. parent is the offending tree, msg describes what went wrong This 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 This 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 This 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 This 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) 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. Registers the TV under the given name in the specified SymTab. The name must start with the & character. tv = NIL is OK. ΚS– "cedar" style˜Iprocšœ™KšœC™Cšœ"™"K˜šΟk ˜ Kšœœ ˜Kšœœœ˜Kšœ œ˜!Kšœœœ˜Kšœœ˜Kšœœœ˜Kšœ œ˜#Kšœœ˜Kšœœ ˜—K˜Kšœœ ˜!Kšœœœ˜(K˜K™šœ™K˜šΟnœœ6œœ˜MKšœ2™2KšœD™DKšœ5™5Kšœ/™/——˜š ž œœœ  œœœ˜EKšœ'™'Kšœ'™'—J˜šž œœ œœ˜0Jšœ;™;—J˜š žœœœœœ˜OJšœ¨™¨——J˜K™šœ™K˜Kšœœ˜K˜šœ œœ ˜!šœ œ˜šœ˜Kšœ œ™šœ™KšœE™E——Kšœ˜Kšœ˜Kšœ$˜$Kšœ,˜,Kšœ˜Kšœ*˜*Kšœ'˜'Kšœ˜——K˜šœœ˜.Jšœ^™^KšœE™EKšœ ™ —K˜—K™™ ™Kš œœœœœ˜B—š ž œœœœ%œ˜LKšœ5™5Kšœ;™;—˜Kš œœœœœ˜J—šž œœ˜Kšœœ'œœ˜MKšœ˜Kšœ1™1KšœI™IKšœ;™;šœ;™;Kšœ5™5—Kšœ>™>—˜Kš œœœœœ˜<—šžœœ˜Kšœœ$œ$œ˜[Kšœ˜Kšœ=™=KšœK™KKšœ?™?KšœD™Dšœ;™;Kšœ3™3—Kšœ7™7—˜Kš œœœœœ˜H—šž œœ˜Kš œœ$œ œœ˜YKšœ˜šœ=™=Kšœ™—KšœK™KKšœ?™?KšœD™DKšœ7™7—˜Kš œœœœœ˜F—šž œœ˜Kšœœ3œœ˜QKšœ˜Kšœ2™2Kšœ2™2KšœD™DKšœ=™=Kšœ.™.K˜—šœ œœ˜šœ˜Kšœœ˜Kšœ œ˜Kšœœœ˜Kšœœ˜Kš˜—Kšœ œ˜—K˜—K™šœ™K™šž œ˜šœ˜Kšœ œ™šœ™KšœE™E——KšœΟc ˜"Kšœœœ˜)Kšœ'œœ˜1Kšœ/œœ˜9Kšœ!œœ˜+Kšœ-œœ˜7Kšœ+œœ˜4Kšœ˜Kšœ ˜Kšœ™Kšœ0™0Kšœ5™5—K˜Jšž œœœ˜=K˜—K™™,K™šžœ˜Jš œœœœœ œ˜TJšœ‚œ(œ™»J˜—šžœœœœœœœœœ˜WJ˜—š ž œœœœœœ˜LJšœz™zJ˜——Kšœ˜K˜——…— T=