code wiki / _hdl_build / nx_gate_gn_gate.nx

nx_gate_gn_gate.nx source

↩ module page · 92 lines · 4052 B

1// nx_gate_gn_gate.nx -- the gate for the integer printer 437 GATES IMPORT. 2// WHY THIS EXISTS: nx_gensota's worklist ranked the unattached organs of generation 3 by 3// importers, and rank 1 was nx_gate_gn itself -- the number-printer at the bottom of the 4// verification fleet had no verification of its own. A printer that silently mis-renders a 5// count would corrupt EVERY gate verdict that quotes a number, and nothing would catch it. 6// HOW IT IS TESTED HONESTLY: gn() writes straight to fd 1, so asserting on a return value 7// would prove nothing. This gate REDIRECTS fd 1 to a file (dup3), calls gn, restores fd 1, 8// and READS THE BYTES BACK -- a writer is only tested by a read-back. 9// TEETH: zero (the special case that returns early) - single digit - multi digit - the 10// decade boundary - negative sign placement - a large value - and a NEGATIVE CONTROL that 11// must FAIL if the comparator is vacuous. 12// license_tier: ORIGINAL expect_exit: 0 No hw writes (Rule 26). 13import "nx_syscalls.nx" 14import "nx_gate_verdict.nx" 15import "nx_gate_gn.nx" 16 17const GG_SAVEFD: i64 = 19 18const GG_TMPMODE: i64 = 0x1a4 19const GG_BUFCAP: i64 = 256 20 21func gg_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 22 23// capture gn(v) into out; returns captured length, or -1 on a redirect failure 24func gg_capture(v: i64, path: *u8, out: *u8) -> i64 { 25 let fd: i64 = sys_openat_wr(path, GG_TMPMODE) 26 if fd < 0 { return 0 - 1 } 27 if sys_dup3(1, GG_SAVEFD, 0) < 0 { sys_close(fd); return 0 - 1 } 28 if sys_dup3(fd, 1, 0) < 0 { sys_close(fd); return 0 - 1 } 29 gn(v) 30 sys_dup3(GG_SAVEFD, 1, 0) 31 sys_close(GG_SAVEFD) 32 sys_close(fd) 33 let lenp: *i64 = sys_mmap(16) as *i64 34 lenp[0] = 0 35 let src: *u8 = sys_read_file(path, lenp) 36 if (src as i64) == 0 { return 0 - 1 } 37 var n: i64 = lenp[0] 38 if n > GG_BUFCAP - 1 { n = GG_BUFCAP - 1 } 39 var i: i64 = 0 40 while i < n { out[i] = src[i]; i = i + 1 } 41 out[n] = 0 as u8 42 return n 43} 44 45func gg_eq(a: *u8, b: *u8) -> i64 { 46 var i: i64 = 0 47 while 1 == 1 { 48 if a[i] != b[i] { return 0 } 49 if a[i] == (0 as u8) { return 1 } 50 i = i + 1 51 } 52 return 0 53} 54 55func gg_check_val(v: i64, want: *u8, ctr: *i64, name: *u8, path: *u8, buf: *u8) -> i64 { 56 let n: i64 = gg_capture(v, path, buf) 57 var ok: i64 = 0 58 if n >= 0 { if gg_eq(buf, want) == 1 { ok = 1 } } 59 gv_check(name, ok, ctr) 60 if ok == 0 { 61 gv_puts(" wanted [" as *u8); gv_puts(want); gv_puts("] got [" as *u8) 62 if n >= 0 { gv_puts(buf) } 63 if n < 0 { gv_puts("<redirect-failed>" as *u8) } 64 gv_puts("]\n" as *u8) 65 } 66 return ok 67} 68 69func main() -> i64 { 70 let ctr: *i64 = gv_ctr() 71 gv_head("NX-GATE-GN-GATE -- read-back proof of the printer 437 gates import" as *u8) 72 let path: *u8 = "knowledge/status/gate_gn_capture.tmp\x00" as *u8 73 let buf: *u8 = sys_mmap(GG_BUFCAP) 74 75 gg_check_val(0, "0" as *u8, ctr, "T1 zero renders \"0\" (the early-return special case)" as *u8, path, buf) 76 gg_check_val(7, "7" as *u8, ctr, "T2 single digit" as *u8, path, buf) 77 gg_check_val(437, "437" as *u8, ctr, "T3 multi digit in correct ORDER (not reversed)" as *u8, path, buf) 78 gg_check_val(10, "10" as *u8, ctr, "T4 decade boundary keeps the trailing zero" as *u8, path, buf) 79 gg_check_val(0 - 42, "-42" as *u8, ctr, "T5 negative: sign FIRST, magnitude after" as *u8, path, buf) 80 gg_check_val(1000000, "1000000" as *u8, ctr, "T6 large value, all interior zeros preserved" as *u8, path, buf) 81 82 // NEGATIVE CONTROL: the comparator must be able to say NO. If this passes, every tooth 83 // above is vacuous and the gate proves nothing. 84 let n7: i64 = gg_capture(437, path, buf) 85 var t7: i64 = 0 86 if n7 >= 0 { if gg_eq(buf, "734" as *u8) == 0 { t7 = 1 } } 87 gv_check("T7 NEG-CONTROL: reversed digits are REJECTED (comparator can fail)" as *u8, t7, ctr) 88 89 let rc: i64 = gv_verdict("GATE-GN-GATE" as *u8, ctr, "printer read-back verified, comparator non-vacuous" as *u8) 90 sys_exit(rc) 91 return rc 92}