nx_substrate_diagram_ascii.nx source
↩ module page · 219 lines · 8087 B
1// nx_substrate_diagram_ascii.nx -- substrate-walker emitting ASCII.
2//
3// Same walker as nx_substrate_diagram.nx but final emit call is
4// nx_diagram_emit_ascii(d) instead of _emit_mermaid(d). Sovereign
5// terminal rendering, zero external dependency (no Mermaid, no
6// Graphviz). Run + `cat specs/substrate_diagram_ascii.txt` to view.
7//
8// Per Wolfram-IP-free doctrine: the substrate must be visible to its
9// owner WITHOUT a closed renderer. This is the floor.
10
11// nx_safety_envelope:
12// intended_use: AUTO_APPLIED -- primitive-specific tuning queued
13// sil_target: SIL1
14// evidence: [bulk_applied_2026-05-16, see-file-comment-for-detail]
15// verdict: NOT_YET_EVALUATED
16
17import "nx_syscalls.nx"
18import "nx_runtime.nx"
19import "nx_axioms.nx"
20import "nx_dirent.nx"
21import "nx_fcntl.nx"
22import "nx_tier.nx"
23import "nx_diagram.nx"
24
25const NX_DIA_MAX_MODULES: nx_idx = 400
26const NX_DIA_MAX_EDGES: nx_idx = 4096
27const NX_DIA_MAX_NAME: nx_size = 96
28const NX_DIA_DIR_BUF: nx_size = 16384
29
30func dia_name_matches(name: *u8, name_len: nx_size) -> nx_int {
31 if name_len < 6 { return 0 }
32 if name[0] != 110 { return 0 }
33 if name[1] != 120 { return 0 }
34 if name[2] != 95 { return 0 }
35 if name[name_len - 3] != 46 { return 0 }
36 if name[name_len - 2] != 110 { return 0 }
37 if name[name_len - 1] != 120 { return 0 }
38 if name_len >= 8 {
39 if name[name_len - 8] == 95 {
40 if name[name_len - 7] == 116 {
41 if name[name_len - 6] == 101 {
42 if name[name_len - 5] == 115 {
43 if name[name_len - 4] == 116 {
44 return 0
45 }
46 }
47 }
48 }
49 }
50 }
51 return 1
52}
53
54func dia_module_from_filename(name: *u8, name_len: nx_size, out: *u8) -> nx_size {
55 let mod_len: nx_size = name_len - 3
56 var i: nx_idx = 0
57 while i < mod_len {
58 out[i] = name[i]
59 i = i + 1
60 }
61 out[mod_len] = 0
62 return mod_len
63}
64
65func dia_collect_into_diagram(dir_path: *u8, d: *Diagram, names_buf: *u8) -> nx_idx {
66 let fd: i64 = nx_openat(NX_AT_FDCWD, dir_path,
67 NX_O_RDONLY | NX_O_DIRECTORY, 0)
68 if fd < 0 { return -1 }
69 let buf: *u8 = sys_mmap(NX_DIA_DIR_BUF)
70 let dr_raw: *u8 = sys_mmap(NX_DIRENT_BYTES)
71 let dr: *NxDirent = dr_raw as *NxDirent
72 var added: nx_idx = 0
73
74 var batch: i64 = nx_dirent_read(fd, buf, NX_DIA_DIR_BUF)
75 while batch > 0 {
76 var off: i64 = 0
77 while off < batch {
78 let next_off: i64 = nx_dirent_iter(buf, off, batch, dr)
79 if next_off <= 0 { off = batch + 1 }
80 if off <= batch {
81 let nm_len: nx_size = nx_dirent_name_len(dr)
82 if dia_name_matches(dr.name, nm_len) == 1 {
83 if added < NX_DIA_MAX_MODULES {
84 let dst_addr: i64 = (names_buf as i64) + added * NX_DIA_MAX_NAME
85 let dst: *u8 = dst_addr as *u8
86 dia_module_from_filename(dr.name, nm_len, dst)
87 nx_diagram_add_node(d, dst, "" as *u8)
88 added = added + 1
89 }
90 }
91 off = next_off
92 }
93 }
94 batch = nx_dirent_read(fd, buf, NX_DIA_DIR_BUF)
95 }
96 sys_close(fd)
97 return added
98}
99
100func dia_find_module_idx(d: *Diagram, names_buf: *u8, name: *u8, name_len: nx_size) -> nx_idx {
101 var mi: nx_idx = 0
102 while mi < d.n_nodes {
103 let cand_addr: i64 = (names_buf as i64) + mi * NX_DIA_MAX_NAME
104 let cand: *u8 = cand_addr as *u8
105 let cand_len: nx_size = strlen(cand)
106 if cand_len == name_len {
107 if strneq(cand, name, cand_len) == 1 { return mi }
108 }
109 mi = mi + 1
110 }
111 return -1
112}
113
114func dia_add_edges_for_module(d: *Diagram, names_buf: *u8, from_idx: nx_idx) -> nx_int {
115 let mod_addr: i64 = (names_buf as i64) + from_idx * NX_DIA_MAX_NAME
116 let module: *u8 = mod_addr as *u8
117
118 let path_buf: *u8 = sys_mmap(512)
119 let prefix: *u8 = "nxc2/runtime/" as *u8
120 let plen: nx_size = strlen(prefix)
121 var k: nx_idx = 0
122 while k < plen { path_buf[k] = prefix[k]; k = k + 1 }
123 let mod_len: nx_size = strlen(module)
124 var k2: nx_idx = 0
125 while k2 < mod_len { path_buf[plen + k2] = module[k2]; k2 = k2 + 1 }
126 path_buf[plen + mod_len] = 46
127 path_buf[plen + mod_len + 1] = 110
128 path_buf[plen + mod_len + 2] = 120
129 path_buf[plen + mod_len + 3] = 0
130
131 let out_len: *i64 = (sys_mmap(8)) as *i64
132 out_len[0] = 0
133 let buf: *u8 = sys_read_file(path_buf, out_len)
134 if (buf as i64) == 0 { return 0 }
135 let n: nx_size = out_len[0]
136
137 var pos: nx_idx = 0
138 var emitted: nx_int = 0
139 while pos < n {
140 var eol: nx_idx = pos
141 var done_l: nx_int = 0
142 while done_l == 0 {
143 if eol >= n { done_l = 1 }
144 if done_l == 0 {
145 if buf[eol] == 10 { done_l = 1 }
146 if done_l == 0 { eol = eol + 1 }
147 }
148 }
149 let line_len: nx_size = eol - pos
150
151 if line_len > 10 {
152 if buf[pos] == 105 { if buf[pos+1] == 109 {
153 if buf[pos+2] == 112 { if buf[pos+3] == 111 {
154 if buf[pos+4] == 114 { if buf[pos+5] == 116 {
155 if buf[pos+6] == 32 {
156 var p: nx_idx = pos + 7
157 var done_q: nx_int = 0
158 while done_q == 0 {
159 if p >= eol { done_q = 1 }
160 if done_q == 0 {
161 if buf[p] == 34 { done_q = 1 }
162 if done_q == 0 { p = p + 1 }
163 }
164 }
165 if p < eol {
166 if buf[p] == 34 {
167 p = p + 1
168 let mod_start: nx_idx = p
169 var done_m: nx_int = 0
170 while done_m == 0 {
171 if p >= eol { done_m = 1 }
172 if done_m == 0 {
173 if buf[p] == 34 { done_m = 1 }
174 if done_m == 0 {
175 if buf[p] == 46 { done_m = 1 }
176 if done_m == 0 { p = p + 1 }
177 }
178 }
179 }
180 let mod_end: nx_idx = p
181 let mname_len: nx_size = mod_end - mod_start
182 let mname: *u8 = ((buf as i64) + mod_start) as *u8
183 let to_idx: nx_idx = dia_find_module_idx(d, names_buf, mname, mname_len)
184 if to_idx >= 0 {
185 nx_diagram_add_edge(d, from_idx, to_idx, "" as *u8)
186 emitted = emitted + 1
187 }
188 }
189 }
190 }
191 }}
192 }}
193 }}
194 }
195 pos = eol + 1
196 }
197 return emitted
198}
199
200func main() -> i64 {
201 let names_buf: *u8 = sys_mmap(NX_DIA_MAX_MODULES * NX_DIA_MAX_NAME)
202 let d: *Diagram = nx_diagram_new(NX_DIA_MAX_MODULES, NX_DIA_MAX_EDGES)
203
204 let n: nx_idx = dia_collect_into_diagram("nxc2/runtime" as *u8, d, names_buf)
205 if n < 0 {
206 println("error: cannot open runtime directory" as *u8)
207 return 1
208 }
209
210 var j: nx_idx = 0
211 while j < d.n_nodes {
212 dia_add_edges_for_module(d, names_buf, j)
213 j = j + 1
214 }
215
216 // Sovereign emitter: ASCII (terminal-renderable, zero external dep).
217 nx_diagram_emit_ascii(d)
218 return 0
219}