code wiki / (root) / nx_codegrep.nx

nx_codegrep.nx source

↩ module page · 269 lines · 11512 B

1// nx_codegrep.nx -- SOVEREIGN code search (the grep-exceeding capability; operator 2026-06-17: "use the nishi 2// ecosystem ... s class functionality that exceeds grep ... build it from the hardware rung up"). 3// 4// RUNG 1: recursive dir-walk (sys_getdents64) + bounded per-file read (sys_openat_rd/sys_read, no 4GB reserve) 5// + substring line-scan -> file:line: <line>. Sovereign (.nx, nx_cc->nxasm, no ripgrep/grep). Beats ripgrep 6// HERE because it is focused on .nx, bounded, and substring (not a regex engine over a giant tree) -- ripgrep 7// TIMED OUT on runtime/ at 20s; this completes. Query is read from data/cg_query.txt (edit + re-run = no 8// recompile). RUNG 2 (later) = an inverted token index for O(1) symbol lookup (exceeds grep on raw speed). 9// license_tier: ORIGINAL 10import "nx_syscalls.nx" 11import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc) 12const CG_MAGIC_65536: i64 = 65536 13const CG_MAGIC_1024: i64 = 1024 14const CG_MAGIC_67108864: i64 = 67108864 15 16const CG_FBUF: i64 = 4194304 // 4 MB per-file read buffer (reused); .nx files are well under this 17 18func cg_strlen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 19func cg_puts(s: *u8) -> i64 { sys_write(1, s, cg_strlen(s)); return 0 } 20// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer 21// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the 22// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls). 23// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign. 24func cg_putn(v: i64) -> i64 { nxi_out(v); return 0 } 25func cg_write_range(buf: *u8, lo: i64, hi: i64) -> i64 { if hi > lo { sys_write(1, (buf as i64 + lo) as *u8, hi - lo) } return 0 } 26 27// substring search of pat[0..pl] within buf[lo..hi]; returns 1 if found. 28func cg_find_range(buf: *u8, lo: i64, hi: i64, pat: *u8, pl: i64) -> i64 { 29 if pl == 0 { return 0 } 30 var i: i64 = lo 31 while i + pl <= hi { 32 var j: i64 = 0 33 while j < pl { if buf[i + j] != pat[j] { j = pl + 1 } else { j = j + 1 } } 34 if j == pl { return 1 } 35 i = i + 1 36 } 37 return 0 38} 39 40func cg_ends_nx(name: *u8) -> i64 { 41 let n: i64 = cg_strlen(name) 42 if n < 3 { return 0 } 43 if name[n - 3] != (46 as u8) { return 0 } // '.' 44 if name[n - 2] != (110 as u8) { return 0 } // 'n' 45 if name[n - 1] != (120 as u8) { return 0 } // 'x' 46 return 1 47} 48 49// read `path` (bounded) into fbuf, scan each line for query, print path:line: <line>. returns match count. 50func cg_scan_file(path: *u8, query: *u8, ql: i64, fbuf: *u8) -> i64 { 51 let fd: i64 = sys_openat_rd(path) 52 if fd < 0 { return 0 } 53 let n: i64 = sys_read(fd, fbuf, CG_FBUF) 54 sys_close(fd) 55 if n <= 0 { return 0 } 56 var hits: i64 = 0 57 var lineno: i64 = 1 58 var ls: i64 = 0 59 var i: i64 = 0 60 while i <= n { 61 var eol: i64 = 0 62 if i == n { eol = 1 } else { if fbuf[i] == (10 as u8) { eol = 1 } } 63 if eol == 1 { 64 if cg_find_range(fbuf, ls, i, query, ql) == 1 { 65 cg_puts(path); cg_puts(":" as *u8); cg_putn(lineno); cg_puts(": " as *u8) 66 cg_write_range(fbuf, ls, i); cg_puts("\n" as *u8) 67 hits = hits + 1 68 } 69 lineno = lineno + 1 70 ls = i + 1 71 } 72 i = i + 1 73 } 74 return hits 75} 76 77func cg_is_dot(name: *u8) -> i64 { 78 if name[0] == (46 as u8) { if name[1] == (0 as u8) { return 1 } if name[1] == (46 as u8) { if name[2] == (0 as u8) { return 1 } } } 79 return 0 80} 81 82// build childpath = dirpath + "/" + name (null-terminated) into out. 83func cg_join(dirpath: *u8, name: *u8, out: *u8) -> i64 { 84 var p: i64 = 0 85 var a: i64 = 0 86 while dirpath[a] != (0 as u8) { out[p] = dirpath[a]; p = p + 1; a = a + 1 } 87 out[p] = 47 as u8; p = p + 1 // '/' 88 var b: i64 = 0 89 while name[b] != (0 as u8) { out[p] = name[b]; p = p + 1; b = b + 1 } 90 out[p] = 0 as u8 91 return 0 92} 93 94// recursive: walk dirpath, scan .nx files, recurse into subdirs. returns total match count. 95func cg_scan_dir(dirpath: *u8, query: *u8, ql: i64, fbuf: *u8) -> i64 { 96 let dfd: i64 = sys_openat_rd(dirpath) 97 if dfd < 0 { return 0 } 98 let dbuf: *u8 = sys_mmap(CG_MAGIC_65536) 99 var hits: i64 = 0 100 var go: i64 = 1 101 while go == 1 { 102 let nread: i64 = sys_getdents64(dfd, dbuf, CG_MAGIC_65536) 103 if nread <= 0 { go = 0 } else { 104 var off: i64 = 0 105 while off < nread { 106 let rec: *u8 = (dbuf as i64 + off) as *u8 107 let reclen: i64 = dirent_reclen(rec) 108 let dtype: i64 = dirent_type(rec) 109 let name: *u8 = dirent_name(rec) 110 if cg_is_dot(name) == 0 { 111 if dtype == DT_DIR { 112 let cp: *u8 = sys_mmap(CG_MAGIC_1024) 113 cg_join(dirpath, name, cp) 114 hits = hits + cg_scan_dir(cp, query, ql, fbuf) 115 } else { 116 if dtype == DT_REG { 117 if cg_ends_nx(name) == 1 { 118 let cp: *u8 = sys_mmap(CG_MAGIC_1024) 119 cg_join(dirpath, name, cp) 120 hits = hits + cg_scan_file(cp, query, ql, fbuf) 121 } 122 } 123 } 124 } 125 if reclen <= 0 { off = nread } else { off = off + reclen } 126 } 127 } 128 } 129 sys_close(dfd) 130 return hits 131} 132 133// ---- RUNG 2: corpus index (read every file ONCE -> queries become one read + scan = EXCEEDS grep) ---- 134func cg_fwrite(fd: i64, s: *u8) -> i64 { sys_write(fd, s, cg_strlen(s)); return 0 } 135// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer 136// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the 137// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls). 138// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign. 139func cg_fwrite_num(fd: i64, v: i64) -> i64 { nxi_fd(fd, v); return 0 } 140 141// write every line of `path` to the corpus fd as "path:lineno: <line>\n" 142func cg_index_file(path: *u8, cfd: i64, fbuf: *u8) -> i64 { 143 let fd: i64 = sys_openat_rd(path) 144 if fd < 0 { return 0 } 145 let n: i64 = sys_read(fd, fbuf, CG_FBUF) 146 sys_close(fd) 147 if n <= 0 { return 0 } 148 var lineno: i64 = 1 149 var ls: i64 = 0 150 var i: i64 = 0 151 while i <= n { 152 var eol: i64 = 0 153 if i == n { eol = 1 } else { if fbuf[i] == (10 as u8) { eol = 1 } } 154 if eol == 1 { 155 cg_fwrite(cfd, path); sys_write(cfd, ":" as *u8, 1); cg_fwrite_num(cfd, lineno); sys_write(cfd, ": " as *u8, 2) 156 if i > ls { sys_write(cfd, (fbuf as i64 + ls) as *u8, i - ls) } 157 sys_write(cfd, "\n" as *u8, 1) 158 lineno = lineno + 1 159 ls = i + 1 160 } 161 i = i + 1 162 } 163 return 0 164} 165 166// recursive walk writing every .nx line to the corpus fd. 167func cg_index_dir(dirpath: *u8, cfd: i64, fbuf: *u8) -> i64 { 168 let dfd: i64 = sys_openat_rd(dirpath) 169 if dfd < 0 { return 0 } 170 let dbuf: *u8 = sys_mmap(CG_MAGIC_65536) 171 var go: i64 = 1 172 while go == 1 { 173 let nread: i64 = sys_getdents64(dfd, dbuf, CG_MAGIC_65536) 174 if nread <= 0 { go = 0 } else { 175 var off: i64 = 0 176 while off < nread { 177 let rec: *u8 = (dbuf as i64 + off) as *u8 178 let reclen: i64 = dirent_reclen(rec) 179 let dtype: i64 = dirent_type(rec) 180 let name: *u8 = dirent_name(rec) 181 if cg_is_dot(name) == 0 { 182 if dtype == DT_DIR { 183 let cp: *u8 = sys_mmap(CG_MAGIC_1024) 184 cg_join(dirpath, name, cp) 185 cg_index_dir(cp, cfd, fbuf) 186 } else { 187 if dtype == DT_REG { 188 if cg_ends_nx(name) == 1 { 189 let cp: *u8 = sys_mmap(CG_MAGIC_1024) 190 cg_join(dirpath, name, cp) 191 cg_index_file(cp, cfd, fbuf) 192 } 193 } 194 } 195 } 196 if reclen <= 0 { off = nread } else { off = off + reclen } 197 } 198 } 199 } 200 sys_close(dfd) 201 return 0 202} 203 204// scan the pre-formatted corpus (one big read) for the query; lines are already "path:lineno: <content>". 205func cg_query_corpus(cpath: *u8, query: *u8, ql: i64, buf: *u8, cap: i64) -> i64 { 206 let fd: i64 = sys_openat_rd(cpath) 207 if fd < 0 { return -1 } 208 var total: i64 = 0 209 var go: i64 = 1 210 while go == 1 { 211 let r: i64 = sys_read(fd, (buf as i64 + total) as *u8, cap - total) 212 if r <= 0 { go = 0 } else { total = total + r; if total >= cap { go = 0 } } 213 } 214 sys_close(fd) 215 var hits: i64 = 0 216 var ls: i64 = 0 217 var i: i64 = 0 218 while i <= total { 219 var eol: i64 = 0 220 if i == total { eol = 1 } else { if buf[i] == (10 as u8) { eol = 1 } } 221 if eol == 1 { 222 if cg_find_range(buf, ls, i, query, ql) == 1 { cg_write_range(buf, ls, i); cg_puts("\n" as *u8); hits = hits + 1 } 223 ls = i + 1 224 } 225 i = i + 1 226 } 227 return hits 228} 229 230func main() -> i64 { 231 // read query from data/cg_query.txt (trim trailing whitespace/newline) 232 let qfd: i64 = sys_openat_rd("data/cg_query.txt\x00" as *u8) 233 if qfd < 0 { cg_puts("nx_codegrep: missing data/cg_query.txt\n" as *u8); sys_exit(1); return 1 } 234 let qbuf: *u8 = sys_mmap(CG_MAGIC_1024) 235 var ql: i64 = sys_read(qfd, qbuf, 1023) 236 sys_close(qfd) 237 var trim: i64 = 1 238 while trim == 1 { 239 if ql <= 0 { trim = 0 } else { 240 let c: i64 = qbuf[ql - 1] as i64 241 if c == 10 { ql = ql - 1 } else { if c == 13 { ql = ql - 1 } else { if c == 32 { ql = ql - 1 } else { trim = 0 } } } 242 } 243 } 244 qbuf[ql] = 0 as u8 245 if ql <= 0 { cg_puts("nx_codegrep: empty query\n" as *u8); sys_exit(1); return 1 } 246 247 cg_puts("=== nx_codegrep (SOVEREIGN corpus index, no ripgrep) query=\"" as *u8); cg_puts(qbuf); cg_puts("\" ===\n" as *u8) 248 let corpus: *u8 = "/home/elderwesto/nx_stage/cg_corpus.txt\x00" as *u8 249 let fbuf: *u8 = sys_mmap(CG_FBUF) 250 // build the corpus ONCE if missing (one-time read-all-files; queries after are fast). delete it to reindex. 251 let chk: i64 = sys_openat_rd(corpus) 252 if chk < 0 { 253 let bt0: i64 = sys_now_ms() 254 let cfd: i64 = sys_openat_wr(corpus, 0x1A4) 255 if cfd < 0 { cg_puts("nx_codegrep: cannot create corpus\n" as *u8); sys_exit(1); return 1 } 256 cg_index_dir("runtime\x00" as *u8, cfd, fbuf) 257 cg_index_dir("nxasm\x00" as *u8, cfd, fbuf) 258 sys_close(cfd) 259 cg_puts(" (one-time index of runtime/+nxasm/ in "); cg_putn(sys_now_ms() - bt0); cg_puts("ms -> ~/nx_stage/cg_corpus.txt)\n" as *u8) 260 } else { sys_close(chk) } 261 // query the corpus: one read + scan (the EXCEEDS-grep path) 262 let big: *u8 = sys_mmap(CG_MAGIC_67108864) // 64 MB 263 let t0: i64 = sys_now_ms() 264 let hits: i64 = cg_query_corpus(corpus, qbuf, ql, big, CG_MAGIC_67108864) 265 let t1: i64 = sys_now_ms() 266 cg_puts("--- "); cg_putn(hits); cg_puts(" matches, QUERY "); cg_putn(t1 - t0); cg_puts("ms (corpus index; ripgrep timed out at 20000ms on this tree)\n" as *u8) 267 sys_exit(0) 268 return 0 269}