code wiki / (root) / nx_compile_wat_scalararm.nx

nx_compile_wat_scalararm.nx source

↩ module page · 106 lines · 3819 B

1// nx_compile_wat.nx -- SOVEREIGN source-file driver for the NishiLang WAT (WebAssembly) backend. 2// The NishiLang counterpart of nxc2.exe's --target wat path: reads a .nx (import-expanded), runs 3// lex_source -> parse_module -> opt_run -> wat_emit_module (nx_wasm.nx, now f32-capable), writes WAT to stdout. 4// This WIRES the sovereign wat emitter into a usable driver so the wat path is no longer C-only. The wat is then 5// fed to nx_wat_compiler (.wat -> .wasm, sovereign) for the browser. usage: nx_compile_wat <src.nx> > out.wat 6// license_tier: ORIGINAL 7import "nx_syscalls.nx" 8import "nx_types.nx" 9import "nx_lex_kinds.nx" 10import "nx_outbuf.nx" 11import "nx_ir.nx" 12import "nx_tokenizer.nx" 13import "nx_parse.nx" 14import "nx_opt.nx" 15import "nx_ir_dump.nx" 16import "nx_ir_validate.nx" 17import "nx_import.nx" 18import "nx_wasm_scalararm.nx" 19 20const WAT_SRC_CAP: i64 = 2097152 21const WAT_OUT_CAP: i64 = 16777216 22const WAT_EXPAND_CAP: i64 = 4194304 23 24func watd_log(msg: *u8, n: i64) -> i64 { return sys_write(2, msg, n) } 25func watd_read_stdin(buf: *u8, cap: i64) -> i64 { 26 var total: i64 = 0 27 let BUDGET: i64 = (cap / 4096) + 16 28 var iter: i64 = 0 29 var done: i64 = 0 30 while done == 0 { 31 if iter >= BUDGET { done = 1 } 32 if done == 0 { 33 if total >= cap { done = 1 } 34 if done == 0 { 35 let dst: *u8 = ((buf as i64) + total) as *u8 36 let got: i64 = sys_read(0, dst, cap - total) 37 if got < 0 { done = 1 } 38 if got == 0 { done = 1 } 39 if got > 0 { total = total + got } 40 } 41 } 42 iter = iter + 1 43 } 44 return total 45} 46 47func main(argc: i64, argv: *i64) -> i64 { 48 var in_buf: *u8 = 0 as *u8 49 var in_n: i64 = 0 50 var path_addr: i64 = 0 51 var out_addr: i64 = 0 52 var i: i64 = 1 53 while i < argc { 54 let arg: *u8 = argv[i] as *u8 55 if arg[0] == 0x2D { 56 if arg[1] == 0x2D { if arg[2] == 0x74 { i = i + 2; continue } } 57 i = i + 1 58 continue 59 } 60 if path_addr == 0 { path_addr = arg as i64 } else { out_addr = arg as i64 } 61 i = i + 1 62 } 63 if path_addr != 0 { 64 let path: *u8 = path_addr as *u8 65 let expand_buf: *u8 = sys_mmap(WAT_EXPAND_CAP) 66 let ctx: *ExpandCtx = expand_ctx_new(expand_buf, WAT_EXPAND_CAP) 67 let rc: i64 = expand_imports(ctx, path) 68 if rc < 0 { watd_log("nx_compile_wat: expand_imports failed\n" as *u8, 38); return 10 } 69 let op: *i64 = ctx.out_pos 70 let end: i64 = *op 71 expand_buf[end] = 0 as u8 72 in_buf = expand_buf 73 in_n = end 74 } 75 if path_addr == 0 { 76 watd_log("nx_compile_wat: usage: nx_compile_wat <src.nx> > out.wat\n" as *u8, 52) 77 return 9 78 } 79 if in_n <= 0 { watd_log("nx_compile_wat: empty input\n" as *u8, 28); return 1 } 80 81 let toks: *Tok = lex_source(in_buf, 262144) 82 if toks == (0 as *Tok) { watd_log("nx_compile_wat: lex_source failed\n" as *u8, 34); return 2 } 83 let m: *Module = parse_module(toks, 0 as *Module) 84 if m == (0 as *Module) { watd_log("nx_compile_wat: parse_module failed\n" as *u8, 36); return 3 } 85 if m.n_functions <= 0 { watd_log("nx_compile_wat: no functions\n" as *u8, 29); return 4 } 86 87 var fi: i64 = 0 88 while fi < m.n_functions { 89 let fn_base: i64 = m.functions as i64 90 let f: *Function = (fn_base + fi * 176) as *Function 91 opt_run(f) 92 fi = fi + 1 93 } 94 95 let o: *OutBuf = out_new(WAT_OUT_CAP) 96 wat_emit_module(m, o) 97 if out_addr != 0 { 98 let fd: i64 = sys_openat_wr(out_addr as *u8, 0x1a4) 99 if fd < 0 { watd_log("nx_compile_wat: open out failed\n" as *u8, 32); return 7 } 100 sys_write(fd, o.buf, o.pos) 101 sys_close(fd) 102 } else { 103 sys_write(1, o.buf, o.pos) 104 } 105 return 0 106}