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}