diff --git a/src/ui.ts b/src/ui.ts index 45fe704..30657d5 100644 --- a/src/ui.ts +++ b/src/ui.ts @@ -18,11 +18,11 @@ function menuRun(): void { function menuClear(): void { SpreadsheetApp.getActiveSpreadsheet() .getSheetByName("Run") - .getRange("A3:H") + .getRange("A3:F") .clearContent(); SpreadsheetApp.getActiveSpreadsheet() .getSheetByName("Run") - .getRange("D2:H2") + .getRange("D2:F") .clearContent(); SpreadsheetApp.getActiveSpreadsheet() .getSheetByName("Run") diff --git a/src/vm.ts b/src/vm.ts index 1628ad4..1d48f3d 100644 --- a/src/vm.ts +++ b/src/vm.ts @@ -141,12 +141,32 @@ function step(n: number = 0): void { // opcode(dst, res) switch (instruction.Opcode) { case Opcodes.Call: - runSheet - .getRange(op0Addr) - .setValue(registers[Registers.PC] + size(instruction)); - runSheet.getRange(dstAddr).setValue(registers[Registers.FP]); + let validCallOp0Value: number | string = + registers[Registers.PC] + size(instruction); + let validCallDstValue: number | string = registers[Registers.FP]; + if (op0Value == "") { + runSheet.getRange(op0Addr).setValue(validCallOp0Value); + } + if (dstValue == "") { + runSheet.getRange(dstAddr).setValue(validCallDstValue); + } + op0Value = + instruction.Op0Register === Registers.PC + ? op0Addr + : runSheet.getRange(op0Addr).getValue(); + dstValue = + instruction.DstRegister === Registers.PC + ? dstAddr + : runSheet.getRange(dstAddr).getValue(); + if ( + Number(dstValue) !== Number(validCallDstValue) || + Number(op0Value) !== Number(validCallOp0Value) + ) { + throw new AssertEqError(); + } break; case Opcodes.AssertEq: + let validAssertEqDstValue: number | string; switch (instruction.ResLogic) { case ResLogics.Add: if (op0Value === "") { @@ -164,6 +184,7 @@ function step(n: number = 0): void { .getRange(dstAddr) .setValue(BigInt(op0Value) + BigInt(op1Value)); } + validAssertEqDstValue = Number(BigInt(op0Value) + BigInt(op1Value)); break; case ResLogics.Mul: if (op0Value === "") { @@ -181,6 +202,7 @@ function step(n: number = 0): void { .getRange(dstAddr) .setValue(BigInt(op0Value) * BigInt(op1Value)); } + validAssertEqDstValue = Number(BigInt(op0Value) * BigInt(op1Value)); break; case ResLogics.Op1: if (op1Value === "") { @@ -189,8 +211,17 @@ function step(n: number = 0): void { if (dstValue === "") { runSheet.getRange(dstAddr).setValue(BigInt(op1Value)); } + validAssertEqDstValue = Number(BigInt(op1Value)); break; } + dstValue = + instruction.DstRegister === Registers.PC + ? dstAddr + : runSheet.getRange(dstAddr).getValue(); + if (Number(dstValue) !== Number(validAssertEqDstValue)) { + throw new AssertEqError(); + } + break; } op0Value =