A self-hosting compiler: the language describes its own compilation, then compiles that description.
Timeline
v0.1
Integers only
first WASM bytecode from .ax.
v0.2-0.4
+ Arrays, strings, closures
Type inference. Match -> if-else. HOF.
v0.5-0.7
+ Multi-file, stdlib
Fixed-point type propagation. 16 stdlib.
v0.8
+ AxVal tagged union
3 tags: int/str/arr. Heterogeneous.
v0.9
Self-compilation
wasm_emit.ax compiles itself: 0 errors.
Deep ouroboros
WASM compiles WASM
234KB WASI / 227KB browser. Fixed-point verified.
DOM imports
7 modules
.ax talks to browser directly. This page rendered by .ax.
dom_on + dom_value
Interactive .ax
buttons, inputs, CRT calculator.
Top-level warning
Split safety
compiler catches orphaned fn bodies.
3 Types, 9 Passes
Three Types, 3 x 3 Passes
The type system has 3 fundamental tags: int, str, arr. The compiler needs 3^2 = 9 analysis passes to infer all types: three hearts (detect, propagate, close) each with three scopes (local, cross-function, global). Three is the minimum for complete type closure. An FPGA pipeline independently converged on the same 9-stage structure.
9 passes
3 hearts x 3 stages
Feature scan + float inference + string inference. Same structure as FPGA pipeline.
Native speed
67x faster
Compiled .ax vs interpreted .ax.
WASM size
~397 KB
deep_ouroboros: compiler in a browser. Fixed-point verified.
Test gate
198/198 + 199p + 795h
test_self + test_pages + test_interactive. Zero regression.
7 modules
~15,218 KB total
home + patterns + connections + theory + ideas + lab + demos.
The Self-Compilation Loop
.ax source -> _wasi_ouroboros.wasm -> WASM bytecode. The WASI compiler reads .ax, tokenizes, parses, and emits WASM. It is itself the output of compiling .ax.
What Self-Compilation Means
A self-compiling language understands itself well enough to reproduce itself. The .ax source code describes how to translate .ax into WASM. When that description is itself valid .ax, and the resulting binary does the same translation correctly, the loop closes.
Cross-Compilation
The browser-compiled output (deep_ouroboros) and the WASI-compiled output (_wasi_ouroboros) produce identical results. Two independent compilation paths, same output. Fixed-point verified.
Performance
Benchmark
Native
Interpreted
Speedup
90K ring ops
20ms
1350ms
67x
Z/970,200 ring scan
93ms
~6200ms
67x
Website compile (141 pages)
138ms
>970K limit
native only
The Bootstrap Story
Most languages are written in other languages. C was written in assembly. Python in C. JavaScript in C++. .ax broke this loop.
It started with a JavaScript bootstrap (axc.js, 3860 lines), then grew enough capability to describe its own compilation process (wasm_emit.ax), then compiled that description into a native WASM binary (_wasi_ouroboros.wasm, ~234KB) that does the same thing. The JS bootstrap was discarded. The C-codegen intermediate (deep_codegen.wasm) was archived too. The language stands on its own ground.
28 sessions of careful cultivation. One version at a time. The bare minimum substrate that can reproduce itself -- using only 3 types.
Contrast Table
Standard view: Self-hosting compilers are an engineering milestone -- clever, but most languages eventually compile themselves.
Ring structure view: .ax needs exactly 3 types and 3^2 = 9 analysis passes. Three is the minimum for type closure (detect/propagate/close at three scopes: local/cross-function/global). An FPGA pipeline built independently converged on the same 9-stage structure. Three systems -- compiler, FPGA, ring algebra -- all land on 3 x 3.
Try .ax
Write .ax code below. Use show to display values. Ring arithmetic is automatic: all numbers live in Z/12,612,600. Built-in constants (D=2, K=3, E=5, b=7, L=11, GATE=13, ESCAPE=17, OMEGA=1576576) and functions (gcd, crt, decompose, reconstruct) are pre-loaded.
Try .ax
Write .ax code below. Use show to display values. Ring arithmetic is automatic: all numbers live in Z/12,612,600. Built-in constants (D=2, K=3, E=5, b=7, L=11, GATE=13, ESCAPE=17, OMEGA=1576576) and functions (gcd, crt, decompose, reconstruct) are pre-loaded.