code wiki / _hdl_build / nx_nishilang_norm.nx
nx_nishilang_norm.nx source
↩ module page · 97 lines · 4280 B
1// nx_nishilang_norm.nx -- THE GENERAL-MODEL BRIDGE (autonomous-builder lane, 2026-07-20).
2// The maker-climb root cause (NB7): a strong GENERAL coder (Qwen-class, coder15) emits `else if` /
3// `else` blocks that NishiLang has no keyword for -> build breaks. This normalizer rewrites those
4// into valid NishiLang EARLY-RETURN form so any off-the-shelf coder's output compiles. SOUND by
5// construction of the loop: the transform is only a SYNTAX rewrite; the symbolic judge (nx_symjudge)
6// then property-verifies the normalized fix over an exhaustive sweep, so a mis-normalization is
7// caught (fail-closed) -- never a silent wrong fix. Rewrites (semantics-preserving for return-bodies):
8// `} else if C {` -> `} if C {` (else-if chain -> separate early-return ifs)
9// `} else { E }` -> `} E ` (strip the else wrapper + its matching close brace)
10// argv: <infile> <outfile> (reads generated-fix text, writes normalized NishiLang)
11// exit: 0 wrote | 2 io. Idempotent (already-valid NishiLang passes through byte-unchanged).
12// license_tier: ORIGINAL No hw writes (Rule 26).
13import "nx_seg_store.nx"
14import "nx_syscalls.nx"
15
16const NN_CAP: i64 = 262144
17const NN_MAXPEND: i64 = 64
18const NN_LB: i64 = 123 // {
19const NN_RB: i64 = 125 // }
20
21func nn_starts(b: *u8, i: i64, n: i64, s: *u8) -> i64 {
22 var j: i64 = 0
23 while s[j] != (0 as u8) {
24 if i + j >= n { return 0 }
25 if b[i + j] != s[j] { return 0 }
26 j = j + 1
27 }
28 return 1
29}
30
31// normalize src[0,n) into out; returns out length.
32func nn_normalize(src: *u8, n: i64, out: *u8) -> i64 {
33 var o: i64 = 0
34 var i: i64 = 0
35 var depth: i64 = 0 // running brace depth
36 let pend: *i64 = sys_mmap(8 * NN_MAXPEND) as *i64 // stack of depths at which an else-block opened
37 var np: i64 = 0
38 while i < n {
39 // `else if ` -> `if ` (drop "else ")
40 if nn_starts(src, i, n, "else if " as *u8) == 1 {
41 out[o] = 105 as u8; o = o + 1 // i
42 out[o] = 102 as u8; o = o + 1 // f
43 out[o] = 32 as u8; o = o + 1 // space
44 i = i + 8
45 } else {
46 if nn_starts(src, i, n, "else {" as *u8) == 1 {
47 // strip `else {` : emit a single space in place; remember to drop the matching `}`.
48 out[o] = 32 as u8; o = o + 1
49 i = i + 6
50 if np < NN_MAXPEND { pend[np] = depth; np = np + 1 } // matching close is when depth returns HERE
51 depth = depth + 1 // we consumed the `{`
52 } else {
53 let c: i64 = src[i] as i64
54 if c == NN_LB { depth = depth + 1; out[o] = src[i]; o = o + 1; i = i + 1 }
55 else {
56 if c == NN_RB {
57 // is this the close of the most-recent pending else-block?
58 if np > 0 {
59 if depth - 1 == pend[np - 1] {
60 np = np - 1
61 depth = depth - 1
62 i = i + 1 // DROP this `}` (the else wrapper's close)
63 } else {
64 depth = depth - 1; out[o] = src[i]; o = o + 1; i = i + 1
65 }
66 } else {
67 depth = depth - 1; out[o] = src[i]; o = o + 1; i = i + 1
68 }
69 } else {
70 out[o] = src[i]; o = o + 1; i = i + 1
71 }
72 }
73 }
74 }
75 }
76 out[o] = 0 as u8
77 return o
78}
79
80func main(argc: i64, argv: *i64) -> i64 {
81 if argc < 3 {
82 let u: *u8 = "usage: nx_nishilang_norm <infile> <outfile>\n" as *u8
83 var un: i64 = 0
84 while u[un] != (0 as u8) { un = un + 1 }
85 sys_write(2, u, un)
86 sys_exit(2)
87 return 2
88 }
89 let lb: *i64 = sys_mmap(8) as *i64
90 let src: *u8 = sys_read_file(argv[1] as *u8, lb)
91 if (src as i64) == 0 { sys_exit(2); return 2 }
92 let out: *u8 = sys_mmap(NN_CAP)
93 let on: i64 = nn_normalize(src, lb[0], out)
94 if ss_writefile(argv[2] as *u8, out, on) != 0 { sys_exit(2); return 2 }
95 sys_exit(0)
96 return 0
97}