compiler Capstone
- source -> Lex -> Parse -> Analyze -> Compile -> Encode -> Decode -> Run
- strict ownership boundary: compiler emits BC1, VM only consumes BC1
- deterministic handoff contract beats internal implementation choices
Stage contract
- each stage has one input and one output shape
- each stage owns failures in its domain
- no stage reads hidden internals of neighboring stages
- compile output is a stable runtime artifact
Pipeline phases
- Lexer + Parser
- Semantic Analyzer
- Compiler
- BC1 Encoder
- BC1 Decoder
- VM Runtime
Deterministic failure precedence
- lex/parsing errors first
- analyzer errors next (first selected diagnostic)
- compile errors
- encode/decode failures
- runtime errors
Round-trip / reproducibility checks
- same source → same BC1 (modulo formatting policy)
- decode(encode(x)) is behaviorally equivalent for execution
- decoded artifacts are what VM runs, never raw compiler nodes
- stable outputs simplify grading and debugging
Design outcomes
- front-end and runtime can evolve independently
- easier testing at each boundary
- reliable diagnosis of where a bug enters the pipeline
Quick checks
- invalid syntax: stop before analyzer
- valid source + semantic bug: analyzer error only
- bad BC1: decode error before runtime
- valid front-end + bad call behavior: runtime error from VM
- same program executed twice from same BC1 yields same behavior
1 / 1