-- JaMOps.mesa
-- Last changed by Wyatt, 19-Feb-82 10:52:49
-- Last changed by Paxton, 14-Jan-82 14:33:41
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, restore: BOOLEAN ← TRUE];
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[vmname: LONG STRING, maxPages: CARDINAL];
StopJaM: PROC;
}.
Paxton, 20-Oct-81 10:26:07
  add NewFrame, FreeFrame
Wyatt, 22-Oct-81 10:36:26
  add vmname parameter to StartJaM
Wyatt, 24-Oct-81 15:17:56
  add maxPages parameter to StartJaM
Wyatt, 19-Feb-82 10:53:07
  add restore parameter to Error