Hone logo
Hone
Problems

Stack-Based Virtual Machine in JavaScript

This challenge asks you to build a simplified stack-based virtual machine (VM) in JavaScript. Stack-based VMs operate by pushing values onto a stack and executing instructions that manipulate those values. This exercise will help you understand how VMs work at a fundamental level and practice your JavaScript coding skills.

Problem Description

You are to implement a basic stack-based VM that can execute a set of predefined instructions. The VM will receive a program as an array of instructions, where each instruction is a string. The instructions will operate on a stack, pushing and popping values as needed. Your VM should interpret these instructions and produce a final result, which will be the value remaining on the stack after all instructions have been executed.

Key Requirements:

  • Stack: Implement a stack data structure to store values.
  • Instruction Set: Support the following instructions:
    • PUSH <value>: Pushes the numerical value <value> onto the stack.
    • ADD: Pops the top two values from the stack, adds them, and pushes the result back onto the stack.
    • SUB: Pops the top two values from the stack, subtracts the second from the first, and pushes the result back onto the stack.
    • MUL: Pops the top two values from the stack, multiplies them, and pushes the result back onto the stack.
    • DIV: Pops the top two values from the stack, divides the first by the second, and pushes the result back onto the stack. Handle division by zero gracefully (see Edge Cases).
    • PRINT: Prints the top value of the stack to the console (for debugging purposes - this value should not be popped).
    • HALT: Stops execution of the program.
  • Error Handling: Handle invalid instructions and insufficient values on the stack gracefully. Throw an Error with a descriptive message in these cases.
  • Execution: Iterate through the instruction array, interpreting and executing each instruction.

Expected Behavior:

The VM should execute the provided program and leave a single value on the stack after the HALT instruction is encountered. This final value is the result of the program. If the program ends without a single value on the stack, or if an error occurs, the VM should throw an error.

Edge Cases to Consider:

  • Division by Zero: If a DIV instruction is encountered and the second value popped from the stack is zero, throw an Error with the message "Division by zero".
  • Insufficient Values: If an arithmetic instruction (ADD, SUB, MUL, DIV) is encountered and there are fewer than two values on the stack, throw an Error with the message "Insufficient values on stack".
  • Invalid Instruction: If an unknown instruction is encountered, throw an Error with the message "Invalid instruction: [instruction]".
  • No HALT: If the program does not contain a HALT instruction, throw an Error with the message "Program did not halt".
  • Multiple Values at Halt: If the program halts but there are more than one value on the stack, throw an Error with the message "Too many values on stack at halt".

Examples

Example 1:

Input: ["PUSH 5", "PUSH 3", "ADD", "HALT"]
Output: 8
Explanation: Pushes 5 and 3 onto the stack. Adds them (5 + 3 = 8) and pushes 8. HALT is encountered, and 8 is the final result.

Example 2:

Input: ["PUSH 10", "PUSH 2", "DIV", "HALT"]
Output: 5
Explanation: Pushes 10 and 2 onto the stack. Divides 10 by 2 (10 / 2 = 5) and pushes 5. HALT is encountered, and 5 is the final result.

Example 3:

Input: ["PUSH 7", "PUSH 4", "SUB", "PUSH 2", "MUL", "HALT"]
Output: 10
Explanation: Pushes 7 and 4. Subtracts 4 from 7 (7 - 4 = 3). Pushes 3. Pushes 2. Multiplies 3 by 2 (3 * 2 = 6). Pushes 6. HALT is encountered, and 6 is the final result.

Example 4 (Edge Case):

Input: ["PUSH 8", "PUSH 0", "DIV", "HALT"]
Output: Error: Division by zero
Explanation: Attempts to divide 8 by 0, triggering the division by zero error.

Constraints

  • The input program will be an array of strings.
  • Values pushed onto the stack will be integers.
  • The program will contain at least one instruction.
  • The program will contain a HALT instruction.
  • Instruction strings will be properly formatted (e.g., "PUSH 5", "ADD").
  • The maximum length of the instruction array is 100.

Notes

  • Consider using a helper function to parse instructions and extract their arguments.
  • Think about how to represent the stack data structure efficiently.
  • Focus on clear error handling and informative error messages.
  • The PRINT instruction is primarily for debugging and should not affect the final result. It should not pop the value from the stack.
  • The order of operations is determined by the order of instructions in the program.
  • This is a simplified VM; you don't need to implement complex features like variables or control flow. Focus on the core stack-based execution model.
Loading editor...
javascript