Capstone: Source to Bytecode to VM

  • Wire exact helper return types and stop at the earliest failing stage.
  • Reconstruct a full source-to-artifact trace with observable runtime checks.
  • Use independent boundary evidence instead of treating round trips as sufficient.
1 / 6

Readiness

  • Complete v2 lexer, parser, analyzer, compiler, VM, and BC1 helpers.
2 / 6

Worked reconstruction

Use fn difference(a,b){ return a-b; } let result=difference(9,2);. Parsing creates a function declaration and a variable declaration. Analysis resolves the function and two parameters, then accepts the two-argument call. Compilation puts LOAD a; LOAD b; SUB; RETURN in the function body. Main pushes 9, pushes 2, calls difference with arity 2, then defines result. BC1 encodes those instructions; Decode reconstructs them before Run is called.

The result binding is 7, but the VM's final operand stack is empty, so the capstone returns nil. To make that internal value observable through a source program, append if (result != 7) { 1/0; }. Successful completion now proves that this assertion path did not run. It does not turn result into a top-level return value.

3 / 6

Diagnose before implementing

A capstone returns the second analyzer error and calls Run directly on Compile’s object. Both ordinary examples seem to work. Name two contract violations and tests that distinguish them.

4 / 6

Independent transfer

Create a program with an undefined name in a branch that would not execute at runtime, and another with a valid branch guarding division by zero. Explain why static name traversal and dynamic branch execution give different failure outcomes.

5 / 6

Carry forward

Carry the v2 regression baseline into v3. The next milestone replaces named-call assumptions with closure values and extends the heap; it does not discard parsing, stack, or phase-boundary discipline.

6 / 6
←/→ or click edges to navigate · ? help · N notes · F fullscreen