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 ANY ← NIL, --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];
}.