RobotEvaluator.mesa
Created Monday, May 21, 1984 10:38 pm PDT
Last edited by Eric Nickell, October 27, 1984 11:55:55 am PDT
DIRECTORY
Rope USING [ROPE];
RobotEvaluator: CEDAR DEFINITIONS ~ {
UnOp: TYPE ~ REF UnOpRec;
BinOp: TYPE ~ REF BinOpRec;
TrinOp: TYPE ~ REF TrinOpRec;
UnOpRec: PUBLIC TYPE ~ PROC [a: INTEGER] RETURNS [z: INTEGER];
BinOpRec: PUBLIC TYPE ~ PROC [a,b: INTEGER] RETURNS [z: INTEGER];
TrinOpRec: PUBLIC TYPE ~ PROC [a,b,c: INTEGER] RETURNS [z: INTEGER];
Value: TYPE ~ REF ValueRec;
ValueRec: PUBLIC TYPE ~ RECORD [
type: ValueType ← unassigned,
value: INTEGER ← 0,    --Only used if type=integer, or type=symbolRef
fcn: REF ANYNIL,    --Only used if type IN {unExp, binExp, trinExp}
a,b,c: Value ← NIL     --Only used if type IN {unExp, binExp, trinExp}
];
ValueType: TYPE ~ {unassigned, symbolRef, integer, unExp, binExp, trinExp};
Symbol: TYPE ~ REF SymbolRec;
SymbolRec: TYPE ~ RECORD [
name: Rope.ROPE,   --The text in the robot file
value: Value     --What it equals
];
MaxSymbolIndex: PRIVATE INT ~ 1499;  --Should be `fairly' prime
Index: TYPE ~ [0..MaxSymbolIndex);  --An index into a symbol table
SymbolTable: TYPE ~ REF SymbolTableRec;
SymbolTableRec: TYPE ~ ARRAY Index OF Symbol;
opIfThenElse: TrinOp;
opOR, opAND, opMOD, opLT, opEQ, opGT, opNE, opGE, opLE, opPlus, opMinus, opTimes, opDivide: BinOp;
opNOT, opUMinus: UnOp;
ApplyUnaryFcn: PROC [fcn: UnOp, a: Value] RETURNS [z: Value];
Apply the specified function to the given values. fcn should be a TrinOp, BinOp, or UnOp. ApplyFcn will try to resolve the value if possible by calling Eval before it returns.
ApplyBinaryFcn: PROC [fcn: BinOp, a,b: Value] RETURNS [z: Value];
Apply the specified function to the given values. fcn should be a TrinOp, BinOp, or UnOp. ApplyFcn will try to resolve the value if possible by calling Eval before it returns.
ApplyTrinaryFcn: PROC [fcn: TrinOp, a,b,c: Value] RETURNS [z: Value];
Apply the specified function to the given values. fcn should be a TrinOp, BinOp, or UnOp. ApplyFcn will try to resolve the value if possible by calling Eval before it returns.
Eval: PROC [value: Value, s: SymbolTable ← NIL] RETURNS [z: Value];
Evaluate the value. Specifically, if the value was originally defined as a function of other values that were then unassigned, but are at the time of the call to Eval, then Eval will return a Value that is an INTEGER rather than a complex type.
NewUnassignedValue: PROC RETURNS [z: Value];
Returns a new Value which is marked as being `unassigned'.
NewValueFromInteger: PROC [a: INTEGER] RETURNS [z: Value];
Returns a new Value which has the given INTEGER value.
NewSymbolTable: PROC RETURNS [s: SymbolTable];
RopeToSymbolIndex: PROC [r: Rope.ROPE, s: SymbolTable] RETURNS [index: Index];
Looks for the name in the symbol table already. If it fails to find it, it will add it.
NextIndex: PROC [in: Index] RETURNS [out: Index] ~ INLINE
For those procedures that need to enumerate the indices of a symbol table
{RETURN[IF in=0 THEN MaxSymbolIndex-1 ELSE in-1]};
ValueOfSymbol: PROC [index: Index, s: SymbolTable ← NIL] RETURNS [v: Value] ~ INLINE {
RETURN [ Eval[NEW[ValueRec ← [type: symbolRef, value: index]], s] ];
};
AssignValueToSymbol: PROC [v: Value, index: Index, s: SymbolTable] ~ INLINE {
IF s[index]=NIL THEN ERROR ELSE s[index].value ← v;
};
ResolveSymbolTable: PROC [s: SymbolTable] RETURNS [unresolved: BOOLEAN];
}.