Rail

Rail is a self-hosted ARM64 language with six backends (macOS ARM64, Linux ARM64, Linux x86_64, WebAssembly, Cortex-M4, RISC-V rv32imc), an LLM training substrate, and a verifiable provenance layer. The compiler is ~6,719 lines of Rail compiling itself byte-identically at gen2; the runtime is ARM64 assembly embedded in the compiler. Zero C dependencies. One binary.

Quickstart


git clone https://github.com/zemo-g/rail
cd rail
./rail_native run examples/hello.rail

Expected output:


Compiling examples/hello.rail (244 chars)...
  as: OK
  ld: OK
hello, rail
3628800
42

The seed binary (rail_native, ~1.0 MB ARM64) is checked into the repo and self-compiles to a byte-identical fixed point at gen2 (the first cycle may differ; gen2 == gen3 always). No build step before "hello, world".

For Apple Silicon you're done. Other targets need cross-toolchains — see backends.md.

What's here

Language at a glance


-- Comments start with --
add a b = a + b
factorial n = if n <= 1 then 1 else n * factorial (n - 1)

type Option = | Some x | None
unwrap opt d = match opt
  | Some x -> x
  | None -> d

main =
  let _ = print (show (factorial 10))      -- 3628800
  let _ = print (show (unwrap (Some 42) 0)) -- 42
  0

Functions are name args = body. main is the entry point and returns an int. ADTs use type T = | Ctor args | .... Pattern matching uses match (no with). Tail calls are compiled to loops with no stack growth.

Six backends, one compiler


./rail_native run file.rail        # macOS ARM64 (native execute)
./rail_native linux file.rail      # Linux ARM64 (cross)
./rail_native x86 file.rail        # Linux x86_64 (cross, emits .s)
./rail_native wasm file.rail       # WebAssembly
./rail_native cortexm file.rail    # Cortex-M4 (Thumb-2)
./rail_native riscv32 file.rail    # RISC-V rv32imc

The same source compiles to all of them. See backends.md for toolchain requirements.

Why it exists

The thesis is in CLAUDE.md: the compiler is the source of truth. The HTTPS client, the training loop, the documentation generator you're reading — all are compiled by the same binary you cloned. If it compiles, it runs.

The closer-term motivation for *this* documentation: open-source LLMs are bad at Rail because there's no Rail corpus to read. These pages, together with the auto-generated stdlib reference, are the substrate fix.

Rail — self-hosted compiler · All docs · GitHub