nx_compile_wat.nx source
↩ module page · 108 lines · 3899 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.nx"
19const WAT_MAGIC_4096: i64 = 4096
20const WAT_MAGIC_262144: i64 = 262144
21
22const WAT_SRC_CAP: i64 = 2097152
23const WAT_OUT_CAP: i64 = 16777216
24const WAT_EXPAND_CAP: i64 = 4194304
25
26func watd_log(msg: *u8, n: i64) -> i64 { return sys_write(2, msg, n) }
27func watd_read_stdin(buf: *u8, cap: i64) -> i64 {
28 var total: i64 = 0
29 let BUDGET: i64 = (cap / WAT_MAGIC_4096) + 16
30 var iter: i64 = 0
31 var done: i64 = 0
32 while done == 0 {
33 if iter >= BUDGET { done = 1 }
34 if done == 0 {
35 if total >= cap { done = 1 }
36 if done == 0 {
37 let dst: *u8 = ((buf as i64) + total) as *u8
38 let got: i64 = sys_read(0, dst, cap - total)
39 if got < 0 { done = 1 }
40 if got == 0 { done = 1 }
41 if got > 0 { total = total + got }
42 }
43 }
44 iter = iter + 1
45 }
46 return total
47}
48
49func main(argc: i64, argv: *i64) -> i64 {
50 var in_buf: *u8 = 0 as *u8
51 var in_n: i64 = 0
52 var path_addr: i64 = 0
53 var out_addr: i64 = 0
54 var i: i64 = 1
55 while i < argc {
56 let arg: *u8 = argv[i] as *u8
57 if arg[0] == 0x2D {
58 if arg[1] == 0x2D { if arg[2] == 0x74 { i = i + 2; continue } }
59 i = i + 1
60 continue
61 }
62 if path_addr == 0 { path_addr = arg as i64 } else { out_addr = arg as i64 }
63 i = i + 1
64 }
65 if path_addr != 0 {
66 let path: *u8 = path_addr as *u8
67 let expand_buf: *u8 = sys_mmap(WAT_EXPAND_CAP)
68 let ctx: *ExpandCtx = expand_ctx_new(expand_buf, WAT_EXPAND_CAP)
69 let rc: i64 = expand_imports(ctx, path)
70 if rc < 0 { watd_log("nx_compile_wat: expand_imports failed\n" as *u8, 38); return 10 }
71 let op: *i64 = ctx.out_pos
72 let end: i64 = *op
73 expand_buf[end] = 0 as u8
74 in_buf = expand_buf
75 in_n = end
76 }
77 if path_addr == 0 {
78 watd_log("nx_compile_wat: usage: nx_compile_wat <src.nx> > out.wat\n" as *u8, 52)
79 return 9
80 }
81 if in_n <= 0 { watd_log("nx_compile_wat: empty input\n" as *u8, 28); return 1 }
82
83 let toks: *Tok = lex_source(in_buf, WAT_MAGIC_262144)
84 if toks == (0 as *Tok) { watd_log("nx_compile_wat: lex_source failed\n" as *u8, 34); return 2 }
85 let m: *Module = parse_module(toks, 0 as *Module)
86 if m == (0 as *Module) { watd_log("nx_compile_wat: parse_module failed\n" as *u8, 36); return 3 }
87 if m.n_functions <= 0 { watd_log("nx_compile_wat: no functions\n" as *u8, 29); return 4 }
88
89 var fi: i64 = 0
90 while fi < m.n_functions {
91 let fn_base: i64 = m.functions as i64
92 let f: *Function = (fn_base + fi * 176) as *Function
93 opt_run(f)
94 fi = fi + 1
95 }
96
97 let o: *OutBuf = out_new(WAT_OUT_CAP)
98 wat_emit_module(m, o)
99 if out_addr != 0 {
100 let fd: i64 = sys_openat_wr(out_addr as *u8, 0x1a4)
101 if fd < 0 { watd_log("nx_compile_wat: open out failed\n" as *u8, 32); return 7 }
102 sys_write(fd, o.buf, o.pos)
103 sys_close(fd)
104 } else {
105 sys_write(1, o.buf, o.pos)
106 }
107 return 0
108}