<> <> <> <> <<>> DIRECTORY RobotDefs USING [MemoryMap, MemoryMapRep], RobotHardware USING [direct, fire, speed], RobotOpCodes, Rope USING [Equal, Fetch, Length, ROPE]; RobotOpCodesImpl: CEDAR PROGRAM IMPORTS RobotHardware, Rope EXPORTS RobotOpCodes ~ { OPEN RobotOpCodes; MemoryMap: TYPE ~ RobotDefs.MemoryMap; OpCodeEntry: TYPE ~ RECORD [ text: Rope.ROPE, --The actual name hash: INT, --A quick comparison proc: OpProc --The execution proc ]; OpProc: TYPE ~ PRIVATE PROC [addr, cont: INTEGER, m: REF Memory, mw: MemoryMap]; MaxOpCodes: INT ~ 32; opCodeTable: ARRAY [0..MaxOpCodes) OF OpCodeEntry; opCodesInTable: INTEGER _ 0; IsOpCode: PUBLIC PROC [r: Rope.ROPE] RETURNS [BOOLEAN] ~ { RETURN [OpCode[r]^>=0]; --OpCode returns -1 if not an opcode }; <> OpCode: PUBLIC PROC [r: Rope.ROPE] RETURNS [REF INTEGER] ~ { hash: INT _ HashRope[r]; IF opCodesInTable=0 THEN RETURN [NEW[INTEGER _ -1]]; --Implies not there FOR i:INT IN [0..opCodesInTable) DO IF hash=opCodeTable[i].hash AND Rope.Equal[r,opCodeTable[i].text] THEN RETURN[NEW[INTEGER _ i]]; ENDLOOP; RETURN [NEW[INTEGER _ -1]]; --Implies not there }; DoOpCode: PUBLIC PROC [op: INT, addr, cont: INTEGER, m: REF Memory] RETURNS [mw: MemoryMap] ~ { mw _ NEW[RobotDefs.MemoryMapRep _ ALL[FALSE]]; < a noop>> IF opCodeTable[op].proc=NIL THEN RETURN; <<>> <> opCodeTable[op].proc[addr, cont, m, mw]; <<>> IF ~mw[pc] THEN m[pc] _ m[pc]+1; --If nobody else modified it }; HashRope: PRIVATE PROC [r: Rope.ROPE] RETURNS [INT] ~ { len: INTEGER _ Rope.Length[r]; RETURN [len + CharToInt[Rope.Fetch[r,0]] + CharToInt[Rope.Fetch[r,len-1]]]; }; CharToInt: PRIVATE PROC [c: CHAR] RETURNS [i: INT] ~ { RETURN [ORD[c]]; }; Install: PRIVATE PROC [r: Rope.ROPE, proc: OpProc] ~ { opCode: OpCodeEntry _ [ text: r, hash: HashRope[r], proc: proc ]; IF opCodesInTable >= MaxOpCodes THEN ERROR; opCodeTable[opCodesInTable] _ opCode; opCodesInTable _ opCodesInTable + 1; }; ShiftLeft: PRIVATE PROC [shiftee, shifter: INTEGER] RETURNS [shifted: INTEGER] ~ { shifted _ shiftee; SELECT TRUE FROM shifter >=16 => RETURN [0]; shifter IN [0..16) => { THROUGH [1..shifter] DO shifted _ shifted*2 ENDLOOP; RETURN[shifted]; }; shifter=0 => RETURN[shiftee]; shifter IN (-16..0) => { THROUGH [shifter..-1] DO shifted _ shifted/2 ENDLOOP; RETURN[shifted]; }; shifter <=-16 => RETURN[0]; ENDCASE => ERROR; }; Set: PROC [mem: REF Memory, memWrit: MemoryMap, loc: MemoryIndex, val: INTEGER] ~ { mem[loc] _ val; memWrit[loc] _ TRUE; }; <> ac: INTEGER ~ 0; i: INTEGER ~ 1; stk: INTEGER ~ 2; pc: INTEGER ~ 3; fire: INTEGER ~ RobotHardware.fire; direct: INTEGER ~ RobotHardware.direct; speed: INTEGER ~ RobotHardware.speed; <> LDAProc: OpProc ~ {Set[m,mw,ac,cont]}; STAProc: OpProc ~ {Set[m,mw,addr,m[ac]]}; BAZProc: OpProc ~ {IF m[ac]=0 THEN Set[m,mw,pc,cont]}; BALProc: OpProc ~ {IF m[ac]<0 THEN Set[m,mw,pc,cont]}; BAGProc: OpProc ~ {IF m[ac]>0 THEN Set[m,mw,pc,cont]}; BANProc: OpProc ~ {IF m[ac]#0 THEN Set[m,mw,pc,cont]}; LDIProc: OpProc ~ {Set[m,mw,i,cont]}; STIProc: OpProc ~ {Set[m,mw,addr,m[i]]}; BIZProc: OpProc ~ {IF m[i]=0 THEN Set[m,mw,pc,cont]}; BILProc: OpProc ~ {IF m[i]<0 THEN Set[m,mw,pc,cont]}; BIGProc: OpProc ~ {IF m[i]>0 THEN Set[m,mw,pc,cont]}; BINProc: OpProc ~ {IF m[i]#0 THEN Set[m,mw,pc,cont]}; JMPProc: OpProc ~ {Set[m,mw,pc,cont]}; LUPProc: OpProc ~ {Set[m,mw,i,m[i]-1]; IF m[i]>=0 THEN Set[m,mw,pc,cont]}; ADDProc: OpProc ~ {Set[m,mw,ac,m[ac]+cont]}; SUBProc: OpProc ~ {Set[m,mw,ac,m[ac]-cont]}; MULProc: OpProc ~ {Set[m,mw,ac,m[ac]*cont]}; SHFProc: OpProc ~ {Set[m,mw,ac,ShiftLeft[m[ac],cont]]}; FRMProc: OpProc ~ {Set[m,mw,ac,cont-m[ac]]}; FIRProc: OpProc ~ {Set[m,mw,fire,cont]}; TRNProc: OpProc ~ {Set[m,mw,direct,cont]}; SPDProc: OpProc ~ {Set[m,mw,speed,cont]}; <> Install ["LDA", LDAProc]; Install ["STA", STAProc]; Install ["BAZ", BAZProc]; Install ["BAL", BALProc]; Install ["BAG", BAGProc]; Install ["BAN", BANProc]; Install ["LDI", LDIProc]; Install ["STI", STIProc]; Install ["BIZ", BIZProc]; Install ["BIL", BILProc]; Install ["BIG", BIGProc]; Install ["BIN", BINProc]; Install ["JMP", JMPProc]; Install ["LUP", LUPProc]; Install ["ADD", ADDProc]; Install ["SUB", SUBProc]; Install ["MUL", MULProc]; Install ["SHF", SHFProc]; Install ["FRM", FRMProc]; Install ["FIR", FIRProc]; Install ["TRN", TRNProc]; Install ["SPD", SPDProc]; }.