-- JaMOps.mesa -- Last changed by Wyatt, 24-Oct-81 15:18:05 -- Last changed by Paxton, 30-Jan-82 8:49:44 DIRECTORY JaMBasic USING [Object, Root, StringLength, Tag], JaMInternal USING [Cache, Frame, Locals, Node, Stack], StreamDefs USING [StreamHandle]; JaMOps: DEFINITIONS = { OPEN JaMInternal, JaMBasic; -- Types and Constants StreamHandle: TYPE = StreamDefs.StreamHandle; Text: TYPE = LONG STRING; nullOb: Object = [X,null[]]; -- Signals and Errors Error: ERROR[error: Object]; StackOverflow: ERROR[stack: Stack]; Bug: ERROR; Assert: PROC[pred: BOOLEAN] = INLINE { IF NOT pred THEN ERROR Bug }; -- Commonly-used error names rangechk,typechk,undefname,limitchk: name Object; -- Stack operations Top: PROC[stack: Stack] RETURNS[Object] = INLINE { node: Node ← stack.head; IF node=NIL THEN Underflow[stack]; RETURN[node.ob] }; Pop: PROC[stack: Stack] RETURNS[Object] = INLINE { node: Node ← stack.head; IF node=NIL THEN Underflow[stack]; stack.head ← node.next; node.next ← stack.free; stack.free ← node; RETURN[node.ob] }; Push: PROC[stack: Stack, ob: Object] = INLINE { node: Node ← stack.free; IF node=NIL THEN Overflow[stack]; stack.free ← node.next; node.next ← stack.head; stack.head ← node; node.ob ← ob }; Underflow,Overflow: PROC[stack: Stack]; -- these never return Empty: PROC[stack: Stack] RETURNS[BOOLEAN] = INLINE { RETURN[stack.head=NIL] }; Full: PROC[stack: Stack] RETURNS[BOOLEAN] = INLINE { RETURN[stack.free=NIL] }; GetMark: PROC[stack: Stack] RETURNS[Node] = INLINE { RETURN[stack.free] }; Restore: PROC[stack: Stack, mark: Node]; Copy: PROC[stack: Stack, n: CARDINAL]; Dup: PROC[stack: Stack] = INLINE { Copy[stack,1] }; Exch: PROC[stack: Stack]; Roll: PROC[stack: Stack, n,k: CARDINAL]; ClearStack: PROC[stack: Stack]; CountStack: PROC[stack: Stack, max: CARDINAL ← LAST[CARDINAL]] RETURNS[CARDINAL]; CountToMark: PROC[stack: Stack] RETURNS[CARDINAL]; ClearToMark: PROC[stack: Stack]; Index: PROC[stack: Stack, i: CARDINAL] RETURNS[Object]; StackForAll: PROC[stack: Stack, proc: PROC[Object] RETURNS[BOOLEAN], unwind: BOOLEAN ← FALSE] RETURNS[BOOLEAN]; ArrayFromStack: PROC[stack: Stack] RETURNS[array Object]; NewStack: PROC[CARDINAL] RETURNS[Stack]; FreeStack: PROC[Stack]; -- Type-specific stack operations PushCardinal: PROC[stack: Stack, c: CARDINAL] = INLINE { Push[stack,[L,integer[c]]] }; PushInteger: PROC[stack: Stack, i: LONG INTEGER] = INLINE { Push[stack,[L,integer[i]]] }; PushReal: PROC[stack: Stack, r: REAL] = INLINE { Push[stack,[L,real[r]]] }; PushBoolean: PROC[stack: Stack, b: BOOLEAN] = INLINE { Push[stack,[L,boolean[b]]] }; PopCardinal: PROC[stack: Stack, limit: CARDINAL ← 0] RETURNS[CARDINAL]; PopInteger: PROC[stack: Stack] RETURNS[LONG INTEGER]; PopReal: PROC[stack: Stack] RETURNS[REAL]; PopBoolean: PROC[stack: Stack] RETURNS[BOOLEAN]; PopString: PROC[stack: Stack] RETURNS[string Object]; PopArray: PROC[stack: Stack] RETURNS[array Object]; PopDict: PROC[stack: Stack] RETURNS[dict Object]; PopCommand: PROC[stack: Stack] RETURNS[command Object]; PopStream: PROC[stack: Stack] RETURNS[stream Object]; TopInteger: PROC[stack: Stack] RETURNS[LONG INTEGER]; TopDict: PROC[stack: Stack] RETURNS[dict Object]; -- Array operations Array: PROC[length: CARDINAL] RETURNS[array Object]; ACopy: PROC[array: array Object, expand: CARDINAL ← 0] RETURNS[array Object]; SubArray: PROC[array: array Object, beg,len: CARDINAL] RETURNS[array Object]; PutArray: PROC[from: array Object, beg: CARDINAL, into: array Object]; APut: PROC[array: array Object, i: CARDINAL, ob: Object]; AGet: PROC[array: array Object, i: CARDINAL] RETURNS[Object]; AStore: PROC[stack: Stack, array: array Object]; ALoad: PROC[stack: Stack, array: array Object]; AFind: PROC[array: array Object, ob: Object] RETURNS[BOOLEAN,CARDINAL]; AAtom: PROC[array: array Object] RETURNS[found: BOOLEAN, atom: Object, rem: array Object]; ABind: PROC[array: array Object, dict: dict Object]; ArrayForAll: PROC[array: array Object, proc: PROC[Object] RETURNS[BOOLEAN]] RETURNS[BOOLEAN]; -- Dictionary operations Dict: PROC[maxlen: CARDINAL] RETURNS[dict Object]; DictLength: PROC[dict: dict Object] RETURNS[CARDINAL]; Where: PROC[frame: Frame, key: Object] RETURNS[BOOLEAN,dict Object]; Get: PROC[dict: dict Object, key: Object] RETURNS[Object]; TryToGet: PROC[dict: dict Object, key: Object] RETURNS[BOOLEAN,Object]; Put: PROC[dict: dict Object, key, value: Object]; Def: PROC[frame: Frame, key, value: Object]; Load: PROC[frame: Frame, key: Object] RETURNS[Object]; TryToLoad: PROC[frame: Frame, key: Object] RETURNS[BOOLEAN,Object]; Store: PROC[frame: Frame, key, value: Object]; Del: PROC[dict: dict Object, key: Object]; ClrDict: PROC[dict: dict Object]; AttachDict: PROC[dict, adict: dict Object]; DetachDict: PROC[dict, adict: dict Object]; DetachAll: PROC[dict: dict Object]; Begin: PROC[frame: Frame, dict: dict Object]; End: PROC[frame: Frame]; NewCache: PROC RETURNS[Cache]; FreeCache: PROC[Cache]; -- Locals GetLocalsTop: PROC[frame: Frame] RETURNS[CARDINAL] = INLINE { RETURN[frame.locals.curlen] }; SetLocalsTop: PROC[frame: Frame, top: CARDINAL] = INLINE { frame.locals.curlen ← MIN[frame.locals.curlen,top] }; DefineLocal: PROC[frame: Frame, key,value: Object]; LoadLocal: PROC[frame: Frame, key: Object] RETURNS[Object]; TryToLoadLocal: PROC[frame: Frame, key: Object] RETURNS[BOOLEAN,Object]; StoreLocal: PROC[frame: Frame, key,value: Object]; NewLocals: PROC RETURNS[Locals]; FreeLocals: PROC[Locals]; -- Key comparison KeyName: PROC[key: Object] RETURNS[Object] = INLINE { RETURN[WITH k:key SELECT FROM string => StringToName[k], ENDCASE => key] }; Equality: TYPE = {nil,F,T}; -- nil (if incompatible types), False, or True Compare: PROC[a,b: Object] RETURNS[Equality]; Equal: PROC[a,b: Object] RETURNS[BOOLEAN] = INLINE { WITH a:a SELECT FROM name => WITH b:b SELECT FROM name => RETURN[a.id=b.id]; ENDCASE; ENDCASE; RETURN[Compare[a,b]=T] }; -- Execution Execute: PROC[Frame,Object]; Stop: PROC[Frame]; GetAbort: PROC[Frame] RETURNS[BOOLEAN]; SetAbort: PROC[Frame,BOOLEAN]; MarkLoop: PROC[frame: Frame]; UnmarkLoop: PROC[frame: Frame]; -- Names NameToString: PROC[name Object] RETURNS[string Object]; StringToName: PROC[string Object,Text ← NIL] RETURNS[name Object]; CreateName: PROC[text: Text, tag: Tag ← X] RETURNS[name: name Object, known: BOOLEAN]; -- boolean is true if name already existed, false if was just created MakeName: PROC[text: Text, tag: Tag ← X] RETURNS[name Object] = INLINE { RETURN [CreateName[text,tag].name] }; -- Strings String: PROC[length: StringLength] RETURNS[string Object]; SCopy: PROC[string: string Object, expand: CARDINAL ← 0] RETURNS[string Object]; SubString: PROC[s: string Object, beg,len: CARDINAL] RETURNS[string Object]; PutString: PROC[from: string Object, beg: CARDINAL, into: string Object]; StringCompare: PROC[a,b: string Object] RETURNS[INTEGER]; MakeString: PROC[Text,Tag ← L] RETURNS[string Object]; StringText: PROC[string Object, Text]; StringForAll: PROC[string Object, PROC[CHARACTER] RETURNS[BOOLEAN]]; -- Scanning StreamToken: PROC[frame: Frame, stream: StreamHandle] RETURNS[found,error: BOOLEAN, token: Object]; StringToken: PROC[frame: Frame, ob: string Object] RETURNS[found,error: BOOLEAN, token: Object, rem: string Object]; LineComplete: PROC[text: Text] RETURNS[BOOLEAN]; -- Streams MakeStream: PROC[StreamHandle, Tag ← L] RETURNS[stream Object]; GetStream: PROC[stream Object] RETURNS[StreamHandle]; KillStream: PROC[stream Object]; -- Registration and control root: READONLY LONG POINTER TO Root; defaultFrame: READONLY Frame; RegisterExplicit: PROC[frame: Frame, text: Text, proc: PROC[Frame]]; RegisterImplicit: PROC[frame: Frame, text: Text, proc: PROC[]]; RegisterInternal: PROC[text: Text, proc: PROC[Frame]] RETURNS[command Object]; ForEachFrame: PROC[PROC[Frame]]; ForEachFrameExcept: PROC[Frame,PROC[Frame]]; NewFrame: PROC RETURNS[Frame]; FreeFrame: PROC[Frame]; DoCommand: PROC[frame: Frame, ob: command Object]; -- Installation InstallReason: TYPE = {init,free,register}; InstallProc: TYPE = PROC[InstallReason,Frame]; Install: PROC[InstallProc]; ForEachInstalled: InstallProc; StartJaM: PROC; }.