code wiki / _hdl_build / nx_record_gate.nx
nx_record_gate.nx source
↩ module page · 154 lines · 6597 B
1// nx_record_gate.nx -- referee for NXR1 (nx_record.nx), the typed self-describing record encoding.
2//
3// EVERY TOOTH HERE IS CHOSEN TO BE A THING A TSV ROW CANNOT DO. That is the point: this gate does not
4// merely show the codec round-trips, it shows the codec is STRUCTURALLY IMMUNE to the four failure modes
5// that make positional tab-delimited text unfit for the information plane (debt seq1326).
6// T3 = a TAB and a NEWLINE inside a value survive (TSV: corrupts the row / splits the record)
7// T4 = an absent field does NOT shift its neighbours (TSV: every later column reads as the wrong one)
8// T5 = an UNKNOWN field id is stepped over, not fatal (TSV: a new column breaks every old reader)
9// T8 = a type mismatch yields the default, not raw bytes (TSV: everything is text, so nothing is checked)
10// T7 is the NON-VACUITY tooth: it proves field 20 IS findable in the full record, so T4's "absent" is a
11// real absence and not this gate failing to find anything at all.
12//
13// license_tier: ORIGINAL expect_exit: 0
14import "nx_gate.nx"
15import "nx_record.nx"
16
17const RG_TEETH: i64 = 8
18const RG_BUF: i64 = 4096
19const RG_OUTS: i64 = 32
20const RG_FID_A: i64 = 10
21const RG_FID_B: i64 = 20
22const RG_FID_C: i64 = 30
23const RG_FID_UNKNOWN: i64 = 999
24const RG_VAL_A: i64 = 111
25const RG_VAL_B: i64 = 222
26const RG_VAL_C: i64 = 333
27const RG_DEFAULT: i64 = 0 - 7
28const RG_TAB: i64 = 9
29const RG_NL: i64 = 10
30const RG_CH_A: i64 = 97
31const RG_CH_B: i64 = 98
32const RG_CH_C: i64 = 99
33const RG_DIRTY_LEN: i64 = 5
34
35func rg_row(name: *u8, ok: i64) -> i64 {
36 gw(" " as *u8); gw(name)
37 if ok == 1 { gw(" PASS\n" as *u8) } else { gw(" FAIL\n" as *u8) }
38 return 0
39}
40
41func main() -> i64 {
42 let b: *u8 = sys_mmap(RG_BUF)
43 let outs: *i64 = sys_mmap(RG_OUTS) as *i64
44
45 // ---- FULL record: fields A, B, C all present, typed i64 ----
46 var o: i64 = nxr_init(b)
47 o = nxr_add_i64(b, o, RG_FID_A, RG_VAL_A)
48 o = nxr_add_i64(b, o, RG_FID_B, RG_VAL_B)
49 o = nxr_add_i64(b, o, RG_FID_C, RG_VAL_C)
50
51 // ---- T1: typed i64 round-trips through field ids ----
52 var t1: i64 = 0
53 if nxr_get_i64(b, o, RG_FID_A, RG_DEFAULT) == RG_VAL_A {
54 if nxr_get_i64(b, o, RG_FID_C, RG_DEFAULT) == RG_VAL_C { t1 = 1 }
55 }
56
57 // ---- T7 NON-VACUITY: field B IS present and findable HERE. If this fails, T4 below is passing
58 // for free because nothing is findable at all.
59 var t7: i64 = 0
60 if nxr_get_i64(b, o, RG_FID_B, RG_DEFAULT) == RG_VAL_B { t7 = 1 }
61
62 // ---- T2: field count is exactly what was written ----
63 var t2: i64 = 0
64 if nxr_count(b) == 3 { t2 = 1 }
65
66 // ---- T3: a value containing a TAB and a NEWLINE survives byte-exact.
67 // A TSV row cannot represent this at all: the tab ends the field, the newline ends the record.
68 let dirty: *u8 = sys_mmap(64)
69 dirty[0] = RG_CH_A as u8
70 dirty[1] = RG_TAB as u8
71 dirty[2] = RG_CH_B as u8
72 dirty[3] = RG_NL as u8
73 dirty[4] = RG_CH_C as u8
74 let d: *u8 = sys_mmap(RG_BUF)
75 var od: i64 = nxr_init(d)
76 od = nxr_add(d, od, RG_FID_A, NXR_T_STR, dirty, RG_DIRTY_LEN)
77 var t3: i64 = 0
78 if nxr_find(d, od, RG_FID_A, outs) == NXR_FOUND {
79 if outs[1] == RG_DIRTY_LEN {
80 let vo: i64 = outs[0]
81 if d[vo] == (RG_CH_A as u8) { if d[vo + 1] == (RG_TAB as u8) {
82 if d[vo + 2] == (RG_CH_B as u8) { if d[vo + 3] == (RG_NL as u8) {
83 if d[vo + 4] == (RG_CH_C as u8) { t3 = 1 } } } } }
84 }
85 }
86
87 // ---- T4: SPARSE record -- A and C written, B NEVER written.
88 // B must read as the DEFAULT, and C must still read as C. In a positional TSV, dropping the
89 // middle column makes C's value arrive where B was expected. This is the mixed-schema class
90 // already live in the debt- plane (5-col and 7-col rows in one store).
91 let s: *u8 = sys_mmap(RG_BUF)
92 var os: i64 = nxr_init(s)
93 os = nxr_add_i64(s, os, RG_FID_A, RG_VAL_A)
94 os = nxr_add_i64(s, os, RG_FID_C, RG_VAL_C)
95 var t4: i64 = 0
96 if nxr_get_i64(s, os, RG_FID_B, RG_DEFAULT) == RG_DEFAULT {
97 if nxr_get_i64(s, os, RG_FID_C, RG_DEFAULT) == RG_VAL_C {
98 if nxr_get_i64(s, os, RG_FID_A, RG_DEFAULT) == RG_VAL_A { t4 = 1 }
99 }
100 }
101
102 // ---- T5: FORWARD COMPAT -- an UNKNOWN field id sits between two known ones. A reader that has
103 // never heard of 999 must step over it by its own length and still find C.
104 let u: *u8 = sys_mmap(RG_BUF)
105 var ou: i64 = nxr_init(u)
106 ou = nxr_add_i64(u, ou, RG_FID_A, RG_VAL_A)
107 ou = nxr_add(u, ou, RG_FID_UNKNOWN, NXR_T_BYTES, dirty, RG_DIRTY_LEN)
108 ou = nxr_add_i64(u, ou, RG_FID_C, RG_VAL_C)
109 var t5: i64 = 0
110 if nxr_get_i64(u, ou, RG_FID_C, RG_DEFAULT) == RG_VAL_C {
111 if nxr_get_i64(u, ou, RG_FID_A, RG_DEFAULT) == RG_VAL_A { t5 = 1 }
112 }
113
114 // ---- T6: FAIL-CLOSED -- a TRUNCATED record is refused WHOLE, never partially read.
115 var t6: i64 = 0
116 if nxr_valid(b, o) == 1 {
117 if nxr_valid(b, o - 1) == 0 {
118 if nxr_find(b, o - 1, RG_FID_A, outs) == NXR_ABSENT { t6 = 1 }
119 }
120 }
121
122 // ---- T8: TYPE SAFETY -- field A in the dirty record is a STR. Reading it as i64 must yield the
123 // DEFAULT, not a reinterpretation of whatever bytes happen to be there.
124 var t8: i64 = 0
125 if nxr_get_i64(d, od, RG_FID_A, RG_DEFAULT) == RG_DEFAULT { t8 = 1 }
126
127 var passes: i64 = 0
128 if t1 == 1 { passes = passes + 1 }
129 if t2 == 1 { passes = passes + 1 }
130 if t3 == 1 { passes = passes + 1 }
131 if t4 == 1 { passes = passes + 1 }
132 if t5 == 1 { passes = passes + 1 }
133 if t6 == 1 { passes = passes + 1 }
134 if t7 == 1 { passes = passes + 1 }
135 if t8 == 1 { passes = passes + 1 }
136 var green: i64 = 0
137 if passes == RG_TEETH { green = 1 }
138
139 gw("=== nx_record_gate -- NXR1 typed self-describing records (seq1326 rung 1) ===\n" as *u8)
140 rg_row("T1-typed-i64-roundtrip-by-field-id " as *u8, t1)
141 rg_row("T2-field-count-exact " as *u8, t2)
142 rg_row("T3-TAB-and-NEWLINE-in-value-survive " as *u8, t3)
143 rg_row("T4-absent-field-does-NOT-shift-others" as *u8, t4)
144 rg_row("T5-unknown-field-id-skipped-not-fatal" as *u8, t5)
145 rg_row("T6-truncated-record-refused-WHOLE " as *u8, t6)
146 rg_row("T7-NONVACUITY-B-findable-when-present" as *u8, t7)
147 rg_row("T8-type-mismatch-yields-default " as *u8, t8)
148 gw("verdict=" as *u8)
149 if green == 1 { gw("GREEN" as *u8) } else { gw("RED" as *u8) }
150 gw(" passes=" as *u8); gn(passes); gw("/" as *u8); gn(RG_TEETH); gw("\n" as *u8)
151
152 if green == 1 { return 0 }
153 return 1
154}