perm filename IEXPR.2[EAL,HE]1 blob
sn#676467 filedate 1982-09-27 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00004 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 {$NOMAIN Expression Interpreter }
C00023 00003 { Externally defined routines: }
C00029 00004 (* expression evaluator: evalExp *)
C00048 ENDMK
C⊗;
{$NOMAIN Expression Interpreter }
const
(* Constants from EDIT *)
maxLines = 28; (* smaller on the 11 than on the 10 *)
maxPPLines = 18;
maxBpts = 25;
maxTBpts = 20; (* max could be exceeded by huge case stmnt *)
listinglength = 2000; (* Length of Listingarray *)
type
byte = 0..255; (* doesn't really belong here, but... *)
ascii = char;
atext = text;
{ Define all the pointer types here }
vectorp = ↑vector;
transp = ↑trans;
strngp = ↑strng;
eventp = ↑event;
framep = ↑frame;
varidefp = ↑varidef;
nodep = ↑node;
pdbp = ↑pdb;
envheaderp = ↑envheader;
enventryp = ↑enventry;
environp = ↑environment;
messagep = ↑message;
cmoncbp = ↑cmoncb;
dump = ↑integer;
token = array[1..4] of integer; {Same size as a token}
cursorp = array[1..4] of integer;
(* datatype definitions *)
datatypes = (pconstype, varitype, svaltype, vectype, rottype, transtype,
frametype, eventtype, strngtype, labeltype, proctype, arraytype,
reftype, valtype, cmontype, nulltype, undeftype,
dimensiontype, mactype, macargtype, freevartype);
scalar = real;
u = (used,free);
vector = record case u of
used: (refcnt: integer; val: array [1..3] of real);
free: (next: vectorp);
end;
trans = record case u of
used: (refcnt: integer; val: array [1..3,1..4] of real);
free: (next: transp);
end;
cstring = packed array [1..10] of ascii;
c4str = packed array [1..4] of ascii;
c5str = packed array [1..5] of ascii;
c20str = packed array [1..20] of ascii;
linestr = packed array [1..130] of ascii;
strng = record
next: strngp;
ch: cstring;
end;
event = record
next: eventp; (* all events are on one big list *)
count: integer;
waitlist: pdbp;
end;
frame = record
vari: varidefp; (* back pointer to variable name & info *)
calcs: nodep; (* affixment info *)
case ftype: boolean of (* frame = true, device = false *)
true: (valid: integer; val, fdepr: transp; dcntr: integer; dev: framep);
false: (mech: integer; case sdev: boolean of
true: (sdest: real); false: (tdest,appr,depr: transp));
(* sdev = true for scalar devices, false for frames *)
end;
(* statement definitions *)
stmntypes = (progtype, blocktype, coblocktype, endtype, coendtype,
fortype, iftype, whiletype, untiltype, casetype,
calltype, returntype,
printtype, prompttype, pausetype, aborttype, assigntype,
signaltype, waittype, enabletype, disabletype, cmtype,
affixtype, unfixtype,
movetype, operatetype, opentype, closetype, centertype,
stoptype, retrytype,
requiretype, definetype, macrotype, commenttype, dimdeftype,
setbasetype, wristtype, tovaltype, declaretype, emptytype);
(* more??? *)
(* auxiliary definitions: variable, etc. *)
varidef = packed record
next,dnext: varidefp;
name: dump;
level: 0..255; (* environment level *)
offset: 0..255; (* environment offset *)
dtype: varidefp; (* to hold the dimension info *)
tbits: 0..15; (* special type bits: array = 1, proc = 2, ref = 4 & ? *)
dbits: 0..15; (* for use by debugger/interpreter *)
case vtype: datatypes of
arraytype: (a: nodep);
proctype: (p: nodep);
labeltype,
cmontype: (s: dump);
mactype: (mdef: dump);
macargtype: (marg: dump);
pconstype: (c: nodep);
dimensiontype: (dim: nodep);
end;
(* definition of the ubiquitous NODE record *)
nodetypes = (exprnode, leafnode, listnode, clistnode, colistnode, forvalnode,
deprnode, viaptnode, apprnode, destnode, durnode,
sfacnode, wobblenode, swtnode, nullingnode, wristnode, cwnode,
arrivalnode, departingnode,
ffnode, forcenode, stiffnode, gathernode, cmonnode, errornode,
calcnode, arraydefnode, bnddefnode, bndvalnode,
waitlistnode, procdefnode, tlistnode, dimnode, commentnode);
exprtypes = ( svalop, (* scalar operators *)
sltop, sleop, seqop, sgeop, sgtop, sneop, (* relations *)
notop, orop, xorop, andop, eqvop, (* logical *)
saddop, ssubop, smulop, sdivop, snegop, sabsop, (* scalar ops *)
sexpop, maxop, minop, intop, idivop, modop,
sqrtop, logop, expop, timeop, (* functions *)
sinop, cosop, tanop, asinop, acosop, atan2op, (* trig *)
vdotop, vmagnop, tmagnop,
vecop, (* vector operators *)
vmakeop, unitvop, vaddop, vsubop, crossvop, vnegop,
svmulop, vsmulop, vsdivop, tvmulop, wrtop,
tposop, taxisop,
transop, (* trans operators *)
tmakeop, torientop, ttmulop, tvaddop, tvsubop, tinvrtop,
vsaxwrop, constrop, ftofop, deproachop, fmakeop, vmkfrcop,
ioop, (* i/o operators *)
queryop, inscalarop,
specop, (* special operators *)
arefop, callop, grinchop, macroop, vmop, adcop, dacop,
badop,
addop, subop, negop, mulop, divop, absop); (* for parsing *)
leaftypes = pconstype..strngtype;
reltypes = sltop..sgtop;
forcetypes = (force,absforce,torque,abstorque,angvelocity);
node = record
next: nodep;
case ntype: nodetypes of
exprnode: (op: exprtypes; arg1, arg2, arg3: nodep; elength: integer);
leafnode: (case ltype: leaftypes of
varitype: (vari: varidefp; vid: dump);
pconstype: (cname: varidefp; pcval: nodep);
svaltype: (s: scalar; wid: integer);
vectype: (v: vectorp);
transtype: (t: transp);
strngtype: (length: integer; str: strngp) ); (* also used by commentnodes *)
listnode: (lval: nodep);
clistnode: (cval: integer; stmnt: dump; clast: nodep);
colistnode: (prev: nodep; cstmnt: dump);
forvalnode: (fvar: enventryp; fstep: scalar);
arrivalnode:(evar: varidefp);
deprnode,
apprnode,
destnode: (loc: nodep; code: dump);
viaptnode: (vlist: boolean; via,duration,velocity: nodep; vcode: dump);
durnode: (durrel: reltypes; durval: nodep);
sfacnode,
wobblenode,
swtnode: (clval: nodep);
nullingnode,
wristnode,
cwnode: (notp: boolean); (* true = nonulling/zero wrist/counter_clockwise *)
ffnode: (ff: nodep; csys, pdef: boolean); (* true = world, false = hand *)
forcenode: (ftype: forcetypes; frel: reltypes; fval, fvec, fframe: nodep);
stiffnode: (fv, mv, coc: nodep);
gathernode: (gbits: integer);
cmonnode: (cmon: dump; errhandlerp: boolean);
errornode: (eexpr: nodep);
calcnode: (rigid, frame1: boolean; other: framep; case tvarp: boolean of
false: (tval: transp); true: (tvar: enventryp) );
arraydefnode: (numdims: 1..10; bounds: nodep; combnds: boolean);
bnddefnode: (lower, upper: nodep);
bndvalnode: (lb, ub, mult: integer);
waitlistnode: (who: pdbp; when: integer);
procdefnode:(ptype: datatypes; level: 0..255;
pname, paramlist: varidefp; body: dump);
tlistnode: (tok: dump);
dimnode: (time, distance, angle, dforce: integer);
end;
(* process descriptor blocks & environment record definitions *)
queuetypes = (nullqueue,nowrunning,runqueue,inputqueue,eventqueue,sleepqueue,
forcewait,devicewait,joinwait,proccall);
pdb = packed record
nextpdb,next: pdbp; (* for list of all/active pdb's *)
level: 0..255; (* lexical level *)
mode: 0..255; (* expression/statement/sub-statement *)
priority: 0..255;
status: queuetypes; (* what are we doing *)
env: envheaderp;
spc: dump; (* current statement *)
epc: nodep; (* current expression (if any) *)
sp: nodep; (* intermediate value stack *)
cm: cmoncbp; (* if we're a cmon point to our definition *)
mech: framep; (* current device being used *)
linenum: integer; (* used by editor/debugger *)
case procp: boolean of (* true if we're a procedure *)
true: (opdb: pdbp; (* pdb to restore when procedure exits *)
pdef: nodep); (* procedure definition node *)
false: (evt: eventp; (* event to signal when process goes away *)
sdef: dump); (* first statement where process was defined *)
end;
envheader = packed record
parent: envheaderp;
env: array [0..4] of environp;
varcnt: 0..255; (* # of variables in use ??? *)
case procp: boolean of (* true if we're a procedure *)
true: (proc: nodep);
false:(block: dump);
end;
enventry = record
case etype: datatypes of
svaltype: (s: scalar);
vectype: (v: vectorp);
transtype: (t: transp);
frametype: (f: framep);
eventtype: (evt: eventp);
strngtype: (length: integer; str: strngp);
cmontype: (c: cmoncbp);
proctype: (p: nodep; penv: envheaderp);
reftype: (r: enventryp);
arraytype: (a: envheaderp; bnds: nodep);
end;
environment = record
next: environp;
vals: array [0..9] of enventryp;
end;
cmoncb = record
running, enabled: boolean; (* cmon's status *)
cmon: dump;
pdb: pdbp;
evt: eventp;
fbits: integer; (* bits for force sensing *)
oldcmon: cmoncbp; (* for debugger *)
end;
(* definition of AL-ARM messages *)
msgtypes = (initarmscmd,calibcmd,killarmscmd,wherecmd,
abortcmd,stopcmd,movehdrcmd,movesegcmd,
centercmd,operatecmd,movedonecmd,signalcmd,readjtcmd,drivecmd,
setccmd,forcesigcmd,forceoffcmd,biasoncmd,biasoffcmd,setstiffcmd,
zerowristcmd,wristcmd,gathercmd,getgathercmd,readadccmd,writedaccmd,
errorcmd,floatcmd);
errortypes = (noerror,noarmsol,timerr,durerr,toolong,useopr,nosuchdev,featna,
unkmess,srvdead,adcdead,nozind,exjtfc,paslim,nopower,badpot,devbusy,
baddev,timout,panicb);
message = record
cmd: msgtypes;
ok: boolean;
case integer of
1: (dev, bits, n: integer;
(* (dev, bits, n, evt: integer; (* for arm code version *)
evt: eventp;
dur: real;
case integer of
1: (v1,v2,v3: real);
2: (sfac,wobble,pos: real);
3: (val,angle,mag: real);
4: (max,min: real);
5: (error: errortypes));
2: (fv1,fv2,fv3,mv1,mv2,mv3: real); (* may never use these... *)
3: (t: array [1..6] of real);
end;
interr = record
case integer of
0: (i: integer);
1: (err,foo: errortypes);
end;
(* Global variables *)
var
(* From ALMAIN *)
b:boolean;
ch:ascii;
ltime: real;
(* From PARSE *)
reswords: array [0..26] of dump;
idents: array [0..26] of dump;
macrostack: array [1..10] of dump;
curmacstack: array [1..10] of varidefp;
macrodepth: integer;
curchar, maxchar, curline: integer;
curBlock,newDeclarations: dump;
curProc: varidefp;
pnode: nodep;
nodim, distancedim, timedim, angledim,
forcedim, torquedim, veldim, angveldim: varidefp;
fvstiffdim, mvstiffdim: nodep;
filedepth: integer;
curpage: integer;
sysVars,unVars: varidefp;
errcount: integer;
outerBlock: dump;
curVariable: varidefp;
curMotion: dump;
endOk,coendOk: integer;
moveLevel: integer;
curErrhandler, curCmon: dump;
endOfLine, backup, expandmacros, flushcomments, dimCheck: boolean;
semiseen, shownline: boolean;
eofError: boolean;
inMove,inCoblock: boolean;
curtoken: token;
file1,file2,file3,file4,file5: atext;
line: linestr;
(* From INTERP *)
curInt, activeInts, readQueue, allPdbs: pdbp;
curEnv, sysEnv: envheaderp;
clkQueue: nodep;
allEvents: eventp;
STLevel: integer; (* set by GO *)
etime: integer; (* used by eval *)
curtime: integer; (* Time of day, in ticks *)
stime: integer; (* used for clock queue on 10 *)
msg: messagep; (* for AL-ARM interaction *)
inputp: integer; (* current offset into inputLine array above *)
debugLevel: integer;
tSingleThreadMode: boolean;
resched, running, escapeI, singleThreadMode: boolean;
msgp: boolean; (* flag set if any messages pending *)
inputReady: boolean;
inputLine: array [1..20] of ascii;
(* From EDIT *)
lines: array [1..maxLines] of dump;
ppLines: array [1..maxPPLines] of dump;
marks: array [1..20] of integer;
cursorStack: array [1..15] of cursorp;
bpts: array [1..maxBpts] of dump;
tbpts: array [1..maxTBpts] of dump;
debugPdbs: array [0..10] of pdbp;
screenheight,dispHeight: integer;
ppBufp,oppBufp,ppOffset,ppSize,nmarks: integer;
lbufp,cursor,ocur,cursorLine,fieldnum,lineNum,findLine,pcLine: integer;
firstDline,topDline,botDline,firstLine,lastLine: integer;
freeLines,oldLines: dump;
findStmnt: dump;
nbpts,ntbpts: integer;
eCurInt: pdbp;
dProg: dump;
smartTerminal: boolean;
setUp,setExpr,setCursor,dontPrint,outFilep,newVarOk,collect: boolean;
eBackup: boolean;
eSingleThreadMode: boolean;
listing: packed array [0..listinglength] of ascii;
lbuf: array [1..160] of ascii;
ppBuf: array [1..100] of ascii;
outFile: atext;
eCurToken: token;
(* Various device & variable pointers *)
speedfactor: enventryp;
barm: framep;
(* Various constant pointers *)
xhat,yhat,zhat,nilvect: vectorp;
niltrans: transp;
bpark, ypark, gpark, rpark: transp; (* arm park positions *)
{ Externally defined routines: }
(* From ALLOC *)
procedure sendCmd; external;
procedure push (n: nodep); external;
function newNode: nodep; external;
procedure relNode(n: nodep); external;
function newEheader: envheaderp; external;
function newEnvironment: environp; external;
(* From IAUX1A *)
function getEntry (level, offset: byte): enventryp; external;
function getVar (level, offset: byte): enventryp; external;
function gtVarn (n: nodep): enventryp; external;
function getNval(n: nodep; var b: boolean): nodep; external;
function getPdb: pdbp; external;
function enterEntry (var i,j: integer; var env: environp;
envhdr: envheaderp; v: varidefp): enventryp; external;
procedure makeVar(e: enventryp; vari: varidefp; tbits: integer);external;
procedure killNode(n: nodep); external;
(* From IAUX1B *)
procedure prntPlist(n: nodep); external;
procedure sleep(whenV: integer); external;
(* Arithmetic Routines *)
function sind(d: real): real; external;
function cosd(d: real): real; external;
function tand(d: real): real; external;
function asin(x: real): real; external;
function acos(x: real): real; external;
function atan2(x,y: real): real; external;
function vdot (u,v: vectorp): scalar; external;
function vmagn (v: vectorp): scalar; external;
function vmake (a,b,c: scalar): vectorp; external;
function svmul (s: scalar; v: vectorp): vectorp; external;
function vsdiv (v: vectorp; s: scalar): vectorp; external;
function vadd (u,v: vectorp): vectorp; external;
function vsub (u,v: vectorp): vectorp; external;
function unitv (v: vectorp): vectorp; external;
function vcross (u,v: vectorp): vectorp; external;
function tvmul (t: transp; v: vectorp): vectorp; external;
function tpos (t: transp): vectorp; external;
function torient (t: transp): transp; external;
function taxis (t: transp): vectorp; external;
function tmagn (t: transp): scalar; external;
function tmake (t: transp; v: vectorp): transp; external;
function tvadd (t: transp; v: vectorp): transp; external;
function tvsub (t: transp; v: vectorp): transp; external;
function ttmul (t1,t2: transp): transp; external;
function tinvrt (t: transp): transp; external;
function vsaxwr(ax: vectorp; w: real): transp; external;
function construct(org,vx,vxy: vectorp): transp; external;
function vmkfrc(v: vectorp): transp; external;
function auxExp(s:scalar): scalar; external;
function auxLn(s:scalar): scalar; external;
(* From IAUX2A *)
procedure getReply; external;
procedure getVal (level, offset: byte); external;
(* Display-related Routines *)
procedure ppLine; external;
procedure ppOutNow; external;
procedure ppChar(ch: ascii); external;
procedure pp5(ch: c5str; length: integer); external;
procedure pp10(ch: cstring; length: integer); external;
procedure pp10L(ch: cstring; length: integer); external;
procedure pp20(ch: c20str; length: integer); external;
procedure pp20L(ch: c20str; length: integer); external;
procedure ppInt(i: integer); external;
procedure ppReal(r: real); external;
procedure ppStrng(length: integer; s: strngp); external;
(* expression evaluator: evalExp *)
(* Changed from the version that runs on the 10, since the pascal-2 compiler *)
(* couldn't handle generating all that code for one procedure. We have broken *)
(* it up into a couple smaller ones. *)
procedure evalExp; external;
procedure evalExp;
var res, n1, n2, n3: nodep; p: pdbp; i, j, tbits: integer; vfp: varidefp;
ep,epar: enventryp; envir: environp; envhdr: envheaderp; ch: ascii;
b, b1, b2, b3: boolean;
procedure doQueryOp;
begin
with curInt↑.epc↑ do
begin
b := false;
if not inputReady then
if readQueue = nil then
begin (* first time through *)
prntplist(arg2);
b := true;
end
else if (readQueue↑.priority div 10) < (curInt↑.priority div 10) then
begin (* first time through *)
prntplist(arg2);
b := true;
end
else sleep(60) (* wait a sec for other input to finish *)
else
begin
inputReady := false;
ch := inputLine[1];
if ord(ch) > 140B then ch := chr(ord(ch)-40B); (* make upper case *)
if (ch = 'Y') or (ch = 'N') then
begin
if ch = 'Y' then res↑.s := 1.0 else res↑.s := 0.0;
push(res);
end
else b := true; (* ask again *)
end;
if b then
begin
relNode(res);
pp20L('Type Y or N: ',13);
ppOutNow;
curInt↑.next := readQueue;
readQueue := curInt; (* swap us out *)
curInt↑.status := inputqueue;
curInt := nil;
inputp := 0;
resched := true;
end
end;
end {doQueryOp};
procedure doInscalarOp;
begin
with curInt↑.epc↑ do
begin
if not inputReady then
begin
if readQueue = nil then b := true
else b := (readQueue↑.priority div 10)<(curInt↑.priority div 10);
if b then
begin (* first time through *)
pp20L('Scalar please: ',15); ppOutNow;
curInt↑.next := readQueue;
readQueue := curInt; (* swap us out *)
curInt↑.status := inputqueue;
curInt := nil;
inputp := 0;
resched := true;
end
else sleep(60); (* wait a sec for other input to finish *)
relNode(res);
end
else
begin (* parse the number *)
inputReady := false;
b := true; (* assume plus *)
i := 1;
while (i <= inputp) and (inputLine[i] = ' ') do i := i + 1;
if inputLine[i] = '+' then i := i + 1
else if inputLine[i] = '-' then begin b := false; i := i + 1 end;
while (i <= inputp) and (inputLine[i] = ' ') do i := i + 1;
j := 0;
while (i <= inputp) and (* get integer part *)
('0' <= inputLine[i]) and (inputLine[i] <= '9') do
begin j := 10*j + ord(inputLine[i]) - ord('0'); i := i + 1 end;
res↑.s := j;
if inputLine[i] = '.' then
begin (* get fractional part *)
i := i + 1;
j := 10;
while (i <= inputp) and
('0' <= inputLine[i]) and (inputLine[i] <= '9') do
begin
res↑.s := res↑.s + (ord(inputLine[i]) - ord('0')) / j;
j := 10 * j;
i := i + 1;
end;
end;
if not b then res↑.s := - res↑.s;
push(res);
end;
end;
end {doInscalarOp};
procedure doCallOp;
var i,j: integer;
begin
with curInt↑.epc↑ do
begin
p := getPdb;
with p↑ do
begin
opdb := curInt;
procp := true;
status := nowrunning;
pdef := arg1↑.vari↑.p;
level := pdef↑.level;
spc := pdef↑.body; (* code to execute *)
end;
with arg1↑.vari↑ do
ep := getVar(level, offset); (* environment entry for procedure *)
envhdr := newEheader;
p↑.env := envhdr;
with envhdr↑ do
begin
parent := ep↑.penv; (* parent is env where proc defined *)
procp := true;
proc := ep↑.p;
varcnt := 0;
for j := 1 to 4 do env[j] := nil;
end;
vfp := ep↑.p↑.paramlist; (* formal parameters *)
n1 := arg2; (* actual parameters *)
envir := newEnvironment; (* always need at least one environment record *)
envir↑.next := nil;
envhdr↑.env[0] := envir;
for j := 0 to 9 do envir↑.vals[j] := nil;
i := 0;
j := -1;
while vfp <> nil do (* make parameter variables *)
begin
epar := enterEntry(i,j,envir,envhdr,vfp);
tbits := vfp↑.tbits;
if tbits = 4 then (* call by reference *)
with n1↑.lval↑ do
if ((ntype = exprnode) and (op <> arefop)) or (* expression *)
((ntype = leafnode) and (ltype <> varitype)) (* constant *)
then tbits := 0; (* change to call by value *)
makeVar(epar,vfp,tbits); (* make var's environment entry *)
with n1↑.lval↑ do (* now bind actual parameter value *)
if tbits = 5 then (* array passed by reference *)
with vari↑ do epar↑.r := getEntry(level,offset)
else if tbits = 4 then (* regular variable passed by reference *)
epar↑.r := gtVarn(n1↑.lval)
else (* need to copy value *)
begin
n2 := getNval(n1↑.lval,b);
with epar↑ do
case etype of
svaltype: s := n2↑.s;
vectype,
transtype: begin
v := n2↑.v;
v↑.refcnt := v↑.refcnt + 1;
end;
frametype: begin
f↑.val := n2↑.t;
f↑.valid := 0; (* mark us as valid *)
f↑.val↑.refcnt := f↑.val↑.refcnt + 1;
end;
strngtype: begin length := n2↑.length; str := n2↑.str end;
otherwise {do nothing};
end;
if b then killNode(n2); (* done with stack entry *)
end;
n1 := n1↑.next;
vfp := vfp↑.next;
end;
for i := j+1 to 9 do envir↑.vals[i] := nil;
curInt↑.epc := curInt↑.epc↑.next; (* advance our epc now *)
curInt↑.status := proccall;
curInt := p; (* swap to procedure now *)
end;
end {doCallOp};
begin
with curInt↑.epc↑ do
begin
if ntype = leafnode then
if ltype = varitype then with vari↑ do getVal(level, offset)
else begin (* should only get here for constants, badops & subscripts *)
if ltype = pconstype then n1 := pcval else n1 := curInt↑.epc;
res:= newNode;
with res↑ do
begin
ntype := leafnode;
ltype := n1↑.ltype;
length := n1↑.length; (* this should work for all leaftypes *)
str := n1↑.str;
end;
push(res);
end
else if ntype = exprnode then
begin
n2 := nil; b2 := false;
n3 := nil; b3 := false;
if (op < ioop) or (op = adcop) or (op = dacop) then (* not a special op *)
begin (* pop appropriate number of args off of stack *)
n1 := getNval(arg1,b1); (* all ops have at least one arg *)
if arg2 <> nil then
begin
n2 := getNval(arg2,b2);
if arg3 <> nil then
begin
n3 := getNval(arg3,b3);
end;
end
end
else begin n1 := nil; b1 := false end;
if (op < specop) or (op = adcop) then (* make sure it's not a special op *)
begin
res := newNode;
res↑.ntype := leafnode;
if (op < vecop) or (ioop < op) then res↑.ltype := svaltype
else if op < transop then res↑.ltype := vectype
else res↑.ltype := transtype;
end;
case op of (* assumes correct args on stack *)
(* relations *)
sltop: if n1↑.s < n2↑.s then res↑.s := 1.0 else res↑.s := 0.0;
sleop: if n1↑.s <= n2↑.s then res↑.s := 1.0 else res↑.s := 0.0;
seqop: if n1↑.s = n2↑.s then res↑.s := 1.0 else res↑.s := 0.0;
sgeop: if n1↑.s >= n2↑.s then res↑.s := 1.0 else res↑.s := 0.0;
sgtop: if n1↑.s > n2↑.s then res↑.s := 1.0 else res↑.s := 0.0;
sneop: if n1↑.s <> n2↑.s then res↑.s := 1.0 else res↑.s := 0.0;
(* logical *)
notop: if n1↑.s = 0.0 then res↑.s := 1.0 else res↑.s := 0.0;
orop: if (n1↑.s <> 0) or (n2↑.s <> 0) then res↑.s := 1.0 else res↑.s := 0.0;
xorop: if (n1↑.s <> 0) <> (n2↑.s <> 0) then res↑.s := 1.0 else res↑.s := 0.0;
andop: if (n1↑.s <> 0) and (n2↑.s <> 0) then res↑.s := 1.0 else res↑.s := 0.0;
eqvop: if (n1↑.s <> 0) = (n2↑.s <> 0) then res↑.s := 1.0 else res↑.s := 0.0;
(* scalar ops *)
saddop: res↑.s := n1↑.s + n2↑.s;
ssubop: res↑.s := n1↑.s - n2↑.s;
smulop: res↑.s := n1↑.s * n2↑.s;
sdivop: res↑.s := n1↑.s / n2↑.s;
snegop: res↑.s := - n1↑.s;
sabsop: res↑.s := abs(n1↑.s);
sexpop: res↑.s := auxExp(n2↑.s * auxLn(n1↑.s)); (* Use another Exp and Ln *)
maxop: if n1↑.s > n2↑.s then res↑.s := n1↑.s else res↑.s := n2↑.s;
minop: if n1↑.s < n2↑.s then res↑.s := n1↑.s else res↑.s := n2↑.s;
intop: res↑.s := round(n1↑.s);
idivop: res↑.s := round(n1↑.s) div round(n2↑.s);
modop: res↑.s := round(n1↑.s) mod round(n2↑.s);
(* functions *)
sqrtop: res↑.s := sqrt(n1↑.s);
logop: res↑.s := auxLn(n1↑.s); (* Use another Ln *)
expop: res↑.s := auxExp(n1↑.s); (* Use another Exp *)
timeop: res↑.s := time - n1↑.s; (* Time is in hours past midnight *)
(* trig *)
sinop: res↑.s := sind(n1↑.s);
cosop: res↑.s := cosd(n1↑.s);
tanop: res↑.s := tand(n1↑.s);
asinop: res↑.s := asin(n1↑.s);
acosop: res↑.s := acos(n1↑.s);
atan2op: res↑.s := atan2(n1↑.s,n2↑.s);
(* vector ops *)
vdotop: res↑.s := vdot(n1↑.v,n2↑.v);
vmagnop: res↑.s := vmagn(n1↑.v);
unitvop: res↑.v := unitv(n1↑.v);
vaddop: res↑.v := vadd(n1↑.v,n2↑.v);
vsubop: res↑.v := vsub(n1↑.v,n2↑.v);
vnegop: res↑.v := svmul(-1.0,n1↑.v);
crossvop: res↑.v := vcross(n1↑.v,n2↑.v);
vmakeop: res↑.v := vmake(n1↑.s,n2↑.s,n3↑.s);
svmulop: res↑.v := svmul(n1↑.s,n2↑.v);
vsmulop: res↑.v := svmul(n2↑.s,n1↑.v);
vsdivop: res↑.v := vsdiv(n1↑.v,n2↑.s);
tvmulop: res↑.v := tvmul(n1↑.t,n2↑.v);
wrtop: res↑.v := tvmul(torient(n2↑.t),n1↑.v);
(* trans ops *)
tposop: res↑.v := tpos(n1↑.t);
taxisop: res↑.v := taxis(n1↑.t);
tmagnop: res↑.s := tmagn(n1↑.t);
fmakeop,
tmakeop: res↑.t := tmake(n1↑.t,n2↑.v);
torientop: res↑.t := torient(n1↑.t);
ttmulop: res↑.t := ttmul(n1↑.t,n2↑.t);
tvaddop: res↑.t := tvadd(n1↑.t,n2↑.v);
tvsubop: res↑.t := tvsub(n1↑.t,n2↑.v);
tinvrtop: res↑.t := tinvrt(n1↑.t);
vsaxwrop: res↑.t := vsaxwr(n1↑.v,n2↑.s);
constrop: res↑.t := construct(n1↑.v,n2↑.v,n3↑.v);
ftofop: res↑.t := ttmul(tinvrt(n1↑.t),n2↑.t);
vmkfrcop: res↑.t := vmkfrc(n1↑.v);
(* input ops *)
queryop: doQueryOp;
inscalarop: doInscalarOp;
vmop: ; (* Vision module: not yet implemented *)
adcop: with msg↑ do
begin
cmd := readadccmd;
n := round(n1↑.s); (* get channel # *)
if (n < 0) or (63 < n) then (* bad channel # *)
begin
pp20L('A/D channel out of r',20); pp20('ange - using chan 0 ',19);
ppLine;
n := 0;
end;
getReply; (* have ARM servo read it in *)
res↑.s := val; (* store result away *)
end;
dacop: with msg↑ do
begin
cmd := writedaccmd;
n := round(n1↑.s); (* get channel # *)
if (n < 1) or (4 < n) then (* bad channel # *)
begin
pp20L('D/A channel out of r',20); pp20('ange - using chan 1 ',19);
ppLine;
n := 1;
end;
val := n2↑.s; (* & magnitude *)
sendCmd; (* have ARM servo write it out *)
end;
(* special *)
arefop: with arg1↑.vari↑ do getVal(level,offset); (* should never get here *)
callop: doCallOp;
badop: ;
otherwise {do nothing};
end;
if op < ioop then push(res); (* save result on stack *)
if b1 then relNode(n1); (* release nodes when done with them *)
if b2 then relNode(n2);
if b3 then relNode(n3);
end
else if ntype <> listnode then
begin (* **** error - bad node **** *)
pp20L('Error in Eval - bad ',20); pp10('node type ',9); ppLine;
(* code to recover??? *)
end;
end;
if curInt <> nil then (* in case we're now waiting for input *)
with curInt↑ do (* advance pointer to next node to be evaluated *)
if epc <> nil then epc := epc↑.next;
end;