code wiki / _hdl_build / nx_term_kat.nx

nx_term_kat.nx source

↩ module page · 51 lines · 1798 B

1// nx_term_kat.nx -- KAT (known-answer test) for the unterminated-final-block 2// bug class, distilled from the nx_ttt_evaluate draw-detect miscompile 3// (2026-06-09). The trap shape: a VOID function whose body ends with a 4// while loop that contains an early-return if. The buggy frontend left the 5// loop-exit block (holding the post-loop stores) with NO terminator, so it 6// FELL THROUGH into the if-body block emitted after it -- the post-loop 7// stores were silently clobbered by the early-return stores. 8// 9// This KAT must stay GREEN forever. It prints a marker AND exits 0, so it 10// is judgeable through marker-grep even on channels where $? lies (see 11// feedback-wsl-exit-code-judging-2026-06-09). 12// 13// license_tier: ORIGINAL 14import "nx_syscalls.nx" 15 16// The trap-shaped function: scan 9 cells; early-return ONGOING(0) on any 17// empty cell; post-loop (board full) store DRAW(2). Mirrors evaluate's tail. 18func tk_scan(s: *i64) { 19 var i: i64 = 0 20 while i < 9 { 21 if s[i] == 0 { 22 s[10] = 0 23 s[11] = 0 24 return 25 } 26 i = i + 1 27 } 28 s[10] = 2 29 s[11] = 0 30} 31 32func main() -> i64 { 33 let s: *i64 = sys_mmap(8 * 12) as *i64 34 35 // Case 1: full board -> post-loop DRAW store must SURVIVE (the bug 36 // clobbered it back to 0 via fallthrough). 37 var i: i64 = 0 38 while i < 9 { s[i] = 1 + (i % 2); i = i + 1 } 39 s[10] = 0 - 1 40 tk_scan(s) 41 if s[10] != 2 { sys_write(1, "TERM-KAT FAIL case1 (draw clobbered)\n" as *u8, 37); return 1 } 42 43 // Case 2: one empty cell -> early-return ONGOING path still correct. 44 s[4] = 0 45 s[10] = 0 - 1 46 tk_scan(s) 47 if s[10] != 0 { sys_write(1, "TERM-KAT FAIL case2 (ongoing wrong)\n" as *u8, 36); return 2 } 48 49 sys_write(1, "TERM-KAT ALL-PASS\n" as *u8, 18) 50 return 0 51}