Diagnostic codes
This is the machine table the compiler and the test goldens are both held to: spec/errors.csv, 23 codes, grouped by the pass that emits them. A code is never renumbered and never reused, so a fix written against E0202 still means the same thing ten releases later.
Every entry carries two things a person needs and one thing a program needs. The person gets the code and the hint; the program gets the same text as a field in the JSON. Run ralt explain E0202 for any of them, or read the table below. Each row links to a page with a program that produces the code, the exact transcript, the repair, and — where the bootstrap never emits the code — a note saying so.
ralt check bad.tp --json [ { "code": "E0202", "kind": "error", "name": "type-mismatch", "file": "bad.tp", "line": 5, "col": 13, "len": 7, "msg": "i32 and f64 do not share an operator; no implicit conversion exists", "hint": "types must match exactly; no implicit conversion exists; use cast<T>(x)" } ]
Exit codes
| status | meaning |
|---|---|
| 0 | clean, or warnings only |
| 1 | at least one diagnostic with severity error |
| 101 | the program trapped at runtime |
| 2 | the command line itself was wrong |
A trap is 101, which is separate from a failed build, so a harness can tell “the source is wrong” from “the program ran and hit a defined edge” without parsing anything. See traps and no-UB.
Lexer
The source text itself is not readable as Tripon.
E0001unterminated-stringstring must close with a double quote on the same lineE0002invalid-characterASCII identifiers only; table in spec/tripon.mdE0003bad-number-literalforms: 123, 0x1F, 0o17, 0b1010, 3.14, 1e-9Parser
One file of grammar decides what may appear here, and it is published.
E0101unexpected-tokensee spec/grammar.ebnf for what is legal hereE0102missing-tokenexpected the token named in the messageTypes
The type contract in spec/tripon.md, sections T1 to T9, enforced.
E0201unknown-identifierdefine it, use the right module, or fix spellingE0202type-mismatchtypes must match exactly; no implicit conversion exists; use cast<T>(x)E0203mutability-requireddeclared const but reassigned; switch to letE0204no-nullnull and undefined do not exist; use opt<T>E0205unhandled-resultResult value ignored; spread with ? or matchE0206non-exhaustive-matchmatch must cover every enum variant or add a deliberate _ armE0207implicit-conversion-deniedno implicit conversions exist; use cast<T>(x) for exact or explicit lossy castsE0212duplicate-match-armremove or reorder the repeated arm; match arms are checked top to bottomTiers
A feature the declared tier does not carry is a hard error, never a surprise.
E0301tier-violationfeature requires a higher tier; raise the tier target or rewrite the callE0302tier-not-declaredadd a top-of-file use tier <name>; statementDriver
What the toolchain needs before a program can be built at all.
E0501entry-point-missingdefine fn main() -> i32Warnings
Not errors. They do not fail a build and they do not change exit code.
E0601unused-bindingprefix with _ to muteE0602unreachable-codeunreachable after earlier return/branchE0603shadowingname shadows an existing binding in scope; renameTraps
A trap is not a crash. It is defined behavior: the program exits 101 and names the code, the file and the line.
E9001integer-overflow-traparithmetic overflow is a defined trap; pass -fast to wrapE9002index-out-of-boundsindexing is bounds-checked everywhere; slice.len() before indexingE9003division-by-zero-trapdiv and mod by zero are defined traps; guard the divisorE9004cast-overflow-trapfloat-to-integer casts outside the target range are defined trapsSeverities
| severity | fails the build | when |
|---|---|---|
| error | yes | the source text is not a valid program |
| warn | no — it does not change the exit code | unused binding, unreachable code, shadowing |
| trap | not applicable | the program ran and hit a defined edge; exit 101 |
The compiler’s explain table has a row for every code above except E9004, which the code generator emits and the trap tests cover, but ralt explain E9004 does not yet answer for. The row below, like the rest of this page, is spec/errors.csv.
Adding a code
Codes are appended, never inserted: a new row goes at the end of spec/errors.csv, the matching golden lands in tests/expected/, and the spec changes before the compiler does. The order of this page follows the first digit of the code — the pass that emits it — and the traps sit last because they are not failures of the program text at all.