self_parse_test.nx source
↩ module page · 49 lines · 2314 B
1// self_parse_test.nx -- feed parse.nx's OWN source through the
2// nx-side lex + parse pipeline and verify it completes without
3// structural crashes.
4//
5// This is a soft self-host milestone: parse.nx, tokenized by lex.nx
6// and parsed by parse.nx at runtime, should produce a Module with
7// roughly the same number of functions it actually declares. We
8// don't bit-diff the IR yet; only check that the pipeline reaches
9// the end without aborting.
10//
11// Source-text-embedding: we use a smaller but representative NishiLang
12// program that exercises most of parse.nx's dispatch paths in a way
13// the linker-embedded string literal can stretch to.
14
15import "syscalls.nx"
16import "types.nx"
17import "lex_kinds.nx"
18import "ir.nx"
19import "lex.nx"
20import "parse.nx"
21
22func main() -> i64 {
23 // A realistic ~20-line NishiLang source exercising:
24 // const, struct, enum (payload), static, func params,
25 // var + assign, for-in, if/else, match, indexing, field access,
26 // __syscall. If parse.nx drives through all of this without
27 // returning null, the front-end is self-host-capable.
28 let src: *u8 = "const CAP: i64 = 64\nstruct Cell { tag: i64, next: *Cell }\nenum Status { Ok, Err(i64) }\nstatic pool: i64\nfunc head(c: *Cell) -> i64 { return c.tag }\nfunc make(x: i64) -> *Cell { var c: Cell\nc.tag = x\nreturn &c }\nfunc scan(buf: *i64, n: i64) -> i64 { var acc: i64 = 0\nfor i in 0..n { acc = acc + buf[i] }\nreturn acc }\nfunc check(s: *Status) -> i64 { match s { Status::Ok => { return 0 }, Status::Err(e) => { return 0 - e } }\nreturn 0 }\nfunc main() -> i64 { let c: *Cell = make(42)\nlet h: i64 = head(c)\nreturn __syscall(93, h, 0, 0, 0, 0, 0) }"
29
30 let toks: *Tok = lex_source(src, 1024)
31 if toks == (0 as *Tok) { return 1 }
32
33 let m: *Module = parse_module(toks, 0 as *Module)
34 if m == (0 as *Module) { return 2 }
35
36 // Expect at least 5 function defs (head, make, scan, check, main).
37 if m.n_functions < 5 { return 3 }
38
39 // Pool walk: every function should have >= 1 block.
40 var i: i64 = 0
41 while i < m.n_functions {
42 let fn_base: i64 = m.functions as i64
43 let f: *Function = (fn_base + i * 176) as *Function
44 if f.n_blocks < 1 { return 10 + i }
45 i = i + 1
46 }
47
48 return 0
49}