-- file BasicOps.mesa
-- edited by Brotz and Hilton, September 23, 1982 5:07 PM

DIRECTORY
AltoDefs,
vmD: FROM "VirtualMgrDefs";

BasicOps: DEFINITIONS =

BEGIN

-- Global Variables

opCode: ARRAY [1 .. nOps] OF OpCodeRec;


-- Procedures


ArithmeticOp: PROCEDURE [op: ArithmeticOpType] RETURNS [done: BOOLEAN];


GoSubGuts: PROCEDURE [lineNumber: CARDINAL];


GoToGuts: PROCEDURE [lineNumber: CARDINAL];


LEOp: OpCodeProc;


LesserOp: OpCodeProc;


ListOp: OpCodeProc;


LoadOp: OpCodeProc;


MulOp: OpCodeProc;


NEOp: OpCodeProc;


NextOp: OpCodeProc;


NormalOp: OpCodeProc;


NotOp: OpCodeProc;


OnGoSubOp: OpCodeProc;


OnGoToOp: OpCodeProc;


OrOp: OpCodeProc;


PopOp: OpCodeProc;


PopAndCompare: PROCEDURE RETURNS [result: INTEGER];


PrintOp: OpCodeProc;


PushIOp: OpCodeProc;


PushOp: OpCodeProc;


QuitOp: OpCodeProc;


ReadOp: OpCodeProc;


RenumberOp: OpCodeProc;


RestoreOp: OpCodeProc;


ReturnOp: OpCodeProc;


RunOp: OpCodeProc;


StopOp: OpCodeProc;


Str1PopOp: OpCodeProc;


Str1PushOp: OpCodeProc;


Str2PopOp: OpCodeProc;


Str2PushOp: OpCodeProc;


SubOp: OpCodeProc;


TabOp: OpCodeProc;


UnaryMinusOp: OpCodeProc;


UsingOp: OpCodeProc;


-- Types

ArithmeticOpType: TYPE = {add, sub, mul, div, exp};

Byte: TYPE = AltoDefs.BYTE;

OpCodeRec: TYPE = RECORD [proc: OpCodeProc, type: OpCodeType, name: STRING];

OpCodeProc: TYPE = PROCEDURE [cm: vmD.ComposedMessagePtr, pc: vmD.CharIndex]
RETURNS [done: BOOLEAN, newPc: vmD.CharIndex];

OpCodeType: TYPE = {loner, byte, var, varList, label, labelList, defFn};


-- Contstants

-- In the following, A stands for the 16-bit address of a BasicValue or ArrayRecord;
-- b stands for an 8-bit quantity.

PushVal: Byte = 1; -- Push A : pushes contents of BasicValue A onto stack.
PopVal: Byte = 2; -- Pop A : pops top value of stack into BasicValue A.
PushI: Byte = 3; -- PushI b : Pushes an integer BasicValue whose value is b.
Add: Byte = 4; -- Add : pops two values, adds them, pushes result.
Sub: Byte = 5; -- Sub : subtracts top value from value beneath, pushes result.
Mul: Byte = 6; -- Mul : pops two values, multiplies them, pushes result.
Div: Byte = 7; -- Div : divides top value into value beneath, pushes real result.
CallBuiltInFn: Byte = 8; -- CallBuiltInFn varPtr : pops two arguments from stack, calls registered built-in function varPtr. Pushes single BasicValue result.
Arr1Push: Byte = 9; -- Arr1Push a : Looks up VarPtr a, pops 1 BV from stack, allocates 1-dim array if necessary, indexes a, pushes result.
Arr2Push: Byte = 10; -- Arr2Push a : Looks up VarPtr a, pops 2 BV’s from stack, allocates 2-dim array if necessary, (top is second index), indexes a, pushes result.
Arr1Pop: Byte = 11; -- Arr1Pop a : Looks up VarPtr a, pops 1 BV to be stored, pops one index, allocates 1-dim array if necessary, indexes a and stores first BV in it.
Arr2Pop: Byte = 12; -- Arr2Pop a : Looks up VarPtr a, pops 1 BV to be stored, pops two BV’s for indices (top is second index), allocates 2-dim array if necessary, indexes a and stores first BV in it.
CallUserFn: Byte = 13; -- CallUserFn f : pops one BV, evaluates f, pushes one BV result.
And: Byte = 14; -- And : Pops two BV’s. If either is zero, pushes BV[0], else pushes BV[1].
Or: Byte = 15; -- Or : Pops two BV’s. If either is non-zero, pushes BV[1], else pushes BV[0].
Not: Byte = 16; -- Not : Pops one BV. If zero, pushes BV[1], else pushes BV[0].
Exp: Byte = 17; -- Exp : Pops two BV’s. Pushes top-1 ↑ top.
Equal: Byte = 18; -- Equal : Pops two BV’s. Pushes BV[1] if equal, else pushes BV[0].
NE: Byte = 19; -- NE : Pops two BV’s. Pushes BV[0] if equal, else pushes BV[1].
GE: Byte = 20; -- GE : Pops two BV’s. Pushes BV[1] if top-1 >= top, else pushes BV[0].
LE: Byte = 21; -- LE : Pops two BV’s. Pushes BV[1] if top-1 <= top, else pushes BV[0].
Greater: Byte = 22; -- Greater : Pops two BV’s. Pushes BV[1] if top-1 > top, else pushes BV[0].
Lesser: Byte = 23; -- Lesser : Pops two BV’s. Pushes BV[1] if top-1 < top, else pushes BV[0].
Read: Byte = 24; -- Read : pushes the next data item onto the stack.
Print: Byte = 25; -- Print v1, s1, v2, s2, ... vn, 0 : performs PRINT function from v1, v2, ... , stopping when it encounters the final 0. The si’s are 0, 1, or 2 for stop, comma, or semicolon respectively.
End: Byte = 26; -- Performs END command.
FnEnd: Byte = 27; -- Performs FNEND command.
GoTo: Byte = 28; -- GoTo label : Jumps to code for statement "label".
GoSub: Byte = 29; -- GoSub label : Jumps to code for statement "label", pushing current pc.
Done: Byte = 30; -- Indicates end of program text line.
OnGoTo: Byte = 31; -- OnGoTo label1, label2, ... labeln, 0 : Pops one BV, jumps to appropriate label.
OnGoSub: Byte = 32; -- OnGoSub label1, label2, ... labeln, 0 : Pops one BV, gosubs to appropriate label.
IfZeroDone: Byte = 33; -- IfZeroDone : for IF THEN statements. Pops one BV, if zero, then done.
For: Byte = 34; -- For v : Pops three BV’s, stores top-2 in v, stores v, top-1 and top in a next stack record.
Next: Byte = 35; -- Next v : performs the NEXT command.
Return: Byte = 36; -- does a return.
Quit: Byte = 37; -- does a return.
UnaryMinus: Byte = 38; -- performs unary minus operation on stack top.
Tab: Byte = 39; -- TabOp : pops a byte from stack, prints byte number of spaces, if byte = 255, prints CR; if byte = 254, prints spaces to the next tab stop.
Load: Byte = 40; -- Load : pops a string from the stack, loads a module by that name.
Run: Byte = 41; -- Run : pops a line number from the stack, runs stored code starting there.
Cont: Byte = 42; -- Cont : runs stored code starting from contPc.
Auto: Byte = 43; -- Auto : pops one cardinal from stack to use for auto line numbering.
List: Byte = 44; -- List : pops two cardinals from stack (top is end line number, top-1 is start line number) for LIST command.
Renumber: Byte = 45; -- Renumber : pops four cardinals from stack, top = new start number, top-1 = increment, top-2 = old start number, top-3 = old end number; performs RENUMBER command.
Stop: Byte = 46; -- Stop : performs STOP command.
Delete: Byte = 47; -- Delete : pops two line numbers, top = start line, top-1 = end line (if zero then only delete start line).
Dim: Byte = 48; -- Dim varptr : pops two upper bounds, top=second upper bound, top-1 = first upper bound. Checks varptr to see if array already dimensioned. If so, and new bounds are the same as the old, then no-op. If so, and bounds are different, frees old array and allocates new one. If not, allocates array. A singly dimensioned array has 0 as its second upper bound.
DimStr: Byte = 49; -- DimStr varptr : pops one upper bound. Checks varptr to see if string already allocated. If so, and new bound is the same as the old, then no-op. If so, and bound is different, frees old string and allocates new one. If not, allocates string.
DefFn: Byte = 50; -- DefFn byte varptr1 varptr2 : Defines a user function with name varptr1, argument varptr2 (0 if no argument). byte = 1 if single line function, 2 if multiple line function.
Normal: Byte = 51; -- Normal : Turns off auto line numbering.
CodeList: Byte = 52; -- CodeList : Similar to List, but lists generated code.
Image: Byte = 53; -- Image : precedes an image specification.
Using: Byte = 54; -- Using lineNumber : directs print ops to use the lineNumber’th image.
InputNum: Byte = 55; -- InputNum byte : reads typein, pushes result onto the stack. byte=0 means start new input, byte#0 means continue same input line.
InputStr: Byte = 56; -- InputStr byte : reads typein, pushes result onto the stack. byte=0 means start new input, byte#0 means continue same input line.
Restore: Byte = 57; -- Restore : resets data pointers.
Data: Byte = 58; -- Data var1 var2 ... varn 0 : Data op is followed by n varPointers (to constants) to be read by Read ops.
Str1Push: Byte = 59; -- Str1Push a : Looks up VarPtr a, pops 1 BV from stack, pushes a new substring of a from bv through a.length.
Str2Push: Byte = 60; -- Str2Push a : Looks up VarPtr a, pops 2 BV’s from stack, top=final index, top-1=initial index, pushes substring.
Str1Pop: Byte = 61; -- Str1Pop a : Looks up VarPtr a, pops 1 BV string to be stored, pops one index, replaces subtring of a from index through a.length1.
Str2Pop: Byte = 62; -- Str2Pop a : Looks up VarPtr a, pops 1 BV string to be stored, pops two BV’s for indices, top=final index, top-1=initial index, replaces substring of a.
Help: Byte = 63; -- Help : Prints help information.

nOps: CARDINAL = 63;


END. -- of BasicOps.mesa --