|
|
@ -40,41 +40,46 @@ public class Interpreter { |
|
|
|
static long accumulator; |
|
|
|
static long accumulator; |
|
|
|
|
|
|
|
|
|
|
|
static int content(int r) { |
|
|
|
static int content(int r) { |
|
|
|
|
|
|
|
var register = Register.values()[r]; |
|
|
|
|
|
|
|
return content(register); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int content(Register r) { |
|
|
|
// Returns the current content of register r,
|
|
|
|
// Returns the current content of register r,
|
|
|
|
// even if r is one of the pseudo-registers L1..L6.
|
|
|
|
// even if r is one of the pseudo-registers L1..L6.
|
|
|
|
|
|
|
|
|
|
|
|
switch (r) { |
|
|
|
switch (r) { |
|
|
|
case Machine.CBr: |
|
|
|
case CB: |
|
|
|
return CB; |
|
|
|
return CB; |
|
|
|
case Machine.CTr: |
|
|
|
case CT: |
|
|
|
return CT; |
|
|
|
return CT; |
|
|
|
case Machine.PBr: |
|
|
|
case PB: |
|
|
|
return Machine.PB; |
|
|
|
return Machine.PB; |
|
|
|
case Machine.PTr: |
|
|
|
case PT: |
|
|
|
return Machine.PT; |
|
|
|
return Machine.PT; |
|
|
|
case Machine.SBr: |
|
|
|
case SB: |
|
|
|
return SB; |
|
|
|
return SB; |
|
|
|
case Machine.STr: |
|
|
|
case ST: |
|
|
|
return ST; |
|
|
|
return ST; |
|
|
|
case Machine.HBr: |
|
|
|
case HB: |
|
|
|
return HB; |
|
|
|
return HB; |
|
|
|
case Machine.HTr: |
|
|
|
case HT: |
|
|
|
return HT; |
|
|
|
return HT; |
|
|
|
case Machine.LBr: |
|
|
|
case LB: |
|
|
|
return LB; |
|
|
|
return LB; |
|
|
|
case Machine.L1r: |
|
|
|
case L1: |
|
|
|
return data[LB]; |
|
|
|
return data[LB]; |
|
|
|
case Machine.L2r: |
|
|
|
case L2: |
|
|
|
return data[data[LB]]; |
|
|
|
return data[data[LB]]; |
|
|
|
case Machine.L3r: |
|
|
|
case L3: |
|
|
|
return data[data[data[LB]]]; |
|
|
|
return data[data[data[LB]]]; |
|
|
|
case Machine.L4r: |
|
|
|
case L4: |
|
|
|
return data[data[data[data[LB]]]]; |
|
|
|
return data[data[data[data[LB]]]]; |
|
|
|
case Machine.L5r: |
|
|
|
case L5: |
|
|
|
return data[data[data[data[data[LB]]]]]; |
|
|
|
return data[data[data[data[data[LB]]]]]; |
|
|
|
case Machine.L6r: |
|
|
|
case L6: |
|
|
|
return data[data[data[data[data[data[LB]]]]]]; |
|
|
|
return data[data[data[data[data[data[LB]]]]]]; |
|
|
|
case Machine.CPr: |
|
|
|
case CP: |
|
|
|
return CP; |
|
|
|
return CP; |
|
|
|
default: |
|
|
|
default: |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
@ -85,7 +90,6 @@ public class Interpreter { |
|
|
|
|
|
|
|
|
|
|
|
static void dump() { |
|
|
|
static void dump() { |
|
|
|
// Writes a summary of the machine state.
|
|
|
|
// Writes a summary of the machine state.
|
|
|
|
int addr, staticLink, dynamicLink, localRegNum; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
System.out.println(""); |
|
|
|
System.out.println(""); |
|
|
|
System.out.println("State of data store and registers:"); |
|
|
|
System.out.println("State of data store and registers:"); |
|
|
@ -95,7 +99,7 @@ public class Interpreter { |
|
|
|
else { |
|
|
|
else { |
|
|
|
System.out.println(" HB-->"); |
|
|
|
System.out.println(" HB-->"); |
|
|
|
System.out.println(" |--------|"); |
|
|
|
System.out.println(" |--------|"); |
|
|
|
for (addr = HB - 1; addr >= HT; addr--) { |
|
|
|
for (var addr = HB - 1; addr >= HT; addr--) { |
|
|
|
System.out.print(addr + ":"); |
|
|
|
System.out.print(addr + ":"); |
|
|
|
if (addr == HT) |
|
|
|
if (addr == HT) |
|
|
|
System.out.print(" HT-->"); |
|
|
|
System.out.print(" HT-->"); |
|
|
@ -110,41 +114,43 @@ public class Interpreter { |
|
|
|
if (ST == SB) |
|
|
|
if (ST == SB) |
|
|
|
System.out.println(" |--------| (stack is empty)"); |
|
|
|
System.out.println(" |--------| (stack is empty)"); |
|
|
|
else { |
|
|
|
else { |
|
|
|
dynamicLink = LB; |
|
|
|
var dynamicLink = LB; |
|
|
|
staticLink = LB; |
|
|
|
var staticLink = LB; |
|
|
|
localRegNum = Machine.LBr; |
|
|
|
var localRegNum = Register.LB; |
|
|
|
System.out.println(" ST--> |////////|"); |
|
|
|
System.out.println(" ST--> |////////|"); |
|
|
|
System.out.println(" |--------|"); |
|
|
|
System.out.println(" |--------|"); |
|
|
|
for (addr = ST - 1; addr >= SB; addr--) { |
|
|
|
for (var addr = ST - 1; addr >= SB; addr--) { |
|
|
|
System.out.print(addr + ":"); |
|
|
|
System.out.print(addr + ":"); |
|
|
|
if (addr == SB) |
|
|
|
if (addr == SB) |
|
|
|
System.out.print(" SB-->"); |
|
|
|
System.out.print(" SB-->"); |
|
|
|
else if (addr == staticLink) { |
|
|
|
else if (addr == staticLink) { |
|
|
|
switch (localRegNum) { |
|
|
|
switch (localRegNum) { |
|
|
|
case Machine.LBr: |
|
|
|
case LB: |
|
|
|
System.out.print(" LB-->"); |
|
|
|
System.out.print(" LB-->"); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.L1r: |
|
|
|
case L1: |
|
|
|
System.out.print(" L1-->"); |
|
|
|
System.out.print(" L1-->"); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.L2r: |
|
|
|
case L2: |
|
|
|
System.out.print(" L2-->"); |
|
|
|
System.out.print(" L2-->"); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.L3r: |
|
|
|
case L3: |
|
|
|
System.out.print(" L3-->"); |
|
|
|
System.out.print(" L3-->"); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.L4r: |
|
|
|
case L4: |
|
|
|
System.out.print(" L4-->"); |
|
|
|
System.out.print(" L4-->"); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.L5r: |
|
|
|
case L5: |
|
|
|
System.out.print(" L5-->"); |
|
|
|
System.out.print(" L5-->"); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.L6r: |
|
|
|
case L6: |
|
|
|
System.out.print(" L6-->"); |
|
|
|
System.out.print(" L6-->"); |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
staticLink = data[addr]; |
|
|
|
staticLink = data[addr]; |
|
|
|
localRegNum = localRegNum + 1; |
|
|
|
localRegNum = Register.values()[localRegNum.ordinal() + 1]; |
|
|
|
} else |
|
|
|
} else |
|
|
|
System.out.print(" "); |
|
|
|
System.out.print(" "); |
|
|
|
if ((addr == dynamicLink) && (dynamicLink != SB)) |
|
|
|
if ((addr == dynamicLink) && (dynamicLink != SB)) |
|
|
@ -277,45 +283,46 @@ public class Interpreter { |
|
|
|
int addr, size; |
|
|
|
int addr, size; |
|
|
|
char ch; |
|
|
|
char ch; |
|
|
|
|
|
|
|
|
|
|
|
switch (primitiveDisplacement) { |
|
|
|
var primitive = Primitive.values()[primitiveDisplacement]; |
|
|
|
case Machine.idDisplacement: |
|
|
|
switch (primitive) { |
|
|
|
|
|
|
|
case ID: |
|
|
|
break; // nothing to be done
|
|
|
|
break; // nothing to be done
|
|
|
|
case Machine.notDisplacement: |
|
|
|
case NOT: |
|
|
|
data[ST - 1] = toInt(!isTrue(data[ST - 1])); |
|
|
|
data[ST - 1] = toInt(!isTrue(data[ST - 1])); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.andDisplacement: |
|
|
|
case AND: |
|
|
|
ST = ST - 1; |
|
|
|
ST = ST - 1; |
|
|
|
data[ST - 1] = toInt(isTrue(data[ST - 1]) & isTrue(data[ST])); |
|
|
|
data[ST - 1] = toInt(isTrue(data[ST - 1]) & isTrue(data[ST])); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.orDisplacement: |
|
|
|
case OR: |
|
|
|
ST = ST - 1; |
|
|
|
ST = ST - 1; |
|
|
|
data[ST - 1] = toInt(isTrue(data[ST - 1]) | isTrue(data[ST])); |
|
|
|
data[ST - 1] = toInt(isTrue(data[ST - 1]) | isTrue(data[ST])); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.succDisplacement: |
|
|
|
case SUCC: |
|
|
|
data[ST - 1] = overflowChecked(data[ST - 1] + 1); |
|
|
|
data[ST - 1] = overflowChecked(data[ST - 1] + 1); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.predDisplacement: |
|
|
|
case PRED: |
|
|
|
data[ST - 1] = overflowChecked(data[ST - 1] - 1); |
|
|
|
data[ST - 1] = overflowChecked(data[ST - 1] - 1); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.negDisplacement: |
|
|
|
case NEG: |
|
|
|
data[ST - 1] = -data[ST - 1]; |
|
|
|
data[ST - 1] = -data[ST - 1]; |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.addDisplacement: |
|
|
|
case ADD: |
|
|
|
ST = ST - 1; |
|
|
|
ST = ST - 1; |
|
|
|
accumulator = data[ST - 1]; |
|
|
|
accumulator = data[ST - 1]; |
|
|
|
data[ST - 1] = overflowChecked(accumulator + data[ST]); |
|
|
|
data[ST - 1] = overflowChecked(accumulator + data[ST]); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.subDisplacement: |
|
|
|
case SUB: |
|
|
|
ST = ST - 1; |
|
|
|
ST = ST - 1; |
|
|
|
accumulator = data[ST - 1]; |
|
|
|
accumulator = data[ST - 1]; |
|
|
|
data[ST - 1] = overflowChecked(accumulator - data[ST]); |
|
|
|
data[ST - 1] = overflowChecked(accumulator - data[ST]); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.multDisplacement: |
|
|
|
case MULT: |
|
|
|
ST = ST - 1; |
|
|
|
ST = ST - 1; |
|
|
|
accumulator = data[ST - 1]; |
|
|
|
accumulator = data[ST - 1]; |
|
|
|
data[ST - 1] = overflowChecked(accumulator * data[ST]); |
|
|
|
data[ST - 1] = overflowChecked(accumulator * data[ST]); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.divDisplacement: |
|
|
|
case DIV: |
|
|
|
ST = ST - 1; |
|
|
|
ST = ST - 1; |
|
|
|
accumulator = data[ST - 1]; |
|
|
|
accumulator = data[ST - 1]; |
|
|
|
if (data[ST] != 0) |
|
|
|
if (data[ST] != 0) |
|
|
@ -323,7 +330,7 @@ public class Interpreter { |
|
|
|
else |
|
|
|
else |
|
|
|
status = failedZeroDivide; |
|
|
|
status = failedZeroDivide; |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.modDisplacement: |
|
|
|
case MOD: |
|
|
|
ST = ST - 1; |
|
|
|
ST = ST - 1; |
|
|
|
accumulator = data[ST - 1]; |
|
|
|
accumulator = data[ST - 1]; |
|
|
|
if (data[ST] != 0) |
|
|
|
if (data[ST] != 0) |
|
|
@ -331,41 +338,41 @@ public class Interpreter { |
|
|
|
else |
|
|
|
else |
|
|
|
status = failedZeroDivide; |
|
|
|
status = failedZeroDivide; |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.ltDisplacement: |
|
|
|
case LT: |
|
|
|
ST = ST - 1; |
|
|
|
ST = ST - 1; |
|
|
|
data[ST - 1] = toInt(data[ST - 1] < data[ST]); |
|
|
|
data[ST - 1] = toInt(data[ST - 1] < data[ST]); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.leDisplacement: |
|
|
|
case LE: |
|
|
|
ST = ST - 1; |
|
|
|
ST = ST - 1; |
|
|
|
data[ST - 1] = toInt(data[ST - 1] <= data[ST]); |
|
|
|
data[ST - 1] = toInt(data[ST - 1] <= data[ST]); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.geDisplacement: |
|
|
|
case GE: |
|
|
|
ST = ST - 1; |
|
|
|
ST = ST - 1; |
|
|
|
data[ST - 1] = toInt(data[ST - 1] >= data[ST]); |
|
|
|
data[ST - 1] = toInt(data[ST - 1] >= data[ST]); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.gtDisplacement: |
|
|
|
case GT: |
|
|
|
ST = ST - 1; |
|
|
|
ST = ST - 1; |
|
|
|
data[ST - 1] = toInt(data[ST - 1] > data[ST]); |
|
|
|
data[ST - 1] = toInt(data[ST - 1] > data[ST]); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.eqDisplacement: |
|
|
|
case EQ: |
|
|
|
size = data[ST - 1]; // size of each comparand
|
|
|
|
size = data[ST - 1]; // size of each comparand
|
|
|
|
ST = ST - 2 * size; |
|
|
|
ST = ST - 2 * size; |
|
|
|
data[ST - 1] = toInt(equal(size, ST - 1, ST - 1 + size)); |
|
|
|
data[ST - 1] = toInt(equal(size, ST - 1, ST - 1 + size)); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.neDisplacement: |
|
|
|
case NE: |
|
|
|
size = data[ST - 1]; // size of each comparand
|
|
|
|
size = data[ST - 1]; // size of each comparand
|
|
|
|
ST = ST - 2 * size; |
|
|
|
ST = ST - 2 * size; |
|
|
|
data[ST - 1] = toInt(!equal(size, ST - 1, ST - 1 + size)); |
|
|
|
data[ST - 1] = toInt(!equal(size, ST - 1, ST - 1 + size)); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.eolDisplacement: |
|
|
|
case EOL: |
|
|
|
data[ST] = toInt(currentChar == '\n'); |
|
|
|
data[ST] = toInt(currentChar == '\n'); |
|
|
|
ST = ST + 1; |
|
|
|
ST = ST + 1; |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.eofDisplacement: |
|
|
|
case EOF: |
|
|
|
data[ST] = toInt(currentChar == -1); |
|
|
|
data[ST] = toInt(currentChar == -1); |
|
|
|
ST = ST + 1; |
|
|
|
ST = ST + 1; |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.getDisplacement: |
|
|
|
case GET: |
|
|
|
ST = ST - 1; |
|
|
|
ST = ST - 1; |
|
|
|
addr = data[ST]; |
|
|
|
addr = data[ST]; |
|
|
|
try { |
|
|
|
try { |
|
|
@ -375,12 +382,12 @@ public class Interpreter { |
|
|
|
} |
|
|
|
} |
|
|
|
data[addr] = currentChar; |
|
|
|
data[addr] = currentChar; |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.putDisplacement: |
|
|
|
case PUT: |
|
|
|
ST = ST - 1; |
|
|
|
ST = ST - 1; |
|
|
|
ch = (char) data[ST]; |
|
|
|
ch = (char) data[ST]; |
|
|
|
System.out.print(ch); |
|
|
|
System.out.print(ch); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.geteolDisplacement: |
|
|
|
case GETEOL: |
|
|
|
try { |
|
|
|
try { |
|
|
|
while ((currentChar = System.in.read()) != '\n') |
|
|
|
while ((currentChar = System.in.read()) != '\n') |
|
|
|
; |
|
|
|
; |
|
|
@ -388,10 +395,10 @@ public class Interpreter { |
|
|
|
status = failedIOError; |
|
|
|
status = failedIOError; |
|
|
|
} |
|
|
|
} |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.puteolDisplacement: |
|
|
|
case PUTEOL: |
|
|
|
System.out.println(""); |
|
|
|
System.out.println(""); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.getintDisplacement: |
|
|
|
case GETINT: |
|
|
|
ST = ST - 1; |
|
|
|
ST = ST - 1; |
|
|
|
addr = data[ST]; |
|
|
|
addr = data[ST]; |
|
|
|
try { |
|
|
|
try { |
|
|
@ -401,18 +408,18 @@ public class Interpreter { |
|
|
|
} |
|
|
|
} |
|
|
|
data[addr] = (int) accumulator; |
|
|
|
data[addr] = (int) accumulator; |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.putintDisplacement: |
|
|
|
case PUTINT: |
|
|
|
ST = ST - 1; |
|
|
|
ST = ST - 1; |
|
|
|
accumulator = data[ST]; |
|
|
|
accumulator = data[ST]; |
|
|
|
System.out.print(accumulator); |
|
|
|
System.out.print(accumulator); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.newDisplacement: |
|
|
|
case NEW: |
|
|
|
size = data[ST - 1]; |
|
|
|
size = data[ST - 1]; |
|
|
|
checkSpace(size); |
|
|
|
checkSpace(size); |
|
|
|
HT = HT - size; |
|
|
|
HT = HT - size; |
|
|
|
data[ST - 1] = HT; |
|
|
|
data[ST - 1] = HT; |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.disposeDisplacement: |
|
|
|
case DISPOSE: |
|
|
|
ST = ST - 1; // no action taken at present
|
|
|
|
ST = ST - 1; // no action taken at present
|
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
@ -422,7 +429,6 @@ public class Interpreter { |
|
|
|
// Runs the program in code store.
|
|
|
|
// Runs the program in code store.
|
|
|
|
|
|
|
|
|
|
|
|
Instruction currentInstr; |
|
|
|
Instruction currentInstr; |
|
|
|
int op, r, n, d, addr, index; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Initialize registers ...
|
|
|
|
// Initialize registers ...
|
|
|
|
ST = SB; |
|
|
|
ST = SB; |
|
|
@ -434,65 +440,67 @@ public class Interpreter { |
|
|
|
// Fetch instruction ...
|
|
|
|
// Fetch instruction ...
|
|
|
|
currentInstr = Machine.code[CP]; |
|
|
|
currentInstr = Machine.code[CP]; |
|
|
|
// Decode instruction ...
|
|
|
|
// Decode instruction ...
|
|
|
|
op = currentInstr.op; |
|
|
|
var op = currentInstr.opCode; |
|
|
|
r = currentInstr.r; |
|
|
|
var r = currentInstr.register; |
|
|
|
n = currentInstr.n; |
|
|
|
var n = currentInstr.length; |
|
|
|
d = currentInstr.d; |
|
|
|
var d = currentInstr.operand; |
|
|
|
|
|
|
|
int addr; |
|
|
|
|
|
|
|
|
|
|
|
// Execute instruction ...
|
|
|
|
// Execute instruction ...
|
|
|
|
switch (op) { |
|
|
|
switch (op) { |
|
|
|
case Machine.LOADop: |
|
|
|
case LOAD: |
|
|
|
addr = d + content(r); |
|
|
|
addr = d + content(r); |
|
|
|
checkSpace(n); |
|
|
|
checkSpace(n); |
|
|
|
for (index = 0; index < n; index++) |
|
|
|
for (var index = 0; index < n; index++) |
|
|
|
data[ST + index] = data[addr + index]; |
|
|
|
data[ST + index] = data[addr + index]; |
|
|
|
ST = ST + n; |
|
|
|
ST = ST + n; |
|
|
|
CP = CP + 1; |
|
|
|
CP = CP + 1; |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.LOADAop: |
|
|
|
case LOADA: |
|
|
|
addr = d + content(r); |
|
|
|
addr = d + content(r); |
|
|
|
checkSpace(1); |
|
|
|
checkSpace(1); |
|
|
|
data[ST] = addr; |
|
|
|
data[ST] = addr; |
|
|
|
ST = ST + 1; |
|
|
|
ST = ST + 1; |
|
|
|
CP = CP + 1; |
|
|
|
CP = CP + 1; |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.LOADIop: |
|
|
|
case LOADI: |
|
|
|
ST = ST - 1; |
|
|
|
ST = ST - 1; |
|
|
|
addr = data[ST]; |
|
|
|
addr = data[ST]; |
|
|
|
checkSpace(n); |
|
|
|
checkSpace(n); |
|
|
|
for (index = 0; index < n; index++) |
|
|
|
for (var index = 0; index < n; index++) |
|
|
|
data[ST + index] = data[addr + index]; |
|
|
|
data[ST + index] = data[addr + index]; |
|
|
|
ST = ST + n; |
|
|
|
ST = ST + n; |
|
|
|
CP = CP + 1; |
|
|
|
CP = CP + 1; |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.LOADLop: |
|
|
|
case LOADL: |
|
|
|
checkSpace(1); |
|
|
|
checkSpace(1); |
|
|
|
data[ST] = d; |
|
|
|
data[ST] = d; |
|
|
|
ST = ST + 1; |
|
|
|
ST = ST + 1; |
|
|
|
CP = CP + 1; |
|
|
|
CP = CP + 1; |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.STOREop: |
|
|
|
case STORE: |
|
|
|
addr = d + content(r); |
|
|
|
addr = d + content(r); |
|
|
|
ST = ST - n; |
|
|
|
ST = ST - n; |
|
|
|
for (index = 0; index < n; index++) |
|
|
|
for (var index = 0; index < n; index++) |
|
|
|
data[addr + index] = data[ST + index]; |
|
|
|
data[addr + index] = data[ST + index]; |
|
|
|
CP = CP + 1; |
|
|
|
CP = CP + 1; |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.STOREIop: |
|
|
|
case STOREI: |
|
|
|
ST = ST - 1; |
|
|
|
ST = ST - 1; |
|
|
|
addr = data[ST]; |
|
|
|
addr = data[ST]; |
|
|
|
ST = ST - n; |
|
|
|
ST = ST - n; |
|
|
|
for (index = 0; index < n; index++) |
|
|
|
for (var index = 0; index < n; index++) |
|
|
|
data[addr + index] = data[ST + index]; |
|
|
|
data[addr + index] = data[ST + index]; |
|
|
|
CP = CP + 1; |
|
|
|
CP = CP + 1; |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.CALLop: |
|
|
|
case CALL: |
|
|
|
addr = d + content(r); |
|
|
|
addr = d + content(r); |
|
|
|
if (addr >= Machine.PB) { |
|
|
|
if (addr >= Machine.PB) { |
|
|
|
callPrimitive(addr - Machine.PB); |
|
|
|
callPrimitive(addr - Machine.PB); |
|
|
|
CP = CP + 1; |
|
|
|
CP = CP + 1; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
checkSpace(3); |
|
|
|
checkSpace(3); |
|
|
|
if ((0 <= n) && (n <= 15)) |
|
|
|
if (0 <= n && n <= 15) |
|
|
|
data[ST] = content(n); // static link
|
|
|
|
data[ST] = content(n); // static link
|
|
|
|
else |
|
|
|
else |
|
|
|
status = failedInvalidInstruction; |
|
|
|
status = failedInvalidInstruction; |
|
|
@ -503,7 +511,7 @@ public class Interpreter { |
|
|
|
CP = addr; |
|
|
|
CP = addr; |
|
|
|
} |
|
|
|
} |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.CALLIop: |
|
|
|
case CALLI: |
|
|
|
ST = ST - 2; |
|
|
|
ST = ST - 2; |
|
|
|
addr = data[ST + 1]; |
|
|
|
addr = data[ST + 1]; |
|
|
|
if (addr >= Machine.PB) { |
|
|
|
if (addr >= Machine.PB) { |
|
|
@ -518,43 +526,43 @@ public class Interpreter { |
|
|
|
CP = addr; |
|
|
|
CP = addr; |
|
|
|
} |
|
|
|
} |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.RETURNop: |
|
|
|
case RETURN: |
|
|
|
addr = LB - d; |
|
|
|
addr = LB - d; |
|
|
|
CP = data[LB + 2]; |
|
|
|
CP = data[LB + 2]; |
|
|
|
LB = data[LB + 1]; |
|
|
|
LB = data[LB + 1]; |
|
|
|
ST = ST - n; |
|
|
|
ST = ST - n; |
|
|
|
for (index = 0; index < n; index++) |
|
|
|
for (var index = 0; index < n; index++) |
|
|
|
data[addr + index] = data[ST + index]; |
|
|
|
data[addr + index] = data[ST + index]; |
|
|
|
ST = addr + n; |
|
|
|
ST = addr + n; |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.PUSHop: |
|
|
|
case PUSH: |
|
|
|
checkSpace(d); |
|
|
|
checkSpace(d); |
|
|
|
ST = ST + d; |
|
|
|
ST = ST + d; |
|
|
|
CP = CP + 1; |
|
|
|
CP = CP + 1; |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.POPop: |
|
|
|
case POP: |
|
|
|
addr = ST - n - d; |
|
|
|
addr = ST - n - d; |
|
|
|
ST = ST - n; |
|
|
|
ST = ST - n; |
|
|
|
for (index = 0; index < n; index++) |
|
|
|
for (var index = 0; index < n; index++) |
|
|
|
data[addr + index] = data[ST + index]; |
|
|
|
data[addr + index] = data[ST + index]; |
|
|
|
ST = addr + n; |
|
|
|
ST = addr + n; |
|
|
|
CP = CP + 1; |
|
|
|
CP = CP + 1; |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.JUMPop: |
|
|
|
case JUMP: |
|
|
|
CP = d + content(r); |
|
|
|
CP = d + content(r); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.JUMPIop: |
|
|
|
case JUMPI: |
|
|
|
ST = ST - 1; |
|
|
|
ST = ST - 1; |
|
|
|
CP = data[ST]; |
|
|
|
CP = data[ST]; |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.JUMPIFop: |
|
|
|
case JUMPIF: |
|
|
|
ST = ST - 1; |
|
|
|
ST = ST - 1; |
|
|
|
if (data[ST] == n) |
|
|
|
if (data[ST] == n) |
|
|
|
CP = d + content(r); |
|
|
|
CP = d + content(r); |
|
|
|
else |
|
|
|
else |
|
|
|
CP = CP + 1; |
|
|
|
CP = CP + 1; |
|
|
|
break; |
|
|
|
break; |
|
|
|
case Machine.HALTop: |
|
|
|
case HALT: |
|
|
|
status = halted; |
|
|
|
status = halted; |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|