code wiki / _hdl_build / nx_doc_heal_let.nx
nx_doc_heal_let.nx source
↩ module page · 87 lines · 4139 B
1// nx_doc_heal_let.nx -- DOCTOR auto-fixer (doc_heal family) for the #1 empty-.s cause: a `let` binding that is
2// later REASSIGNED (let is immutable in NishiLang -> reassign silently compile-fails to an empty .s). dhl_heal
3// rewrites each offending `let NAME` -> `var NAME`, and ONLY those: it does NOT touch a clean `let` (never
4// reassigned), a `==` comparison, or a `NAME[i] = ...` index-assignment (the pointer isn't reassigned). This turns
5// the team from autonomous RECALL (NX-LET-REASSIGN) into autonomous FIX. Pure string transform; the wired Doctor
6// runs it on an empty-.s source then recompiles. license_tier: ORIGINAL
7import "nx_syscalls.nx"
8
9func dhl_isident(c: i64) -> i64 {
10 if c >= 97 { if c <= 122 { return 1 } }
11 if c >= 65 { if c <= 90 { return 1 } }
12 if c >= 48 { if c <= 57 { return 1 } }
13 if c == 95 { return 1 }
14 return 0
15}
16// copy the identifier starting at pos into out (nul-term); return its length.
17func dhl_name_at(src: *u8, n: i64, pos: i64, out: *u8) -> i64 {
18 var o: i64 = 0; var i: i64 = pos
19 while i < n {
20 let c: i64 = src[i] as i64
21 if dhl_isident(c) == 1 { out[o] = src[i]; o = o + 1; i = i + 1 } else { i = n }
22 }
23 out[o] = 0 as u8
24 return o
25}
26// 1 if `name` is ASSIGNED ( NAME =, not ==, not the decl's own init at declnamepos, not NAME[..]= ) somewhere in src.
27func dhl_is_reassigned(src: *u8, n: i64, name: *u8, nl: i64, declnamepos: i64) -> i64 {
28 var i: i64 = 0
29 while i + nl <= n {
30 var bb: i64 = 0
31 if i == 0 { bb = 1 } else { if dhl_isident(src[i-1] as i64) == 0 { bb = 1 } }
32 if bb == 1 {
33 var m: i64 = 1; var k: i64 = 0
34 while k < nl { if src[i+k] != name[k] { m = 0; k = nl } else { k = k + 1 } }
35 if m == 1 {
36 let after: i64 = i + nl
37 var ba: i64 = 0
38 if after >= n { ba = 1 } else { if dhl_isident(src[after] as i64) == 0 { ba = 1 } }
39 if ba == 1 { if i != declnamepos {
40 // first non-whitespace char after NAME
41 var p: i64 = after
42 var stop: i64 = 0
43 while stop == 0 {
44 if p >= n { stop = 1 } else { if src[p] == (32 as u8) { p = p + 1 } else { if src[p] == (9 as u8) { p = p + 1 } else { stop = 1 } } }
45 }
46 if p < n { if src[p] == (61 as u8) { // '='
47 var iseq: i64 = 0
48 if p + 1 < n { if src[p+1] == (61 as u8) { iseq = 1 } } // exclude '=='
49 if iseq == 0 { return 1 } // a real reassignment
50 } }
51 } }
52 }
53 }
54 i = i + 1
55 }
56 return 0
57}
58// rewrite every reassigned `let NAME` -> `var NAME`. returns the number of fixes. out is the healed source.
59func dhl_heal(src: *u8, n: i64, out: *u8, outcap: i64) -> i64 {
60 let namebuf: *u8 = sys_mmap(256)
61 var o: i64 = 0; var i: i64 = 0; var changes: i64 = 0
62 while i < n {
63 var do_var: i64 = 0
64 if i + 4 <= n {
65 if src[i] == (108 as u8) { if src[i+1] == (101 as u8) { if src[i+2] == (116 as u8) { if src[i+3] == (32 as u8) {
66 var bb: i64 = 0
67 if i == 0 { bb = 1 } else { if dhl_isident(src[i-1] as i64) == 0 { bb = 1 } }
68 if bb == 1 {
69 var np: i64 = i + 4
70 var sk: i64 = 0
71 while sk == 0 { if np < n { if src[np] == (32 as u8) { np = np + 1 } else { sk = 1 } } else { sk = 1 } }
72 let nl: i64 = dhl_name_at(src, n, np, namebuf)
73 if nl > 0 { if dhl_is_reassigned(src, n, namebuf, nl, np) == 1 { do_var = 1 } }
74 }
75 } } } }
76 }
77 if do_var == 1 {
78 if o + 4 < outcap { out[o]=118 as u8; out[o+1]=97 as u8; out[o+2]=114 as u8; out[o+3]=32 as u8; o = o + 4 }
79 i = i + 4; changes = changes + 1
80 } else {
81 if o < outcap - 1 { out[o] = src[i]; o = o + 1 }
82 i = i + 1
83 }
84 }
85 out[o] = 0 as u8
86 return changes
87}