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
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 |
| 143 | const WC_OP_MEMORY_INIT: i64 = 74 |
| 144 | const WC_BULK_PREFIX: i64 = 0xfc |
| 145 | const WC_MEMORY_INIT: i64 = 8 |
| 146 | const WC_DATA_COUNT_SECTION: i64 = 12 |
| 455 | const WCD_ASCII_ZERO: i64 = 48 |
| 456 | const WCD_ASCII_NINE: i64 = 57 |
| 457 | const WCD_ASCII_A: i64 = 65 |
| 458 | const WCD_ASCII_F: i64 = 70 |
| 459 | const WCD_ASCII_a: i64 = 97 |
| 460 | const WCD_ASCII_f: i64 = 102 |
| 461 | const WCD_HEX_RADIX: i64 = 16 |
| 462 | const WCD_ESCAPE: i64 = 92 |
| 463 | const WCD_I32_MAX: i64 = 2147483647 |
| 464 | const WCD_U32_MAX: i64 = 4294967295 |
| 465 | const WCD_U32_MODULUS: i64 = 4294967296 |
| 466 | const WCD_SEGMENT_HEADER_MAX: i64 = 1+1+5+1+5 // flags, i32.const, sLEB32, end, uLEB32 length. |
| 467 | const WCD_SECTION_HEADER_MAX: i64 = 1+5+5 // section ID, section length, segment count. |
| 468 | const WCD_I32_CONST: i64 = 0x41 |
| 469 | const WCD_END: i64 = 0x0b |
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 |
| 43 | func wc_refuse(msg: *u8) -> i64 |
| 52 | func wc_mem_flags(has_max: i64, shared: i64) -> i64 |
| 57 | func is_ws(c: i64) -> i64 |
| 64 | func is_delim(c: i64) -> i64 |
| 71 | func lex_next(buf: *u8, n: i64, ls: *i64) -> i64 |
| 125 | func atom_eq(buf: *u8, s: i64, l: i64, kw: *u8) -> i64 |
| 131 | func atom_int(buf: *u8, s: i64, l: i64) -> i64 |
| 148 | func instr_op(buf: *u8, s: i64, l: i64) -> i64 |
| 232 | func emit_instr(body: *u8, bp: i64, op: i64, arg: i64) -> i64 |
| 321 | func op_has_operand(op: i64) -> i64 |
| 330 | func op_is_local(op: i64) -> i64 |
| 336 | func resolve_local(buf: *u8, s: i64, l: i64, lns: *i64, lnl: *i64, cnt: i64) -> i64 |
| 350 | func emit_name(sc: *u8, s: i64, buf: *u8, ns: i64, nl: i64) -> i64 |
| 357 | func emit_locals(body: *u8, bp: i64, ltype: *i64, np: i64, ntot: i64) -> i64 |
| 379 | func emit_functype(sc: *u8, s: i64, np: i64, nr: i64) -> i64 |
| 390 | func sig_find_or_add(tnp: *i64, tnr: *i64, ntp: *i64, np: i64, nr: i64) -> i64 |
| 397 | func substr_eq(buf: *u8, a: i64, b: i64, l: i64) -> i64 |
| 403 | func resolve_label(buf: *u8, s: i64, l: i64, lks: *i64, lkl: *i64, lsp: i64) -> i64 |
| 413 | func resolve_func(buf: *u8, s: i64, l: i64, fts: *i64, ftl: *i64, nf: i64) -> i64 |
| 420 | func prescan_ftab(buf: *u8, n: i64, fts: *i64, ftl: *i64, nimp: *i64) -> i64 |
| 471 | func wc_hex(c: i64) -> i64 |
| 478 | func wc_data(buf: *u8,n: i64,ls: *i64,dst: *u8,at: i64,cap: i64) -> i64 |
| 540 | func wc_compile_file(inp: *u8, outp: *u8) -> i64 |
| 941 | func main(argc: i64, argv: *i64) -> i64 |