{ } BytecodeVM Playground
C++ · WEBASSEMBLY

Source code

Ctrl / ⌘ + Enter to run
New here? Choose an example, run it, then open Execution to follow the stack.

Inside the interpreter

Ready

Run the example to inspect its execution.

The BytecodeVM language

A small programming language built to make execution visible. Write a program, explore how it becomes tokens and bytecode, then watch a stack-based virtual machine execute it.

The engine is written in C++ and compiled to WebAssembly for this playground. Your code runs on your own device. The editor accepts the custom language shown below.

Your first program

x = 10
y = 20
print(x + y)

This prints 30. Assign variables with = and display values with print(...). Statements need no semicolons.

Values and operators

FeatureSyntax
Whole numbers42, -7
Booleanstrue (1), false (0)
Arithmetic+ - * / and parentheses
Comparisons== != < <= > >=
Comments// comment or # comment

Multiplication and division come before addition and subtraction. Division uses integers: 7 / 2 gives 3. Comparisons produce 1 or 0; conditions treat 0 as false and other integers as true. Variable names are case-sensitive.

Make a decision

score = 85
if score >= 80 {
  print(1)
} else {
  print(0)
}

Use braces around each block. The else block is optional.

Repeat with a loop

x = 1
total = 0
while x <= 5 {
  total = total + x
  x = x + 1
}
print(total)

This prints 15. Change the loop variable so the condition eventually becomes false.

Functions and recursion

func factorial(n) {
  if n <= 1 {
    return 1
  }
  return n * factorial(n - 1)
}
print(factorial(5))

This prints 120. Separate multiple parameters and arguments with commas. Function assignments are local to that call; functions can read global variables. Use an explicit return to return a value.

Read the execution view

Each snapshot shows the state before the highlighted bytecode instruction runs. Next moves to the following snapshot; Back goes to the previous one. The rightmost stack value is the top. Call frames show active functions, and locals belong to the current call. The final snapshot shows completion or failure.

The program finishes before you replay its trace. Stepping currently follows bytecode instructions. Output in the execution view includes only values printed up to the selected snapshot.

What this version supports

Integers, booleans, variables, arithmetic, comparisons, branches, loops, functions, and recursion. Strings, decimals, arrays, user input, classes, imports, and logical &&/|| operators are not supported.

One existing language behaviour to know: reading an undefined variable gives 0. Assignments and print statements leave a value on the VM stack, so statement results can accumulate during loops.

Playground limits

A run stops after 10,000 instructions, 128 function frames, or 10,000 values in one frame. Printed output is limited to approximately 16 KB. The trace records up to 2,000 instructions and 8 MB of snapshots, then the final state. A long run can therefore finish with a shortened trace. You can stop a run at any time.

Created by Pary Vendan · Original C++ project on GitHub