Master the fundamental concepts of build a bytecode vm through this focused micro-challenge.
Every interpreter follows the same loop: fetch the next instruction, decode its opcode, execute the handler. CPython's `ceval.c` and Lua's `lvm.c` are this pattern at production scale. Your `switch` statement is the same structure CPython 3.11 later replaced with computed gotos for speed.
The program counter points at the next bytecode byte. Each cycle:
The operand stack is a fixed-size LIFO buffer:
For example, `(10 + 20) * 3 - 5` compiles to a sequence of pushes and arithmetic ops ending with a single value on the stack.
```c while (running) { uint8_t op = bytecode[pc++]; switch (op) { case OP_PUSH: ... case OP_ADD: ... } } ```
Start with a debug print of pc and stack contents each cycle while developing. Interpreter bugs show up as impossible stack states long before you get wrong final answers. Once handlers are correct, gate the trace behind a flag so benchmarks stay meaningful.
This exercise asks you to wire up a complete interpreter loop with overflow checks. You will implement `push`, `pop`, and handlers for arithmetic so later tasks add control flow without rewriting the core loop.
Implement a complete stack-based VM interpreter in C.
Requirements:
Test:
Three hints are available for this task, revealed one at a time inside the code workspace so you can struggle productively before seeing them.
All starter code and reference implementations are available for your local setup.
View on Github