nx_langsem_gate.nx source
↩ module page · 155 lines · 9453 B
1// nx_langsem_gate.nx -- THE EXECUTABLE RECORD OF NISHILANG'S OWN SEMANTICS.
2//
3// WHY THIS EXISTS. Every fact below was learned by a seat the expensive way -- by a build failing,
4// by a test that quietly could not fail, or by an extraction that happened to work -- and then
5// written into prose that the next seat may or may not read. Prose is not a control. These are the
6// language's load-bearing behaviours, and until now NOTHING asserted them, so a compiler change
7// could alter one and the estate would find out through a silently wrong world, a silently
8// unshared static, or a comparison that never matches.
9//
10// Measured 2026-08-28 with nx_spendgate: no incumbent gates NishiLang semantics (nx_bless_compiler
11// self-deploys the compiler; nx_cc_equiv_gate proves an OPTIMISATION is equivalent; neither pins
12// the contract a source author writes against). So this is the missing referee, not a duplicate.
13//
14// WHAT IT DELIBERATELY DOES NOT PIN, stated so absence is not read as coverage:
15// * define-before-use. NishiLang is single-pass and the compiler REFUSES a const used above its
16// declaration; asserting a REFUSAL needs a fork of the compiler over a bad fixture, which is a
17// different (and heavier) gate than this in-process one. Named here as the owed rung.
18// * right-shift sign behaviour on negatives. I have no measured evidence for it in the record,
19// and a gate must not encode a guess: a tooth asserting the wrong answer would be worse than
20// no tooth, because it would read as coverage. Owed: measure it, then pin it.
21//
22// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
23import "nx_syscalls.nx"
24import "nx_gate_verdict.nx"
25import "nx_langsem_lib.nx"
26
27// the gate's OWN module static, to prove zero-initialisation on this side of the import too
28static LG_OWN: i64
29const LG_WRITE_A: i64 = 12345
30const LG_WRITE_B: i64 = 6789
31const LG_INTERNAL: i64 = 999
32
33func main() -> i64 {
34 let ctr: *i64 = gv_ctr()
35 gv_head("=== nx_langsem_gate -- NishiLang's own semantics, asserted not assumed ===" as *u8)
36
37 // ---- ZERO INITIALISATION -------------------------------------------------------------
38 // Every arena-and-static discipline in the estate assumes a static starts at 0 (nx_worldpipe
39 // guards its bake with `if WP_HYD == 0`, the engine calls a zero region "no overrides by
40 // construction"). If statics ever started as garbage, those guards would fire at random.
41 gv_puts(" own-static=" as *u8); gv_num(LG_OWN)
42 gv_puts(" lib-untouched-static=" as *u8); gv_num(ls_untouched()); gv_puts("\n" as *u8)
43 var t1: i64 = 0
44 if LG_OWN == 0 { if ls_untouched() == 0 { t1 = 1 } }
45 gv_check("statics-are-zero-initialised-in-both-modules" as *u8, t1, ctr)
46
47 // ---- CROSS-MODULE CONST VISIBILITY ---------------------------------------------------
48 var t2: i64 = 0
49 if LS_CONST_ANSWER == 424242 { t2 = 1 }
50 gv_check("importer-reads-a-const-declared-in-an-imported-lib" as *u8, t2, ctr)
51
52 // ---- CROSS-MODULE STATIC ASSIGNMENT: THE LOAD-BEARING ONE ----------------------------
53 // This is the fact the shared-core/base-class pattern rests on. nx_worldpipe_core owns
54 // WP_SEED and nx_worldpipe assigns it; if these were per-module copies the extracted core
55 // would generate terrain from a seed of 0 while its owner believed it had set one -- a
56 // silently wrong world, not a build error. Three legs: the importer's write is visible to
57 // the importer, it is visible INSIDE the declaring module, and a second write moves it (so
58 // the first result cannot be a coincidence of initial values).
59 LS_SHARED = LG_WRITE_A
60 let seen_here_a: i64 = LS_SHARED
61 let seen_there_a: i64 = ls_get()
62 LS_SHARED = LG_WRITE_B
63 let seen_here_b: i64 = LS_SHARED
64 let seen_there_b: i64 = ls_get()
65 gv_puts(" wrote " as *u8); gv_num(LG_WRITE_A)
66 gv_puts(" -> importer sees " as *u8); gv_num(seen_here_a)
67 gv_puts(", lib sees " as *u8); gv_num(seen_there_a)
68 gv_puts(" | wrote " as *u8); gv_num(LG_WRITE_B)
69 gv_puts(" -> importer sees " as *u8); gv_num(seen_here_b)
70 gv_puts(", lib sees " as *u8); gv_num(seen_there_b); gv_puts("\n" as *u8)
71 var t3: i64 = 0
72 if seen_here_a == LG_WRITE_A { if seen_here_b == LG_WRITE_B { t3 = 1 } }
73 gv_check("importer-may-ASSIGN-a-static-declared-in-an-imported-lib" as *u8, t3, ctr)
74 var t4: i64 = 0
75 if seen_there_a == LG_WRITE_A { if seen_there_b == LG_WRITE_B { t4 = 1 } }
76 gv_check("the-lib-SEES-the-importers-write-one-storage-not-a-copy" as *u8, t4, ctr)
77
78 // and the reverse direction: the lib writes, the importer sees it
79 ls_set(LG_INTERNAL)
80 var t5: i64 = 0
81 if LS_SHARED == LG_INTERNAL { t5 = 1 }
82 gv_check("the-importer-SEES-the-libs-write-same-storage-both-ways" as *u8, t5, ctr)
83
84 // ---- INTEGER DIVISION TRUNCATES TOWARD ZERO ------------------------------------------
85 // Not a curiosity: the estate has been bitten by it repeatedly. wc_er_flux is antisymmetric
86 // ONLY because truncation is toward zero; a threshold written `x > y*N/M` truncates the bar
87 // DOWNWARD (a whole latent false-pass class, debt 1785565607); and nx_softdyn's damping term
88 // (v*C)/SD_G truncates to a dead zone that made a measured plant three times less damped than
89 // its own coefficient implied. If division ever floored instead, every one of those changes
90 // meaning -- silently, in the direction of "still compiles, still runs".
91 let dpos: i64 = 7/2
92 let dneg: i64 = (0 - 7)/2
93 let mpos: i64 = 7%2
94 let mneg: i64 = (0 - 7)%2
95 gv_puts(" 7/2=" as *u8); gv_num(dpos)
96 gv_puts(" -7/2=" as *u8); gv_num(dneg)
97 gv_puts(" 7%2=" as *u8); gv_num(mpos)
98 gv_puts(" -7%2=" as *u8); gv_num(mneg); gv_puts("\n" as *u8)
99 var t6: i64 = 0
100 if dpos == 3 { if dneg == 0 - 3 { t6 = 1 } }
101 gv_check("integer-division-TRUNCATES-toward-zero-both-signs" as *u8, t6, ctr)
102 // NEGATIVE CONTROL, named so the gate-law census can see it: floor division would give -4.
103 // This tooth fails the day the language changes that, which is exactly when the estate's
104 // antisymmetry and threshold arithmetic would start lying.
105 var t7: i64 = 0
106 if dneg != 0 - 4 { t7 = 1 }
107 gv_check("neg-control-division-is-NOT-floor-semantics" as *u8, t7, ctr)
108 var t8: i64 = 0
109 if mpos == 1 { if mneg == 0 - 1 { t8 = 1 } }
110 gv_check("modulo-sign-FOLLOWS-the-dividend-consistent-with-truncation" as *u8, t8, ctr)
111
112 // the same arithmetic evaluated INSIDE the other module: a compiler that changed division
113 // only in one translation unit would be caught here and nowhere else in the estate
114 let probe: i64 = ls_divmod_probe(0 - 7, 2)
115 gv_puts(" cross-module divmod probe(-7,2)=" as *u8); gv_num(probe)
116 gv_puts(" (want " as *u8); gv_num((0 - 3)*100 + (0 - 1)); gv_puts(")\n" as *u8)
117 var t9: i64 = 0
118 if probe == (0 - 3)*100 + (0 - 1) { t9 = 1 }
119 gv_check("division-and-modulo-agree-ACROSS-a-module-boundary" as *u8, t9, ctr)
120
121 // ---- INLINE-CAST STRING INDEXING -----------------------------------------------------
122 // Pinned because its failure mode was the worst kind the estate has recorded: before the
123 // 2026-08-13 compiler fix, `("lit" as *u8)[j]` compiled clean and simply NEVER COMPARED EQUAL,
124 // so the only symptom was a test that quietly could not fail. It was found solely because a
125 // gv_bite tooth reported VACUOUS instead of passing. A regression here would be invisible
126 // again, so it gets a tooth of its own.
127 let c0: i64 = ("abc" as *u8)[0] as i64
128 let c1: i64 = ("abc" as *u8)[1] as i64
129 let c2: i64 = ("abc" as *u8)[2] as i64
130 gv_puts(" inline-cast index abc -> " as *u8); gv_num(c0)
131 gv_puts(" " as *u8); gv_num(c1)
132 gv_puts(" " as *u8); gv_num(c2); gv_puts(" (want 97 98 99)\n" as *u8)
133 var t10: i64 = 0
134 if c0 == 97 { if c1 == 98 { if c2 == 99 { t10 = 1 } } }
135 gv_check("inline-cast-string-literal-INDEXES-correctly" as *u8, t10, ctr)
136 // and it must EQUAL the same byte read through a hoisted binding -- the workaround the fix
137 // retired. If these two ever disagree the fix has regressed in one path only.
138 let hoisted: *u8 = "abc" as *u8
139 var t11: i64 = 0
140 if hoisted[1] as i64 == c1 { t11 = 1 }
141 gv_check("inline-cast-and-hoisted-binding-READ-THE-SAME-BYTE" as *u8, t11, ctr)
142
143 // ---- BITE CELL: the comparison itself must be capable of failing ---------------------
144 // The vacuity guard for this whole gate. If equality on these values could not distinguish,
145 // every tooth above would pass for free. bad = a comparison that MUST be false; good = one
146 // that MUST be true.
147 var bad: i64 = 0
148 var good: i64 = 0
149 if c1 == 97 { bad = 1 }
150 if c1 == 98 { good = 1 }
151 gv_bite("neg-control-equality-can-distinguish-97-from-98" as *u8, good, bad, ctr)
152
153 return gv_verdict("LANGSEM-GATE" as *u8, ctr,
154 "NishiLang's load-bearing semantics are now asserted, not folklore: statics zero-init, cross-module const AND static visibility with ONE storage in both directions (the fact the shared-core pattern rests on), truncation-toward-zero division with a named floor-semantics neg-control, and inline-cast string indexing pinned against the silent-miscompare class. NOT pinned yet, and said so: define-before-use refusal (needs a compiler fork) and right-shift sign on negatives (no measured evidence -- a guess would read as coverage)." as *u8)
155}