code wiki / _hdl_build / nx_sharpgrade.nx
nx_sharpgrade.nx source
↩ module page · 184 lines · 6749 B
1// nx_sharpgrade.nx -- THE MATH PARTY of the small-sharp-tool grade (operator 2026-07-20: "linux small
2// sharp philosophy, thats really the grade... out-linux linux... three parties agree: you, the nishi
3// ecosystem, and the math"). Objective cohesion measure of ONE organ: does it do ONE thing (SHARP) or
4// several disjoint things that should SPLIT into separate small sharp tools?
5// THE MATH: parse the organ's functions, build the intra-organ CALL GRAPH, compute CONNECTED COMPONENTS
6// (union-find). 1 component = one cohesive responsibility = SHARP. K>1 components = K responsibilities.
7// Refine with VOCABULARY: a component split whose function-name PREFIXES are all one family (sd_*, st_*)
8// = a cohesive utility lib (SHARP-LIB, theme-cohesion); distinct prefix families across components =
9// genuinely separate tools = SPLIT-K (the nx_clock time-primitive-vs-scheduler defect, made computable).
10// Also EMITS the function inventory (name|prefix|component) = the mining-archive substrate (rule 13).
11// argv: <organ-source.nx>
12// verdict SHARP | SHARP-LIB | SPLIT-<k>. exit 0 always (a grade is data). Reproducible/deterministic.
13// license_tier: ORIGINAL No hw writes (Rule 26).
14import "nx_seat_drive_lib.nx"
15import "nx_deploy_lib.nx"
16import "nx_syscalls.nx"
17
18const SG_SRCCAP: i64 = 4194304
19const SG_MAXF: i64 = 512
20
21func sg_isid(c: i64) -> i64 {
22 if c >= 97 { if c <= 122 { return 1 } }
23 if c >= 65 { if c <= 90 { return 1 } }
24 if c >= 48 { if c <= 57 { return 1 } }
25 if c == 95 { return 1 }
26 return 0
27}
28
29func sg_find(parent: *i64, x: i64) -> i64 {
30 var r: i64 = x
31 while parent[r] != r { r = parent[r] }
32 return r
33}
34func sg_union(parent: *i64, a: i64, b: i64) -> i64 {
35 let ra: i64 = sg_find(parent, a)
36 let rb: i64 = sg_find(parent, b)
37 if ra != rb { parent[ra] = rb }
38 return 0
39}
40
41// does a call to name[no..no+nl) start at buf[p]? word-boundary before + '(' after
42func sg_call_at(buf: *u8, p: i64, n: i64, name: *u8, no: i64, nl: i64) -> i64 {
43 if p + nl + 1 > n { return 0 }
44 if p > 0 { if sg_isid(buf[p-1] as i64) == 1 { return 0 } }
45 var k: i64 = 0
46 while k < nl { if buf[p+k] != name[no+k] { return 0 } k = k + 1 }
47 if buf[p+nl] != (40 as u8) { return 0 }
48 return 1
49}
50// does buf[s..e) call name[no..no+nl)?
51func sg_calls(buf: *u8, s: i64, e: i64, name: *u8, no: i64, nl: i64) -> i64 {
52 var p: i64 = s
53 while p < e {
54 if sg_call_at(buf, p, e, name, no, nl) == 1 { return 1 }
55 p = p + 1
56 }
57 return 0
58}
59// prefix length of name[no..no+nl) = up to first '_' (whole name if none)
60func sg_preflen(name: *u8, no: i64, nl: i64) -> i64 {
61 var i: i64 = 0
62 while i < nl { if name[no+i] == (95 as u8) { return i } i = i + 1 }
63 return nl
64}
65func sg_pref_eq(name: *u8, ao: i64, al: i64, bo: i64, bl: i64) -> i64 {
66 let pa: i64 = sg_preflen(name, ao, al)
67 let pb: i64 = sg_preflen(name, bo, bl)
68 if pa != pb { return 0 }
69 var i: i64 = 0
70 while i < pa { if name[ao+i] != name[bo+i] { return 0 } i = i + 1 }
71 return 1
72}
73
74func main(argc: i64, argv: *i64) -> i64 {
75 if argc < 2 { sd_w("usage: nx_sharpgrade <organ-source.nx>\n" as *u8); sys_exit(2); return 2 }
76 let path: *u8 = argv[1] as *u8
77 let buf: *u8 = sys_mmap(SG_SRCCAP)
78 let n: i64 = dp_read(path, buf, SG_SRCCAP)
79 if n <= 0 { sd_w("NX-SHARPGRADE source unreadable\n" as *u8); sys_exit(2); return 2 }
80
81 let noff: *i64 = sys_mmap(8 * SG_MAXF) as *i64
82 let nlen: *i64 = sys_mmap(8 * SG_MAXF) as *i64
83 let bstart: *i64 = sys_mmap(8 * SG_MAXF) as *i64
84 let parent: *i64 = sys_mmap(8 * SG_MAXF) as *i64
85 var nf: i64 = 0
86
87 // PASS 1: find "func NAME(" at line starts
88 var i: i64 = 0
89 var bol: i64 = 1
90 while i < n {
91 if bol == 1 {
92 var m: i64 = 1
93 if i + 5 >= n { m = 0 }
94 if m == 1 { if buf[i] != (102 as u8) { m = 0 } }
95 if m == 1 { if buf[i+1] != (117 as u8) { m = 0 } }
96 if m == 1 { if buf[i+2] != (110 as u8) { m = 0 } }
97 if m == 1 { if buf[i+3] != (99 as u8) { m = 0 } }
98 if m == 1 { if buf[i+4] != (32 as u8) { m = 0 } }
99 if m == 1 { if nf < SG_MAXF {
100 let ns: i64 = i + 5
101 var ne: i64 = ns
102 var s2: i64 = 1
103 while s2 == 1 { if ne >= n { s2 = 0 } else { if buf[ne] == (40 as u8) { s2 = 0 } else { if sg_isid(buf[ne] as i64) == 1 { ne = ne + 1 } else { s2 = 0 } } } }
104 if ne > ns {
105 noff[nf] = ns
106 nlen[nf] = ne - ns
107 bstart[nf] = i
108 parent[nf] = nf
109 nf = nf + 1
110 }
111 } }
112 }
113 let c: i64 = buf[i] as i64
114 if c == 10 { bol = 1 } else { bol = 0 }
115 i = i + 1
116 }
117 // body ranges: [bstart[k], bstart[k+1]) ; last -> n
118 // PASS 2: edges (union-find). func i's body calls func j -> union
119 var a: i64 = 0
120 while a < nf {
121 let s: i64 = bstart[a]
122 var e: i64 = n
123 if a + 1 < nf { e = bstart[a+1] }
124 var b: i64 = 0
125 while b < nf {
126 if b != a { if sg_calls(buf, s, e, buf, noff[b], nlen[b]) == 1 { sg_union(parent, a, b) } }
127 b = b + 1
128 }
129 a = a + 1
130 }
131 // count components
132 var comps: i64 = 0
133 var r: i64 = 0
134 while r < nf { if sg_find(parent, r) == r { comps = comps + 1 } r = r + 1 }
135 // distinct prefixes across all funcs
136 var dpref: i64 = 0
137 var p1: i64 = 0
138 while p1 < nf {
139 var seen: i64 = 0
140 var p2: i64 = 0
141 while p2 < p1 { if sg_pref_eq(buf, noff[p1], nlen[p1], noff[p2], nlen[p2]) == 1 { seen = 1; p2 = p1 } else { p2 = p2 + 1 } }
142 if seen == 0 { dpref = dpref + 1 }
143 p1 = p1 + 1
144 }
145
146 // function inventory (mining-archive substrate): FN <name> comp=<root>
147 var fi: i64 = 0
148 while fi < nf {
149 sd_w("FN " as *u8)
150 sys_write(1, ((buf as i64) + noff[fi]) as *u8, nlen[fi])
151 sd_w(" comp=" as *u8)
152 let cb: *u8 = sys_mmap(24)
153 var co: i64 = sd_num(cb, 0, sg_find(parent, fi))
154 sd_w(cb)
155 sd_w("\n" as *u8)
156 fi = fi + 1
157 }
158
159 sd_w("NX-SHARPGRADE funcs=" as *u8)
160 let nb: *u8 = sys_mmap(64)
161 sd_num(nb, 0, nf)
162 sd_w(nb)
163 sd_w(" components=" as *u8)
164 sd_num(nb, 0, comps)
165 sd_w(nb)
166 sd_w(" prefixes=" as *u8)
167 sd_num(nb, 0, dpref)
168 sd_w(nb)
169 sd_w(" verdict=" as *u8)
170 if comps <= 1 {
171 sd_w("SHARP\n" as *u8)
172 } else {
173 if dpref <= 1 {
174 sd_w("SHARP-LIB\n" as *u8)
175 } else {
176 sd_w("SPLIT-" as *u8)
177 sd_num(nb, 0, comps)
178 sd_w(nb)
179 sd_w("\n" as *u8)
180 }
181 }
182 sys_exit(0)
183 return 0
184}