Browse Source

Implement JUMP_IF opcodes

ApisNecros 1 year ago
parent
commit
b3daf87ad6
1 changed files with 50 additions and 2 deletions
  1. 50 2
      IntComp/Computer.js

+ 50 - 2
IntComp/Computer.js

@@ -18,10 +18,22 @@ module.exports = class Computer {
             MULTIPLY: 2,
             INPUT: 3,
             OUTPUT: 4,
+            JUMP_IF_TRUE: 5,
+            JUMP_IF_FALSE: 6,
+            LESS_THAN: 7,
+            EQUALS: 8,
             HALT: 99,
         };
 
         this.parameterMode = ComputerParameterMode.POSITION_MODE;
+
+        /**
+         * Whether the Execute loop should skip moving the pointer after running the opcode
+         *
+         * Some opcodes, such as JUMP_IF_TRUE set the stack pointer, and as such shouldn't have
+         * the Execute function move it after the opcode finishes executing.
+         */
+        this.skipNext = false;
     }
 
     /**
@@ -44,6 +56,7 @@ module.exports = class Computer {
      */
     Execute(rawOpcode) {
         let status = true;
+        this.skipNext = false;
 
         const opcode = rawOpcode % 100;
 
@@ -65,14 +78,24 @@ module.exports = class Computer {
                 this.Operation_Output();
                 break;
             }
+            case this.OPCODES.JUMP_IF_TRUE: {
+                this.Operation_JumpIf(rawOpcode, true);
+                break;
+            }
+            case this.OPCODES.JUMP_IF_FALSE: {
+                this.Operation_JumpIf(rawOpcode, false);
+                break;
+            }
             case this.OPCODES.HALT:
                 status = false;
                 break;
             default:
-                throw Error(`Opcode ${opcode} not found\nMemdump: ${JSON.stringify(this.stack.Dump())}`);
+                throw Error(`Opcode ${opcode} not found\nMemdump: ${JSON.stringify(this.stack.Dump())}\nPointer: ${this.stack.pointer}`);
         }
 
-        this.stack.Next();
+        if (!this.skipNext) {
+            this.stack.Next();
+        }
 
         return status;
     }
@@ -167,6 +190,31 @@ module.exports = class Computer {
         console.log(`OUTPUT FROM ADDRESS ${currAddress}: ${this.stack.GetAtIndex(outputPosition, ComputerParameterMode.IMMEDIATE_MODE)}`);
     }
 
+    /**
+     * Execute the Jump_If_True and Jump_If_False opcodes
+     *
+     * Jumps to a given address in memory if the value at next address is memory matches
+     * the given true/false condition.
+     *
+     * @param {number} rawOpcode The opcode in memory used to make this call
+     * @param {boolean} testCondition The value the memory value should be compared against
+     * @returns {void}
+     */
+    Operation_JumpIf(rawOpcode, testCondition) {
+        const paramMode = ComputerParameterMode.ParseParameterMode(rawOpcode, 1);
+        const jumpAddressMode = ComputerParameterMode.ParseParameterMode(rawOpcode, 2);
+
+        const param = this.stack.Next().Get(paramMode);
+        const jumpAddress = this.stack.Next().Get(jumpAddressMode);
+
+        const performJump = !!param == testCondition;
+
+        if (performJump) {
+            this.skipNext = true;
+            this.stack.SetPointerAddress(jumpAddress);
+        }
+    }
+
     /**
      * Outputs the computer's stack to the console
      * @returns {void}