Native compiler — change journey
TypeRB Native has two connected journeys:
- compile an application; and
- use a Native compiler to build the next Native compiler.
The second journey amplifies mistakes in the first. This page keeps the responsibilities separate so that a change is not judged only by whether a bootstrap happens to converge.
Use the versioned big map when you need current source addresses.
Classify the change first
Section titled “Classify the change first”| Question | Owner | Evidence to ask for first |
|---|---|---|
| What should TypeRB source mean? | The TypeRB language and reference conformance behavior | A settled portable case |
| Does Native accept the case? | Native subset and exact compatibility claim | Valid and invalid differential cases |
| How is checked meaning represented natively? | Native compiler internals | Deterministic checked form or QBE IL |
| How are values laid out and executed? | Native MIR, runtime, ABI, and target profile | Boundary, runtime, and target tests |
| Can the compiler reproduce itself? | Native bootstrap chain | Exact adjacent-generation evidence |
| Is a result faster or smaller? | A registered measurement boundary | Correctness first, then comparable measurements |
If the first row is unsettled, stop. Native is not a second place to define a different TypeRB language.
The Native repository’s compatibility declaration names the exact TypeRB identity backed by current evidence. Its versioning guide explains why Native implementation identity, language compatibility, internal protocols, runtime ABI, targets, and bootstrap evidence remain separate axes.
The application path
Section titled “The application path”-
Start from portable meaning
Name the accepted TypeRB behavior and the exact Native compatibility claim. Unsupported behavior must fail clearly instead of falling back to different semantics.
-
Recognize and check the supported source
The TypeRB-authored frontend lexes, parses, resolves, and checks the bounded subset. Valid and invalid inputs should agree with the reference behavior inside the claimed boundary.
-
Make native execution decisions explicit
Checked operations cross into Native-owned representation. Layout, calling convention, managed references, and runtime services belong here, not in the portable source language.
-
Emit deterministic QBE IL
QBE IL is a visible handoff. It should change when the intended native representation changes and remain identical when an internal refactor does not change that representation.
-
Cross the external tool boundary
QBE, the assembler, linker, C toolchain boundary, platform ABI, and system libraries are explicit dependencies. Record which side owns a failure.
-
Observe the program
Exit status, standard output, diagnostics, artifacts, and cleanup are stronger evidence than “the compiler process completed.”
Bootstrap adds a feedback loop
Section titled “Bootstrap adds a feedback loop”A normal application stops after it is built. A self-hosted compiler becomes the tool used by the next build:
previous Native seed -> builds the current TypeRB compiler source -> candidate compiler -> builds the same compiler source again -> next candidate compilerThe exact generation names are less important than three questions:
- Did each candidate actually run as the compiler for the next generation?
- Was recovery tooling kept outside the ordinary Native-to-Native chain?
- Did the required compiler, QBE, and executable identities converge under the declared policy?
Evidence in the right order
Section titled “Evidence in the right order”| Order | Evidence | What it rules out |
|---|---|---|
| 1 | Portable valid and invalid cases | A Native-only dialect or silent fallback |
| 2 | Deterministic diagnostics and QBE IL | Hidden nondeterminism and source-specific output |
| 3 | Representative application output and failure behavior | A compiler artifact that does not preserve program behavior |
| 4 | Adjacent Native-to-Native generations | A seed that cannot drive the next complete build |
| 5 | Exact fixed point and target inspection | Drift across regeneration or target boundaries |
| 6 | Registered time, memory, and size measurements | Performance claims made from incomparable or incorrect runs |
Correctness evidence comes first because a fast fixed point that accepts the wrong language is not progress toward a Native TypeRB implementation.
Read the Native evidence for a deeper explanation of what each claim can prove, how bootstrap generations depend on one another, and which inferences remain invalid after a successful fixed point.
Do not read gate numbers as compiler stages
Section titled “Do not read gate numbers as compiler stages”A gate records an experiment question and its acceptance evidence. It is history and rationale, not a stage traversed by every application.
For ordinary compiler work:
- follow the application responsibilities above;
- identify the native boundary the change affects;
- use a gate or decision record to learn why that boundary exists; and
- rerun only the evidence that the boundary requires, plus its declared regressions.
This keeps historical directory names from becoming the reader’s architecture.
Search by observable identities
Section titled “Search by observable identities”Useful search terms survive file moves better than helper names:
rg -n '<command or diagnostic fragment>' --glob '*.trb' --glob '*.sh'rg -n '<QBE symbol or emitted operation>' --glob '*.trb' --glob '*.ssa'rg -n '<manifest field or target profile>' --glob '*.json' --glob '*.md'Trace one producer and one consumer. For a runtime or ABI change, also identify the source-level case that reaches it and the target evidence that observes it.
A practical reading order
Section titled “A practical reading order”- Run the Native executable trace.
- Follow its String and
putscall in the Native code clinic. - Run the nearest check from the workflow and test matrix.
- Use this page to separate the application path from the bootstrap path.
- Use the big map to find the corresponding producer in the newer pinned version.
- Read the nearest conformance case, then the decision or gate record that explains the boundary.
- Read bootstrap machinery only if the change can alter compiler reproduction.
This order lets the compiler remain an understandable program before it becomes an artifact that builds itself.