next-gen self-hosted platform for things n stuff
aoughwl.github.io
A from-scratch reimplementation of the Nimony toolchain (the NIF-based Nim compiler) — parser, semchecker, lowering, backends — written in Nimony and self-hosting, built from the ground up.
Our intermediate format is AIF ≡ NIF, byte-for-byte, so every stage is a drop-in and any Nim/Nimony program behaves identically — and it also runs in the browser and ships native C / JavaScript backends.
We didn't set out to replace Nimony. The aoughwl substrate was going to run on it; we patched where it fell short, then rebuilt the pieces from scratch, and ours ended up better. We're here now, so we're finishing it.
→ AIF ≡ NIF: how it interops · the full stack
.nim / .aowl → aowlparse → aowlsem* → aowlhexer* → { aowlc → C · aowljs → JS · aowli → interpret }
aowlsem and aowlhexer are intentionally private for now — docs are public, access on request (Discord: timbuktu_guy). The playground moves onto the new sem + hexing shortly.
| Project | Docs |
|---|---|
aowl toolchain — aowlparse · aowlsem · aowlhexer · aowlc · aowljs · aowli |
AIF ≡ NIF |
aowlup — rustup for the stack: installs / versions / selects the toolchain (variants · profiles) |
repo ↗ |
| nim-code — Claude Code plugin + MCP server | docs |
| nimony-lsp — Language Server + VSCode extension | docs |
net stack — tcp·net·tls·http·compress·serve·ws·requests — TLS 1.3, HTTP/1.1+2, WebSocket, HTTP/3 |
docs |
| web / html / css — typed HTML5 + MDN CSS engine + DSL | docs |
| nimony-ts / nimony-py / nimony-hl — idiomatic TS/Py backends + shared HL-IR | ts · py · hl |
More aowlsem — the whole day is a generics push. The semchecker now instantiates and preserves generic constructs end to end: typevar calls and signatures, generic object applications with substituted field types and attached hooks, generic array bounds and range iterators, generic seq index reads, var forwarding through generic params, late-bound generic hook calls, and quoted generic operators. Around it: out parameter type resolution, sink/source normalization, typed pointer comparisons lowered to magics, unchecked-pointer index assignments wrapped, requires pragma expression checking, and threadvar globals emitted. Steady, surgical commits — aowlsem is now past 340 total commits since Tuesday.
The biggest day yet for aowlsem — 126 commits landing the clean-room semchecker's core. It now passes 397/397 corpus fixtures byte-exact against the nimony oracle, and — the milestone — it does a complete zero-diagnostic traversal of the full std/system: the whole system.nim plus its included std/system/*.nim set, ~6,383 lines, semcheck with 0 errors and 0 log lines. Full-system parity against nimony's own output is down to ~33k canonical diff lines from an earliest baseline of ~62k — a 46.5% reduction, with the first mismatch now a third of the way into the semantic output.
Under that headline: the magic table (arithmetic / comparison / set / pointer magics), varargs[T] params with call-site collection, membership (x in coll) generalized across seq/array/string, seq slicing and s[a..b], for (a, b) in … tuple destructuring, ^k backwards indexing, countdown typevar inference, concept declarations, lifetime-hook attachment, and ptr UncheckedArray[T] indexing. aowlsem also grows diagnostics that go beyond nimony — E0205 self-comparison, E0206 unsigned-compared-to-zero, E0207 empty-loop-range, E0208 tuple-index-out-of-bounds, E0209 shift-amount-out-of-range. (source private for now; docs public, access on request)
We also stood up the whole distribution story — private components, public binaries. The plan is simple: anything that stays source-private, we still ship to everyone — obfuscated, inside a stripped binary.
- obfuscate was reworked to be IR-only. It operates entirely on the compiler's own NIF/AIF token tree, never on source text, so it inherently can't corrupt runtime data — strings, chars and comments are their own token kinds and are never touched. Its
obfnifpass renames every declared symbol to an opaque token (by spelling on parsed NIF, symbol-precise on typed NIF) and weaves in behaviour-preserving control flow, then the result re-feeds the pipeline and behaves identically. - aowl-release is the hardening harness — a
build-release.shthat wraps each component's own build and layers source obfuscation → a fail-closed licence/version gate → NIF control-flow injection →--strip-all(drops the symbol table decompilers love). The gate refuses to run an expired build; there's no risky client-side kill-switch. - Five
-releaserepos now exist as the public homes for the currently-private stages — aowlsem-release, aowli-release, aowlts-release, aowlpy-release, aowlweb-release. Source stays private; the obfuscated, gated, stripped binaries land here shortly so anyone can run the full stack.
And aowlup — rustup for the aowl/nimony stack. It installs, versions, and selects the pipeline: every slot has interchangeable variants (parser aowlparser|nifler, sem aowlsem|nimsem, hexer aowlhexer|hexer, plus backends and tooling), grouped into one-command profiles (aowl = all ours, nimony = all theirs, hybrid = the driver default), each pinned to a git version with a GitHub update check (it doubles as a nimony version manager). aowlmony then compiles against whatever aowlup has selected — exactly the rustup : cargo split. The -release binaries plug straight into this: aowlup is how you'll pull, pin, and select them, and aowlup +nimony gives one-shot toolchain overrides.
And the playground grew a semantics choice. aowlsem now runs in the browser — you can pick aowl semantics instead of the default nim semantics when type-checking, right in the playground. It's marked experimental: real and checking a substantial slice today, but not the full stdlib or generics yet, so it grows from here. aowlsuggest moved into the playground too — its quick-fix / lint layer now runs client-side over the parser's diagnostics, so fix-its surface as you edit — and aowlparser got another update, with the latest parser bundle now shipping in the playground.
A heavy day on the front and middle of the pipeline.
aowlparser — reached full 310/310 structural parity with the upstream Nim standard library: the entire stdlib round-trips. Shipped a real check lint mode — grammar-level error detection with fix-its and source-ordered diagnostics: assignment = where == was meant, a for missing its in, identifier-expected on let/const, and more. Fixed three parser hangs (infinite recursion) and hardened the lexer — UTF-8 identifiers, BOM stripping, custom numeric literals (N'big), parenthesized proc literals, term-rewriting template patterns.
aowlsem — a big step toward a true drop-in: an auto-import system that pulls in system and the module's own imports with no manual flags, real include splicing, when not defined(...) folding, definite-assignment that honours noinit/threadvar/importc, typedesc modelled as a type, templates as an overload set, accent-quoted/operator routine names, and the first value-object ARC hook synthesis — the foundation for Table. (source private for now; docs public, access on request)
aowli — the interpreter/VM now reads the shared aowlhl HL-IR layer (hlload / hlclassify / hlwalk) instead of its own tree-walk, and gained dynamic method dispatch with field write-through for ptr/var receivers, closures with nested capture, and UTF-8 add(string, Rune). With this, aowli is feature-complete: it reproduces 100% of the runnable test corpus byte-for-byte against nimony's own compile-and-run, on both engines (tree-walker and bytecode VM).
aowlhl is now the shared high-level IR — one Nim→HL-IR reader that both aowli and aowljs consume, so the interpreter and the JavaScript backend classify and walk the same skeleton. One lowering, many emitters.
The docs site got a ground-up rebuild. Migrated aoughwl.github.io off Jekyll / just-the-docs onto VitePress — it's now a single-page app with instant client-side navigation (no full reloads), a collapsible nested sidebar, a near-black dark theme, local search, and self-hosted fonts (no font or page flash). It deploys through a GitHub Actions workflow instead of Jekyll, and the in-browser playground is preserved byte-identically.
The nav is region-grouped — Overview / Pipeline / Emitters / Tools / Libraries — and every pipeline, emitter, and tool row carries a small right-aligned "↗" straight to that project's GitHub repo. A floating theme toggle sits in the corner, and GitHub · Discord · Support links live in the top bar.
Repositioned: aoughwl is a ground-up Nimony toolchain. Wrote the interop contract — AIF ≡ NIF, byte-for-byte, so any Nim/Nimony program behaves identically. Renamed the compiler stages aif* → aowl* (aowlparse / aowlsem / aowlhexer / aowlc / aowljs / aowli / aowlmony) — aif now names the format only — and nim-code → aowl-code. Reworked the docs into two homes — Documentation (terse reference) and Engineering Notes (opinionated writeups) — collapsed the changelog into a single Changes record, and normalized every repo description + topics across the org. aowlsem and aowlhexer stay private for now (docs public, access on request); the playground moves onto the new sem + hexing shortly.
Created aifhexer
Created aif
Created aifmony
Created aifc
Created aifjs
Created aifjs-js
Created aifsem
Updated aifi
Updated aifparser
Updated nimony-playground
Took nifi private, oh- the fish weren't bittin today
Updated nifi, 6-10x performance gain
Updated nimony-playground
Updated nifparser
Updated nifi
- Added curly bracket support to the nifparser
- Finalized nifparser, passing against the full nimony suite- byte identical to niffler
- Nearly finished nimony-playground, missing small QOL and a final port to the aoughwl ecosystem (I cannot wait)
Created nimony-playground
Created nifparser
Created nifi, a Nimony NIF Interpreter
Created aowl-lsp, it's nimony-lsp, but with a universal plugin system. Obtain novel features!
Created vscode-aowl, aoughwl hosted on-machine within VSCode
Finalized the aoughwl core spec.
Noticed a memory bug exists- likely roots as a true Nimony bug which interacts with niflens and my nim-code instances
Created nifrewrite makes NIF rewrites simple
Fixed IC
Updated niflens
Updated nimony-lsp
Our VSCode extension + Nimony LSP is nearly as performant and featurefull as it can be, live diagnostics work phenomenally as you type... more to come here.
Pushed IC to aoughwl/Nimony: ~1s -> ~10ms
see: ic-parallel-deps, ic-cursor-traversal, ic-warm-daemon, ic-batch-intern
Created niflens, a CLI tool for parsing and viewing NIF
Updated nimony-lsp and nim-code to benefit from niflens — live diagnostics and suggestions now work as you type!
Massively expanded the net stack — now 8 one-concern repos:
• tls — TLS 1.3 over OpenSSL 3, client + server (SNI, ALPN, verification); pulled into its own repo
• serve — HTTPS, a concurrent worker pool, HTTP/2 (nghttp2: h2c + ALPN h2), chunked request bodies + Expect: 100-continue, opt-in gzip/br compression
• dual-stack IPv6 across tcp / net — one listener serves v4 + v6
• new compress repo — one-shot gzip / brotli / zstd codecs
• ws — a nimony-native WebSocket (RFC 6455), server + client, ws:// and wss://
• HTTP/3 in requests (useHttp3) via curl-impersonate's bundled ngtcp2
Every layer is tested against real clients — curl --http2, live wss://, TLS 1.3 handshakes.
Today starts the official aoughwl/nimony fork.
This is now the main place my Nimony work will go:
- features
- bug fixes
- more opinionated, dynamic, and substantial stdlib
We also shipped aoughwl/nimony-lsp and aoughwl/nim-code:
nimony-lspis the language-server sidenim-codeis a Claude Code plugin and MCP server focused on reducing token usage with Nim and Nimony
Effective indefinitely, the Nimony JavaScript/TypeScript/WASM/Python backend work is private.
For interested parties: the JavaScript and WebAssembly backends are ~complete and remain true to the original vision.
I will gladly and promptly add anyone who wants access, but you will need to reach out to me directly over Discord (timbuktu_guy)
