Debugging Playbook (symptom → stage → fix)
This chapter is the practical “when it breaks, do this” guide.
The core approach is simple:
- Identify the earliest wrong artifact
- Run that phase alone
- Fix that phase (not the downstream ones)
6.1 The 60-second triage
When a user reports “the compiler is broken”, you do this:
- Ask for the smallest
.oraprogram that reproduces the issue - Run:
ora lexora parseora emit-mlir
- Note where it first becomes wrong:
- tokens wrong → lexer
- AST wrong → parser
- typed fields wrong / type errors → type resolver / semantics
- MLIR wrong → lowering
- verifier complains → MLIR verifier / legality / passes
- conversion fails → Ora → SIR patterns
- Z3 fails → encoder/constraints
6.2 Symptom map
Symptom: tokens look wrong
Run: ora lex file.ora
Likely area: lexer scanners, keyword tables
Fix style: adjust scanner logic, add a lexer test.
Symptom: parse fails or AST shape is wrong
Run: ora parse file.ora
Likely area: parser rule ordering, error recovery
Fix style: adjust parse functions, add regression test.
Symptom: parser ok, but type resolution fails
Signs:
- “unknown type” where it shouldn’t be
- missing symbol binding
- type mismatch that looks nonsensical
Likely area: semantics phase 1 (symbols) or type resolver (typing rules)
Fix style: add a minimal test and inspect the typed AST.
Symptom: parsing ok, but MLIR emission fails
Likely causes:
- a node form has no lowering rule
- TypeInfo is missing and the lowerer refuses to guess
Likely area: src/mlir/lower.zig and the specific lowering module
Fix style: implement one mapping rule + add a golden MLIR test.
Symptom: MLIR emits, but verifier complains
Likely area: dialect verifier rules
Fix style: decide whether:
- the lowering is producing an illegal op shape, or
- the verifier is missing/too strict for the intended feature
Symptom: Ora → SIR conversion fails
Likely area: missing conversion pattern(s)
Fix style: add a conversion pattern and a test that fails before and passes after.
Symptom: Z3 verification fails or becomes incomplete
Likely causes:
- missing encoding for an op
- incorrect encoding for a constraint
- new op breaks assumptions
Likely area: src/z3/encoder.zig
Fix style: add encoding + add a solver test.
6.3 A debugging mindset that scales
When you fix a bug:
- always add a minimal repro
- always add a test
- write the fix so it is “obviously correct” at the artifact level
That’s how the compiler stays stable while it grows.