Compiler Pipeline
Phases (strictly sequential)
Source → Lexer → Token[] → Parser → AST (PhpArray of Nodes)
→ Analyzer → AnalyzedNode tree → Emitter → PHP code string
| Phase | Location | Input | Output |
|---|---|---|---|
| Lexer | Compiler/Domain/Lexer/ |
Phel source string | Token[] |
| Parser | Compiler/Domain/Parser/ |
Token[] |
AST (PhelArray of nodes) |
| Analyzer | Compiler/Domain/Analyzer/ |
AST nodes | AnalyzedNode tree |
| Emitter | Compiler/Domain/Emitter/ |
AnalyzedNode tree |
PHP code string |
Key Patterns
Special Forms (Analyzer)
Special forms are handled in Compiler/Domain/Analyzer/TypeAnalyzer/SpecialForm/. Each implements analysis for a specific Phel form (def, fn, let, if, do, quote, etc.).
To add a new special form:
- Create analyzer class in
SpecialForm/ - Register in the special form registry
- Create corresponding node emitter (
NodeEmitterInterfaceimplementation) if needed - Add emitter handling
Node Types (Analyzer → Emitter)
Analyzed nodes live in Compiler/Domain/Analyzer/Ast/. Each node type has a corresponding emitter in Compiler/Domain/Emitter/.
Environment & Scope
NodeEnvironment tracks:
- Local bindings and their shadowing
- Context (expression, statement, return)
- Whether result is used (for dead code elimination)
Testing Compiler Code
- Unit tests:
tests/php/Unit/Compiler/— test each phase in isolation - Integration tests:
tests/php/Integration/— end-to-end compilation - Test method:
test_it_<describes_behavior>() - Use
CompilerTestHelperfor quick compile-and-eval in integration tests