The compiler written in twill now runs on the Go bootstrap and performs every stage — lex, parse, check, format, evaluate, and the differential canonical dump — matching the Go reference implementation.
Self-hosting reaches the whole pipeline
check— matches the Go command byte-for-byte on all 443 corpus files (src/,std/,examples/,testdata/).fmt— matches on all 89 source files, save one by-design divergence (twill's formatter preserves blank lines between statements; the Go formatter strips them).run— the self-hosted evaluator runs the entire example corpus with output identical totwill run: autodiff, jacobians, hessians, neural-net training (records, MLP, XOR, CNN, attention), minibatching with a shuffled data pipeline, gradient-boosted trees, and Monte Carlo option pricing.run --dump=canonical— the differential harness's bit-exact dump is emitted in twill too, matching Go on the value-independent programs.
The whole src/ + std/ tree type-checks clean.
Under the hood
Getting the two implementations to agree meant building the systems runtime the evaluator needs and closing every gap between them:
- Numbers: native
str_to_f64/f64_to_str(andnum_to_text,f64_hex) so the interpreter — whose numbers are float64 — reads and prints every literal exactly, instead of the pure-twill decimal machinery that needs an exact 64-bit integer. - Evaluation: tensor operators, string concatenation,
import, traced slices (so gradients flow throughx[i:j]), and a native model-handle bridge for gradient boosting were all wired into the self-hosted evaluator. - Correctness: comparison results are F64 (matching the reference, not a bool-packed buffer);
I64-annotated bindings truncate integer division so the ported tensor kernels index correctly; scalar ordering comparisons work on rank-0 tensors without breaking autodiff.
Known limitations
- Two 1-ULP float-accumulation differences (a hessian's canonical dump; a gradient-boosting regression RMSE), from matmul/reduction accumulation order.
save/loadof a foreign gbm model or a tensor record does not yet round-trip through the evaluator.
🤖 Generated with Claude Code