Implementation architecture
This is the map for someone working on the Rust code. For why the pieces are shaped this way, follow the ADR links. For what the language does, see the spec.
The pipeline
source: &str
│
▼
┌──────────┐ Vec<Token> ┌──────────┐ ast::Module ┌──────────┐
│ lexer │ ──────────────────▶ │ parser │ ────────────────▶ │ resolver │
└──────────┘ + INDENT/DEDENT └──────────┘ (tree) └──────────┘
│
ResolvedModule (tree + scope info)
│
▼
┌─────────────┐
│ interpreter │ ──▶ Output
└─────────────┘
Every stage takes the previous stage's output and either produces the next
artifact or a Vec<Diagnostic>. Nothing prints; the caller
(korrin::run or the CLI) decides what to do with output and errors.
Modules in crates/korrin/src
| Module | Responsibility | Key ADRs |
|---|---|---|
span | Span (byte offsets) and Spanned<T>. | 0008 |
diagnostics | Diagnostic, ErrorCode, SourceMap, rendering. | 0008 |
lexer | Bytes → tokens; indentation state machine; bracket-depth tracking for newline suppression. | 0001, 0003, 0006, 0007 |
ast | Node types for expressions and statements. Spans on every node. | — |
parser | Recursive-descent statements + Pratt-parsed expressions; error recovery. | 0003, 0006 |
resolver | Static checks (return/break/self placement, duplicate params, self-inheritance) and name resolution to scope depth. | 0005, 0011 |
interpreter | Tree walk. Value, Environment, control-flow Signal enum, arithmetic. | 0004, 0009, 0010, 0011 |
builtins | The built-in function and method table. | — |
Cross-cutting conventions
- Errors are values. A stage returns
Result<T, Vec<Diagnostic>>(or accumulates into a sink). Nopanic!on user input, ever — panics are for internal invariant violations only. - Control flow is a value too.
return/break/continueare aninterpreter::Signalenum threaded throughResult, not Rustpanic/catchand not exceptions. This keeps the interpreter honest and maps to a future VM. (ADR 0004) - Spans everywhere. If you add an AST node, it carries a
Span. If you raise a diagnostic, it has a primary label. - The library never touches the terminal. No
println!, no colour detection, nostd::process::exit. That iskorrin-cli's job. (ADR 0012)
How to…
- add a builtin: see
adding-a-builtin.md. - add a keyword: see
adding-a-keyword.md.