A language is a lot more convincing once it can describe itself. The selfhost/ directory holds a Geno frontend and tree-walking interpreter written entirely in Geno: about 8,400 lines across eight modules.
selfhost/
Tokens.geno token definitions
Lexer.geno source text to tokens
Ast.geno syntax tree types
Parser.geno tokens to syntax tree
Types.geno type representation
TypeChecker.geno checking
Interpreter.geno evaluation
Main.geno demo, check, run and test commands
What it is good for
Writing a compiler is a stress test for a language: deep recursion, large algebraic data types, exhaustive matches over dozens of variants, and plenty of string handling. Several of Geno's rough edges were found because the self-hosted parser needed something the language made awkward.
Its functions carry examples, like any other Geno code, so geno test selfhost/ doubles as a regression suite for the language that runs it.
What it is not, yet
- It has no code generation backend and no bootstrap path. The Python implementation remains the reference compiler.
- It covers the subset of Geno its own modules use. Async, traits and app mode are not implemented.
- Builtin coverage is 123 of 231, about 53%.
Keeping it honest
scripts/check_selfhost_parity.py fails the build when a new keyword or builtin appears in the language without either an implementation in selfhost/ or an entry in a named gap group. The gaps are ordered so the next work goes to pure, host-independent builtins first. Nothing drifts silently.
The self-hosted CLI follows the same contracts as the real one, including 0.5's exit semantics: an inner program's Int result becomes the status cmd_run returns.