code wiki / (root) / nx_langcensus.nx

nx_langcensus.nx

buildroot/runtime/nx_langcensus.nx

26963 B554 linesdepth 5pulls 5 transitivereach 0 importersview sourcekind tool
docsdependenciesstructsconstsfunctions

about

nx_langcensus.nx -- THE WHOLE-POPULATION COMPILER CENSUS: compile EVERY top-level program in the tree with a GIVEN compiler, classify each outcome by REASON, and (against a baseline census) name every program whose class changed. This is the instrument a language or codegen change is measured by. WHY THIS EXISTS, MEASURED 2026-09-03. The estate's incumbent compiler ruler, nx_cc_equiv_gate, runs EQ_ROWS = 10 corpus rows. Ten rows is a SAMPLE, and a sample can see that a mechanism works; it can never see that a CLASS of program stopped compiling. On the day LN36/LN39/LN40 landed, a first cut of the integer literal bound refused every decimal above i64 max. Every hand-written fixture was GREEN and the 10-row equivalence gate was GREEN, while 286 real estate programs had stopped compiling -- the estate writes u64 BIT PATTERNS in decimal (FNV offset bases, all-ones masks, hash multipliers), so the correct bound is 2^64-1. Only a census over all 13,790 programs could see that class, and it existed only as a shell loop. ★★★★★★A RULER THAT SAMPLES CAN PROVE A MECHANISM AND CAN NEVER PROVE A POPULATION -- AND A COMPILER CHANGE IS A CLAIM ABOUT THE POPULATION. THREE OUTCOMES, NEVER TWO. A compiler that LOOPS on an input is not a compiler that refused it: before the LN40 packer fix a 20-digit fraction literal spun forever, and a census without a per-program deadline hangs at that file and reports nothing about the 9,000 programs after it. HANG is its own class here, and it is counted, named, and treated as a regression. A harness failure (fork/pipe/exec) is a FOURTH class that asserts nothing about the subject -- ★AN AXIS THAT CANNOT SEE MUST ABSTAIN, NEVER ACQUIT. THE REASON TRAVELS WITH THE COUNT. Every refusal row carries the compiler's own first diagnostic line with the file:line prefix stripped, so rows group into causes and a 773-refusal census reads as a dozen classes rather than a number. The delta against a baseline names each program, because ★A COUNT WITHOUT A WORKLIST IS NOT ACTIONABLE. NO SILENT CAP. If the file table or any buffer fills, coverage_complete goes to 0 and the organ REFUSES (exit LC_EXIT_UNPROVEN) rather than publishing a prefix as a population. Usage: nx_langcensus <cc.elf> <out-path> [timeout_ms] [baseline-census-path] Run with CWD = nxc2/ (or any root holding runtime/). Writes one row per program to <out-path>: OK <path> | ERR <path> :: <reason> | HANG <path> | HARN <path> rc=<n> Exit: 0 NO-REGRESSION - 1 REGRESSION (new refusals or hangs, each named) - 2 usage - 3 UNPROVEN. With no baseline the exit is 0 whenever the census completed: a first census has nothing to regress from, and saying otherwise would make the instrument's first run a permanent RED. RESOURCE ENVELOPE. One compiler fork per program, strictly sequential, each bounded by timeout_ms. Buffers (capture, dirent, path table, reason table) are allocated ONCE before the walk and reused -- ★NEVER ALLOCATE IN A HOT LOOP: a per-row capture buffer over 13,790 rows is gigabytes of address space for nothing. The compiler's stdout is discarded to the capture buffer and never to disk.

dependencies 2 imports · 0 importers

nx_syscalls.nx nx_tool_run.nx nx_langcensus.nx

imports: nx_syscalls.nxnx_tool_run.nx

imported by: nobody (leaf or entry point)

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main lc_puts sys_write lc_len sys_exit sys_openat_rd sys_close sys_mmap nxa_die sys_write ↻ sys_exit ↻ nxa_lock_take nxa_lock_addr sys_write ↻ nxa_lock_give nxa_lock_addr ↻ nxa_report_overrun sys_write ↻ nxa_dump_printable sys_write ↻ nxa_dump_sizes sys_write ↻ sys_read_file sys_openat_rd ↻ sys_lseek sys_mmap ↻ sys_read sys_munmap sys_close ↻ lc_walk sys_openat_rd ↻ sys_mmap ↻ sys_getdents64 dirent_name lc_ends_with lc_len ↻ lc_eq_n lc_cat dirent_reclen sys_close ↻

structs

none

consts

50const LC_MAX_PROGRAMS: i64 = 32768
52const LC_PATH_MAX: i64 = 4096
55const LC_DIRBUF: i64 = 65536
64const LC_CAPBUF: i64 = 16777216
67const LC_CAP_NEARFULL: i64 = 16773120
69const LC_REASON_MAX: i64 = 120
71const LC_MAX_REASONS: i64 = 512
74const LC_DEFAULT_TIMEOUT_MS: i64 = 60000
78const LC_ROWBUF: i64 = 8192
79const LC_MODE_0644: i64 = 0x1a4
82const LC_HEARTBEAT_EVERY: i64 = 250
84const LC_EXIT_OK: i64 = 0
85const LC_EXIT_REGRESSION: i64 = 1
86const LC_EXIT_USAGE: i64 = 2
87const LC_EXIT_UNPROVEN: i64 = 3
90const LC_OK: i64 = 0
91const LC_ERR: i64 = 1
92const LC_HANG: i64 = 2
93const LC_HARN: i64 = 3

functions

96func lc_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
97func lc_eq_n(a: *u8, b: *u8, n: i64) -> i64 {
102func lc_ends_with(s: *u8, sfx: *u8) -> i64 {
called by 1: lc_walk calls 2: lc_lenlc_eq_n
108func lc_cat(dst: *u8, at: i64, s: *u8, cap: i64) -> i64 {
called by 2: lc_walkmain
120func lc_catn(dst: *u8, at: i64, v: i64, cap: i64) -> i64 {
called by 2: lc_putnmain calls 1: sys_mmap
137func lc_puts(s: *u8) -> i64 { sys_write(1, s, lc_len(s)) return 0 }
called by 1: main calls 2: sys_writelc_len
138func lc_putn(v: i64) -> i64 {
called by 1: main calls 3: sys_mmaplc_catnsys_write
148func lc_has_main(path: *u8) -> i64 {
172func lc_marker_at(buf: *u8, i: i64, n: i64) -> i64 {
called by 1: lc_reason calls 2: lc_lenlc_eq_n
195func lc_reason(buf: *u8, n: i64, out: *u8) -> i64 {
called by 1: main calls 3: lc_marker_atlc_lenlc_eq_n
238func lc_walk(dir: *u8, tab: *i64, cap: i64, n_in: i64, full: *i64) -> i64 {
274func lc_base_class(base: *u8, blen: i64, path: *u8) -> i64 {
called by 1: main calls 2: lc_lenlc_eq_n
306func lc_class_name(c: i64) -> *u8 {
called by 1: main
314func main(argc: i64, argv: *i64) -> i64 {