code wiki / _hdl_build / nx_wat_compiler.nx
nx_wat_compiler.nx
buildroot/runtime/_hdl_build/nx_wat_compiler.nx
about
nx_wat_compiler.nx -- G-WASM-001 milestone 3: the SOVEREIGN WAT-text -> WASM-binary pipeline
end to end (lexer + parser + binary emit), reusing leb128.nx. Reads a .wat file (the dialect
nxc2 --target wat emits) and writes a .wasm. NO node/python/WABT in this organ; verified
byte-exact vs WABT used ONCE as an alignment oracle, then dropped.
Subset this milestone handles (the f.wat function): (module (memory (export "memory") N)
(func (export "name") (param i64)* (result i64)? (local i64)* <body of: local.get/local.set/
i64.const/i64.add> )). Remaining opcodes (control flow/call/load/store/etc) = next iterations.
usage: nx_wat_compiler <in.wat> <out.wasm>
STATUS: byte-exact vs WABT on REAL nxc2 output (g.wat: import + 2 funcs + call + br_table +
block/loop/br + mixed i32/i64 locals + arith). Handles: type-dedup, import section, multi-
function (function/code N entries), func symbol table + call, top-level & inline exports,
memory, named/numeric locals, 20+ opcodes, control flow + label depth, br_table.
GAMES: COMPLETE -- compiles nx_dungeon_alpha_wasm (a real game) byte-identical to WABT (9176B),
output instantiates + runs (GAME-LOGIC-OK). Handles flat if/else/end + i64.load/store/load8_u/store8.
GOTCHA fixed: i64.load8_u = 0x31 (0x30 is load8_s); buffers sized in BYTES not entries (overflow=corruption).
The full nx->wat->wasm path is sovereign; WABT/node only ever one-time align/verify oracles.
F618 wasm-SIMD FLIP (2026-07-21): + v128.load/store, i8x16.sub_sat_u, v128.or, extadd-pairwise
u8->u16->u32 (_u and the _s mutation twin), i32x4.extract_lane <lane>, and `(local $x v128)`
(valtype 0x7B). All 0xFD-prefixed, sub-opcodes spec-verified. Unknown mnemonics still REFUSE.
license_tier: ORIGINAL
dependencies 2 imports · 2 importers
imports: leb128.nxnx_syscalls.nx
imported by: nx_vcc_color_wasm_build.nxnx_vcc_probe_wasm.nx
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 23 | const K_MAGIC_65536: i64 = 65536 |
| 24 | const K_MAGIC_4194304: i64 = 4194304 |
| 25 | const K_MAGIC_2097152: i64 = 2097152 |
| 26 | const K_MAGIC_524288: i64 = 524288 |
| 27 | const K_MAGIC_8388608: i64 = 8388608 |
functions
| 29 | func w8(b: *u8, p: i64, v: i64) -> i64 { b[p] = v as u8; return p + 1 } |
| 30 | func wcopy(dst: *u8, dp: i64, src: *u8, n: i64) -> i64 |
| 35 | func emit_section(out: *u8, p: i64, id: i64, sc: *u8, sclen: i64) -> i64 |
| 41 | func is_ws(c: i64) -> i64 |
| 48 | func is_delim(c: i64) -> i64 |
| 55 | func lex_next(buf: *u8, n: i64, ls: *i64) -> i64 |
| 103 | func atom_eq(buf: *u8, s: i64, l: i64, kw: *u8) -> i64 |
| 109 | func atom_int(buf: *u8, s: i64, l: i64) -> i64 |
| 120 | func instr_op(buf: *u8, s: i64, l: i64) -> i64 |
| 186 | func emit_instr(body: *u8, bp: i64, op: i64, arg: i64) -> i64 |
| 253 | func op_has_operand(op: i64) -> i64 called by 1: wc_compile_file |
| 261 | func op_is_local(op: i64) -> i64 called by 1: wc_compile_file |
| 267 | func resolve_local(buf: *u8, s: i64, l: i64, lns: *i64, lnl: *i64, cnt: i64) -> i64 |
| 281 | func emit_name(sc: *u8, s: i64, buf: *u8, ns: i64, nl: i64) -> i64 |
| 288 | func emit_locals(body: *u8, bp: i64, ltype: *i64, np: i64, ntot: i64) -> i64 |
| 310 | func emit_functype(sc: *u8, s: i64, np: i64, nr: i64) -> i64 |
| 321 | func sig_find_or_add(tnp: *i64, tnr: *i64, ntp: *i64, np: i64, nr: i64) -> i64 called by 1: wc_compile_file |
| 328 | func substr_eq(buf: *u8, a: i64, b: i64, l: i64) -> i64 |
| 334 | func resolve_label(buf: *u8, s: i64, l: i64, lks: *i64, lkl: *i64, lsp: i64) -> i64 |
| 344 | func resolve_func(buf: *u8, s: i64, l: i64, fts: *i64, ftl: *i64, nf: i64) -> i64 |
| 351 | func prescan_ftab(buf: *u8, n: i64, fts: *i64, ftl: *i64, nimp: *i64) -> i64 |
| 380 | func wc_compile_file(inp: *u8, outp: *u8) -> i64 |
| 692 | func main(argc: i64, argv: *i64) -> i64 |