Appearance
aowli-release — prebuilt binaries for the aowli interpreter
▶️ Try it live in the Playground — write and run
.nim/.aowlin your browser, no install.
A prebuilt, binary-only distribution of aowli, the typed-AIF interpreter for Nimony. The source stays private in aoughwl/aowli; this repo ships only the built binaries, hardened for distribution.
Builds come from the store. The repository itself is not open to the public; what it produces is the archive a licence downloads.
v0.3.2 — correct string/seq slicing & string equality
The current release is v0.3.2. It fixes two shipped-runtime correctness bugs that could make a program silently mis-parse its own data — found while running a real argument parser under the interpreter:
s[a..b]/s[a..<b]slicing — the indexer only handled a single integer index, so a slice returned just the first element (e.g.path[0..<8]yielded one character) instead of the substring/subsequence. Slicing now reads the range bounds correctly for strings and seqs.- string equality across kinds — a non-string value (a
nil/default, or a mis-sliced char) could compare equal to a string when both reduced to the same number internally (nil == "…"returnedtrue). A string is now only ever equal to another string.
Verified byte-identical to a native compile on the repro plus a slice sweep; the full differential corpus stays at 77/77 (no regression on the hot == path).
v0.3.1 — runs the semantic checker (byte-identical to native)
v0.3.1 carries three root-cause correctness fixes on top of v0.3.0 — the ones that let aowli run aowlsem, the Nimony semantic checker itself, and produce output byte-identical to a native compile (520/520 tokens on the reference .p.nif). That's the milestone: the interpreter is now correct enough to run a real, compiler-grade program end to end, so aowlcode's debug/trace can be pointed at the compiler's own passes.
What v0.3.1 fixes:
- Fully-initialised pointer values — constructing an interior
ptr(vkPtr) left the flat-memory view fields (region/foff/elemBits/base) uninitialised, so a later read saw garbage. Caught with valgrind running under mimalloc's Valgrind-tracking build; everyvkPtrconstruction now sets all fields. This was a genuine memory-safety class, not just a cosmetic gap. seqappend value-copy —s.add xnow copiesxon the way in (the same=copyenvelope semantics v0.3.0 gave assignment), so a later mutation of the appended element doesn't alias the source.- Content-addressed tag dedup —
StringView.==is now gated so NIF tag interning deduplicates correctly (surfaced throughborrowCStringUnsafe); content-addressed /TokenBuf-style programs compare tags by identity as intended.
v0.3.0 — correctness-complete
v0.3.0 was the correctness-complete build of aowli. Both engines — the tree-walker behind aowli-interp / aowli-dbg and the internal bytecode VM — reached zero in-scope divergence across a 423-program differential corpus run against the nimony compiler. The engines agree with each other and with native execution, program for program.
What v0.3.0 closes:
- Value-copy (
=copy) semantics — assigning or binding a value object, tuple, or value-array copies the envelope (refs stay shared).var x = a; x.a = 999no longer mutatesa. - The last OS-boundary gaps — real host
stat/lstat(correctfileExists/dirExists), pointer identity in==/!=,cast[int](ptr)round-tripping through flat memory, and VM argv / stdin seeding. - Broad fixes — float→int conversion, block-expression values, cyclic-import init order, a self-nested-iterator hang, and
Tableelement write-back.
One boundary is documented, not a gap: {.emit.} literal-C and C FFI aren't handled by the pure value interpreter — there's no C to execute in the value model. That's precisely what the hybrid-native provider absorbs: the module in question runs through the real C toolchain as a shared object, while the rest of the program stays interpreted. It's on the roadmap — not a correctness gap in the interpreter.
What's in it
Two binaries, each a fully self-contained interpreter over a .s.aif (a Nimony program's typed, post-semcheck AIF):
aowli-interp— run a program, or--traceit for its execution call-tree.aowli-dbg— batch breakpoints: run with--break:LINE, dumping every hit frame's variables in one pass.
These are the same binaries the aowlcode Claude Code plugin's trace/debug tools shell out to — a public user of that plugin runs entirely off this release, never a private aowli checkout.
Hardening
Before publishing, each build goes through:
- A licence gate (fail-closed, checked at module init) — the binary refuses to run without a valid licence rather than degrading silently.
strip --strip-all— the symbol table is removed entirely.
Both were verified against the shipped binary: the stripped artifact exposes no aowli source paths and no internal proc/type names.
Distribution
Shipped as a GitHub Release, v0.3.1, with the binaries as release assets. Each build lists a SHA256 and a VirusTotal-by-hash link so the asset can be verified independently of trusting the download host.
Usage
sh
chmod +x bin/aowli-interp
./bin/aowli-interp <module.s.aif> # run
./bin/aowli-interp --trace <module.s.aif> # execution call-tree
./bin/aowli-dbg --break:29 <module.s.aif> # batch breakpoint, dumps frame varsResolution order
Tools built against aowli (notably aowlcode's trace/debug) resolve a binary in this order, so a released install never needs source:
$AOWLI_BIN_DIR → ~/.aowl/bin → dev ~/aowli/bin
