Tools
Compilation backends
Nox compiles the typed program to one of two back ends, which are tested against the same corpus and must produce identical program output.
| LLVM (default) | QBE | |
|---|---|---|
| Pipeline | typed IR → LLVM IR (.ll) → clang -O2 (or zig cc -O2) → native |
typed IR → QBE IL (.ssa) → qbe → assembly → cc → native |
| Code speed | faster (roughly 1.5× C on a mixed benchmark suite) | good (roughly 1.7× C) |
| Compile speed | fast | fast |
| Scheduler | multi-core M:N work-stealing with atomic reference counts | single-threaded cooperative |
| Needs | clang or zig on PATH |
the bundled qbe, and a C compiler for linking |
Debug info (-g) |
no | yes (DWARF line tables) |
--target cross-compile, --emit-asm, freestanding |
no | yes |
How the backend is chosen#
--backend llvm and --backend qbe always win. Otherwise (auto):
- freestanding builds,
--target,--emit-asmand-g→ QBE; - on Windows, LLVM when
zigis installed (it links withzig cc -target x86_64-windows-gnu), otherwise QBE with MinGWcc; - on macOS and Linux, LLVM when
clangorzigis onPATH; with neither, QBE and a one-line note; - otherwise LLVM.
Asking for LLVM together with -g, --emit-asm or freestanding is an explicit error rather than a silent switch.
The C driver#
The LLVM path needs a C toolchain driver to optimise and link the .ll file. noxc tries clang first, then zig cc (Zig's bundled clang and LLD), so a machine with only Zig installed
works. The QBE path links with the system cc (or zig cc for cross targets).
What is the same#
Both back ends implement exactly the language in the reference:
- integer overflow: plain
intwraps, fixed-width integers trap, on both; - argument evaluation order, exception semantics,
with/defer/finallycleanup order; - program output, including float formatting.
What differs (and how code should treat it)#
| Difference | Guidance |
|---|---|
| Parallelism: tasks run on a worker pool (LLVM) or interleave on one thread (QBE) | write tasks that are correct under both; communicate with channels |
spawn/nox.thread.start argument types are wider on LLVM |
stay within the QBE set for portable code (Concurrency) |
-g, --target, --emit-asm, freestanding exist only on QBE |
choose --backend qbe for those |
| speed | LLVM is faster; neither is a semantic choice |
Both back ends are run over the entire golden corpus on every change, and a differential test compares their output.
Intermediate files#
noxc build leaves file.ll (LLVM) or file.ssa and file.s (QBE) next to the executable; they are useful for inspecting the generated code and are safe to delete.
Platforms#
See Platforms for which combinations are tested.