Cómo está construido
Compiler pipeline and T0 IR
Estas páginas están en inglés. Una especificación en un solo idioma dice una sola cosa.
1. Pipeline#
| stage | crate / module | input → output | may report |
|---|---|---|---|
| 1. lexing | t0-syntax::lexer |
text → tokens with spans | E-SYN-* |
| 2. parsing | t0-syntax::parser |
tokens → AST | E-SYN-* |
| 3. headers and versions | t0-compiler::headers |
headers + compiler and manifest versions | E-VER-*, E-CAP-NO-HOST, E-CAP-UNKNOWN, E-CAP-VERSION |
| 4. item collection | t0-compiler::items |
declarations → symbol tables (types, functions, consts, strategies, contract namespaces) | E-RES-* |
| 5. type checking | t0-compiler::check |
bodies → typed bodies | E-TYPE-*, E-FIN-*, E-RES-* |
| 6. capability analysis | t0-compiler::check (host calls) |
used operations ⊆ declared contracts | E-CAP-*, W-CAP-UNUSED, W-DEPRECATED |
| 7. strategy lowering | t0-compiler::strategy |
strategy bodies → signal graphs | E-STRAT-* |
| 8. IR generation | t0-compiler::check (emits IR directly from typed bodies) |
→ IR artifact | — |
| 9. IR validation | t0-ir::validate |
artifact → validated artifact | E-IR-* |
| 10. execution planning | t0-runtime + host |
artifact + manifest + grants → run or refuse | E-VER-*, E-CAP-*, E-PERM-DENIED |
Rules: financial semantics live in the dimension table (t0-ir::ops), not
in the parser; permission enforcement is not part of type checking (the
compiler computes the needed permissions; the session decides).
Diagnostics accumulate: an error in one function does not stop checking of
the others.
2. IR (format t0-ir, version 0.1.0)#
2.1 Artifact#
{
"format": "t0-ir",
"ir_version": "0.1.0",
"language_version": "0.1.0",
"compiler": { "name": "t0-compiler", "version": "0.1.0" },
"source_sha256": "…",
"requirements": {
"language": ">=0.1.0, <0.2.0",
"host": { "name": "ttt", "range": ">=0.1.0, <0.2.0" },
"contracts": [ { "id": "backtest", "range": ">=0.1.0, <0.2.0", "checked_against": "0.1.0" } ],
"permissions": ["backtest.run", "market.read"]
},
"body": { "types": [], "consts": [], "functions": [], "strategies": [], "entry": 0 },
"body_sha256": "…"
}body_sha256 is the SHA-256 of the JSON serialisation of body (field
order as declared). A mismatch is E-IR-HASH.
2.2 Body#
types: user structs/enums and contract types used, each with a stable index; a type reference is anIrType(Int,List(IrType),Struct(index),Enum(index), …).functions[i] = { name, params: [IrType], ret: IrType, locals: [IrType], body: [Stmt] }; parameters are the first locals.Stmt = Let{local, value} | Assign{local, path: [field index], value} | Expr | If{cond, then, else} | While{cond, body} | For{local, list, body} | Match{scrutinee, arms} | Return(Option<Expr>) | Break | Continue.Expr = { ty: IrType, span, kind }wherekindis one ofConst,Local(i),Global(const index),Call{func, args},Builtin{op, args},Host{contract, version, op, args},Binary{op: BinOp, l, r},Unary{op, e},And,Or,Field{e, index},Index{list, index},Struct{type, fields},Variant{type, variant, payload},List[...],If{c, a, b},Match{scrutinee, arms},Try{e},Strategy{index, args}.BinOpnames a fully resolved operation (AddInt,AddDecimal,MulPriceQuantity,SubTimestamp, …). The validator looks it up int0-ir::opsand checks operand and result types.- Strategies:
{ name, version, params: [(name, IrType)], nodes, rules, flatten_on_stop }— ADR-0004 and the spec §9.
2.3 Validator checks (trusts nothing)#
- Format name; IR version within the runtime's accepted range.
- Body hash.
- Every type, function, local and const index in range.
- Every expression's declared type equals the type its kind produces (operators via the table, calls via signatures, fields via type definitions, builtins via their signatures).
Break/Continueonly inside loops;Tryonly in functions whose return type can carry the error; match arms well formed.- Every
Hostnode names a contract listed inrequirements.contractsat the version it was checked against, and the operation's needed permission is listed inrequirements.permissions. The host verifies the operation against its own manifest again at call time. - Strategy graphs: node references point to earlier nodes (acyclic), rule conditions are boolean, feature nodes reference declared contracts.
3. Native backend (Phase 7, not implemented)#
The backend interface takes a validated artifact and a subset predicate; supported functions are lowered tree → SSA → machine code. Candidates (Cranelift, LLVM) are chosen by measured compile latency and generated-code speed on representative kernels (rolling statistics over 10⁶–10⁸ elements, parameter sweeps). Differential tests run every supported program on both backends and compare results, errors and the order of host calls. Native code runs in a worker process (ADR-0002).