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}