Skip to content

AIF ≡ NIF — how aoughwl interops with Nimony ​

▶️ Try it live in the Playground — write and run .nim / .aowl in your browser, no install.

aoughwl is a ground-up reimplementation of the Nimony toolchain. The reason it drops straight into the existing nimony world — and the reason any Nim or Nimony program is expected to behave identically in aoughwl — is one deliberate decision about the intermediate format.


The one decision ​

AIF — the Aowl Intermediate Format — is byte-for-byte Nimony's NIF today.

NIF is nimony's persistent, homoiconic S-expression IR: the .p (parsed), .s (semchecked), and .c (lowered) artifacts the compiler passes between its stages. AIF is the same bytes. The rebrand is an identity — a statement that the aoughwl stack owns this format now and will steer it — not a divergence in the wire format.

The files are .nif. Earlier versions of this page (and of the aowlsem and aowlmony pages) said aoughwl writes .p.aif / .s.aif / .c.aif. No tool does, and none is scheduled to: every reader and writer in aowlsem, aowlhexer, aowli, aowlc and aowlmony reads and writes .p.nif / .s.nif / .c.nif, the aowlsem README describes itself as ".p.nif in, .s.nif out", and no commit in any of those repos has ever renamed the extension (checked 2026-09-09). The .aif spelling existed only in prose, and this site has been corrected to say .nif. What aowlparser does stamp is the header: its own (.aif27) magic in place of (.nif27), and a (.vendor "aowlparser") line — and its differential harness normalises that header line before comparing against nifler.

Because the bytes match, each aoughwl stage is a drop-in for its nimony counterpart:

nimony stageaoughwl stageseam
nifler (parse)aowlparsersource → .p.nif
nimsem (semcheck)aowlsem.p.nif → .s.nif
hexer (lower)aowlhexer.s.nif → .c.nif

You can run an all-aoughwl pipeline, an all-nimony pipeline, or any mix — nifler → aowlsem → hexer, aowlparser → nimsem → aowlhexer, and so on. The seams don't care which side produced the artifact.

What "behaves identically" means ​

The contract is observable-behaviour equivalence: a program compiled and run through aoughwl produces the same result as the same program through stock nimony. We hold ourselves to it two ways:

  • Byte-exactness where it's testable. aowlparser's output is byte-for-byte nifler's across the whole nimony standard library and corpus (bar the header lines it stamps with its own identity — (.aif27) and (.vendor "aowlparser") — which the differential harness neutralizes). The parse artifact you feed the rest of the pipeline is the same file nimony would have produced.
  • Differential execution. aowli (the interpreter/VM) and the native/JS backends are checked against nimony's own compile-and-run over its test corpus. Same inputs, same outputs, or it's a bug.

The oracle is nimony's own toolchain: we keep a byte-exact reference build to diff against, so any drift from identical behaviour shows up the moment it appears.

What you get on top ​

Identical behaviour is the floor. Because the stack is written in Nimony and self-hosts over a format it owns, it also gives you what stock nimony can't:

  • Runs in the browser. Parser, semcheck, and execution all compile to JavaScript, so the full pipeline runs client-side — see the playground.
  • Native and web backends. aowlc emits C (GC-free — ARC is baked into the lowered .c.nif); aowljs emits readable, near-native JavaScript.
  • Fast incremental re-checks for live editor tooling, and a fuller, opinionated stdlib and networking stack.

Status & privacy ​

The parse front-end (aowlparser), the interpreter (aowli), and the native/JS backends (aowlc, aowljs) are public. The semantic checker (aowlsem) and the lowering (aowlhexer) are intentionally kept private for now — their docs live on this site, and access is granted on request (ask on Discord, timbuktu_guy, and you'll be added). The playground moves onto the new sem + hexing shortly.