code wiki / _hdl_build / nx_adopt_lib.nx

nx_adopt_lib.nx source

↩ module page · 121 lines · 6052 B

1// nx_adopt_lib.nx -- PURE core of the ADOPTION CENSUS (operator priority, seq1410). 2// 3// THE LAW THIS ENFORCES: **THIS ECOSYSTEM'S BOTTLENECK IS NOT BUILDING PRIMITIVES, IT IS ADOPTING THEM.** 4// Measured three times on 2026-07-30 alone: cpu-feature-detect existed with a KAT and was registered 5// nowhere (seq1359) · ss_close existed with 133 openers and 1 closer (seq1347) · nx_hw_cpu_count exists, 6// is CORRECT (sched_getaffinity, cgroup-safe), and has ZERO external callers in 19,823 files (seq1410) 7// while nx_torrent_get hardcodes MAXP=32. A build-only definition of done is why. 8// ==> A ZERO-CALLER CAPABILITY PRIMITIVE IS A RED DEFECT, NOT A COMPLETED FEATURE. 9// 10// ★SCALE IS THE DESIGN PROBLEM, and the answer is the same one seq1318 taught: the naive census greps the 11// corpus ONCE PER PRIMITIVE = O(primitives x corpus) = ~50 GB of scanning for 500 primitives. Instead we 12// walk the corpus TWICE -- pass A collects definitions into a hash table, pass B counts every identifier 13// against it with O(1) lookups -- so the cost is O(corpus), independent of how many primitives exist. 14// LAW (third application today): ONE PASS OVER THE DATA, THEN ANSWER EVERY QUESTION FROM IT. 15// 16// Rule 15: nx_funcmine already proved this shape (bucket-chained, O(files+funcs)). Its helpers live 17// inside an organ with a main(), so they cannot be imported -- THAT is why they are re-declared here, in 18// a LIB, so the next consumer imports instead of copying. nx_funcmine should migrate onto this lib. 19// license_tier: ORIGINAL Pure. No hw writes (Rule 26). 20import "nx_syscalls.nx" 21 22const AD_FNV_OFF: i64 = 1469598103934665603 23const AD_FNV_PRIME: i64 = 1099511628211 24const AD_EMPTY: i64 = 0 25 26// identifier byte? [A-Za-z0-9_] 27func ad_isid(c: i64) -> i64 { 28 if c >= 97 { if c <= 122 { return 1 } } 29 if c >= 65 { if c <= 90 { return 1 } } 30 if c >= 48 { if c <= 57 { return 1 } } 31 if c == 95 { return 1 } 32 return 0 33} 34 35// an identifier may not START with a digit -- otherwise "4096(" would be counted as a call 36func ad_id_start(c: i64) -> i64 { 37 if c >= 48 { if c <= 57 { return 0 } } 38 return ad_isid(c) 39} 40 41func ad_ends_nx(nm: *u8) -> i64 { 42 var n: i64 = 0 43 while nm[n] != (0 as u8) { n = n + 1 } 44 if n < 4 { return 0 } 45 if nm[n-3] == (46 as u8) { if nm[n-2] == (110 as u8) { if nm[n-1] == (120 as u8) { return 1 } } } 46 return 0 47} 48 49// FNV-1a over buf[s..e). NEVER returns AD_EMPTY, so 0 can mean "empty slot" unambiguously -- 50// a hash that can collide with the empty sentinel silently loses entries. 51func ad_fnv(buf: *u8, s: i64, e: i64) -> i64 { 52 var h: i64 = AD_FNV_OFF 53 var i: i64 = s 54 while i < e { h = h ^ (buf[i] as i64); h = h * AD_FNV_PRIME; i = i + 1 } 55 if h == AD_EMPTY { return 1 } 56 return h 57} 58 59// initial probe slot. cap MUST be a power of two (mask, not modulo). 60func ad_slot(h: i64, cap: i64) -> i64 { 61 var x: i64 = h 62 if x < 0 { x = 0 - x } 63 if x < 0 { x = 0 } 64 return x & (cap - 1) 65} 66 67func ad_next(slot: i64, cap: i64) -> i64 { return (slot + 1) & (cap - 1) } 68 69// byte-compare a name in the arena against buf[s..e) 70func ad_name_eq(arena: *u8, noff: i64, nlen: i64, buf: *u8, s: i64, e: i64) -> i64 { 71 if nlen != e - s { return 0 } 72 var i: i64 = 0 73 while i < nlen { if arena[noff + i] != buf[s + i] { return 0 } i = i + 1 } 74 return 1 75} 76 77// Is this definition ADOPTED? external callers > 0. 78// A primitive called only from its own defining file is DARK -- that is exactly the nx_hw_cpu_count 79// shape (1 definition + 3 self-references + 0 external) which read as "5 matches" to a naive grep and 80// looked alive. SELF-REFERENCES MUST NOT COUNT AS ADOPTION. 81func ad_is_adopted(external: i64) -> i64 { 82 if external > 0 { return 1 } 83 return 0 84} 85 86// ---- THE SPLIT (seq1436): private-by-intent vs public-but-unadopted ---- 87// The raw DARK count (17,098 of 34,529 on 2026-07-30) MIXES TWO CATEGORIES and must never be published 88// as 'half the codebase is dead' -- the same defect the ecosystem already banked on nx_dupfunc, where 89// 3.3k collapsed to 3,145 actionable once gate-only and product-only were separated. 90// 91// ROOT CAUSE OF THE AMBIGUITY: NishiLang HAS NO `static`/private VISIBILITY KEYWORD, so a helper that is 92// designed file-local is syntactically indistinguishable from an exported primitive. Every classifier 93// here is therefore reading INTENT from a NAMING CONVENTION, which is weaker than a compiler-enforced 94// one -- filed separately as the language rung. This is the honest middle: measure the convention the 95// ecosystem ALREADY uses rather than invent a new guess. 96// 97// THE DISCRIMINATOR, grounded in the census output itself (not chosen a priori): 98// PUBLIC -> `nx_` prefix. The ecosystem's exported-API convention. Every one of nx_hw_cpu_count, 99// nx_be_read_u64, nx_ycbcr_pixel_to_rgb, nx_weather_wind_at, nx_pcc_combine appeared DARK 100// in the first run, and each lives in a file that exists to be IMPORTED => real debt. 101// LOCAL -> a leading underscore (author-signalled private: _b2b_mix, _poly_tomont) OR a short module 102// prefix bound to its own file (ch_puts, dc_hexrun, mw_slen, fm_*, rm_*, gv_*) => correct 103// design, correctly zero-external, NOT debt. 104// Being wrong here is CHEAP AND VISIBLE (a name is misfiled, and the name is printed), whereas being 105// wrong in the aggregate is expensive and invisible -- which is exactly why the split is reported 106// alongside the raw total instead of replacing it. 107func ad_is_public(arena: *u8, noff: i64, nlen: i64) -> i64 { 108 if nlen < 4 { return 0 } 109 if arena[noff] == (95 as u8) { return 0 } 110 if arena[noff] != (110 as u8) { return 0 } 111 if arena[noff + 1] != (120 as u8) { return 0 } 112 if arena[noff + 2] != (95 as u8) { return 0 } 113 return 1 114} 115 116// The ONLY number a caller should act on: dark AND public. Everything else is a floor with noise. 117func ad_is_debt(external: i64, is_public: i64) -> i64 { 118 if ad_is_adopted(external) == 1 { return 0 } 119 if is_public == 1 { return 1 } 120 return 0 121}