v6 Capstone: Full Pipeline

Lesson, slides, and applied problem sets.

View Slides

Lesson

v6 Capstone: typed modules through a complete toolchain

This is the final checkpoint for the typed compiler line.

The v6 capstone combines:

  • module syntax and import/export contracts
  • static type checking and function signatures
  • multi-module compile/link
  • BC2 encode/decode boundaries
  • VM execution

The quality bar is strict: one source, one deterministic runtime behavior.


1) What makes v6 capstone different

Compared to earlier versions:

  • invalid type/exports/call contracts fail before codegen
  • runtime receives a cleaner instruction stream
  • fewer avoidable runtime crashes
  • error origin is more discoverable by students

The compiler still has final authority on syntax/runtime artifact boundaries.


2) End-to-end contract shape

Lex -> Parse -> Analyze -> CompileModules -> Link -> Encode -> Decode -> NewVM().Run

  • Analyze includes module graph and type rules
  • CompileModules lower static AST to module bytecode
  • Link rewrites into unified executable graph
  • Decode verifies representation compatibility
  • VM executes only the decoded program

Any early error should stop immediately.


3) Analyzer as trust boundary

In v6, analyzer responsibility includes:

  • main module ordering and existence
  • import resolution to earlier modules
  • export validity and typed member access
  • function signature arity and argument typing
  • assignment/return compatibility
  • const/init declaration consistency

If analyzer emits errors, do not continue to compile.

This keeps runtime simpler and error surface cleaner.


4) Typed member access semantics

For u.f(1, 2) where u is module alias:

  1. resolve alias
  2. resolve exported symbol f
  3. ensure f is callable
  4. validate args against exported function signature
  5. lower to closure map lookup + CALL

This is where module + type systems are actually coupled.


5) BC2 boundary in the v6 capstone

CompileModules -> Link -> Encode -> Decode exists specifically to test serialization correctness.

Encode/Decode should be considered a public compiler/runtime contract, not a convenience step.

If decode fails here, do not invoke VM.


6) Runtime layer responsibilities

VM still owns:

  • arithmetic and control behavior
  • runtime type guards not proven by static analysis
  • memory behavior and execution order

Static checks do not make runtime unnecessary; they reduce expected runtime failures.


7) Practice checkpoints (almost solved)

1) Front-end stop-before-runtime + If assignment type mismatch occurs in top-level call, no VM execution should happen.

2) Module ordering + Importing a future module should fail in analysis; capstone should not emit bytecode.

3) Signature mismatch + u.f(1) when f(a,b)->T should fail before execution with arity/type diagnostics.

4) Encode/decode failure + If decode cannot parse emitted artifact, error should be boundary-level, not runtime.

5) Determinism + Same valid input should produce same linked function count and stable output shape.

6) Runtime contract + After successful static stages, runtime errors should only be true execution errors (undefined operations, div-by-zero, etc.).


Module Items

  • Compile and Run v6 (Capstone)

    Connect v6 lexing, parsing, analysis, module compilation, linking, IO, and VM execution.

    hard Upgrade to Pro to access hard problems
Join Discord