code wiki / _hdl_build / nx_ascii_kat.nx

nx_ascii_kat.nx source

↩ module page · 93 lines · 4963 B

1// nx_ascii_kat.nx -- EXHAUSTIVE differential gate for nx_ascii (HONESTY SYSTEM weak point reach=267; used 2// across lexer/formatter/strconv/path -- a boundary bug there cascades). For ALL 256 byte values, each 3// classifier must equal the independently-computed ASCII ground truth -> catches every off-by-one at every 4// boundary at once (stronger than the in-file smoke). Self-validating: ground truth is inlined, not the organ. 5// license_tier: ORIGINAL expect_exit:0 6import "nx_syscalls.nx" 7import "nx_ascii.nx" 8 9func aw(s: *u8) -> i64 { var n:i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 10func an(v: i64) -> i64 { let b:*u8=sys_mmap(24); var m:i64=v; if m<0{sys_write(1,"-" as *u8,1);m=0-m} let t:*u8=sys_mmap(24); var k:i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var j:i64=0; while j<k{b[j]=t[k-1-j];j=j+1} sys_write(1,b,k); return 0 } 11 12// ground-truth predicates (independent of the organ) 13func gt_digit(c: i64) -> i64 { if c>=48 { if c<=57 { return 1 } } return 0 } 14func gt_lower(c: i64) -> i64 { if c>=97 { if c<=122 { return 1 } } return 0 } 15func gt_upper(c: i64) -> i64 { if c>=65 { if c<=90 { return 1 } } return 0 } 16func gt_alpha(c: i64) -> i64 { if gt_lower(c)==1 { return 1 } return gt_upper(c) } 17func gt_alnum(c: i64) -> i64 { if gt_alpha(c)==1 { return 1 } return gt_digit(c) } 18func gt_hex(c: i64) -> i64 { if gt_digit(c)==1 { return 1 } if c>=97 { if c<=102 { return 1 } } if c>=65 { if c<=70 { return 1 } } return 0 } 19func gt_space(c: i64) -> i64 { if c==32 { return 1 } if c==9 { return 1 } if c==10 { return 1 } if c==13 { return 1 } if c==11 { return 1 } if c==12 { return 1 } return 0 } 20func gt_print(c: i64) -> i64 { if c>=32 { if c<=126 { return 1 } } return 0 } 21func gt_id_start(c: i64) -> i64 { if gt_alpha(c)==1 { return 1 } if c==95 { return 1 } return 0 } 22func gt_id_cont(c: i64) -> i64 { if gt_alnum(c)==1 { return 1 } if c==95 { return 1 } return 0 } 23 24func main() -> i64 { 25 var pass: i64 = 0 26 27 // T1: is_digit / is_lower / is_upper exhaustive 28 var m1: i64 = 0 29 var c: i64 = 0 30 while c < 256 { 31 if nx_ascii_is_digit(c) != gt_digit(c) { m1 = m1 + 1 } 32 if nx_ascii_is_lower(c) != gt_lower(c) { m1 = m1 + 1 } 33 if nx_ascii_is_upper(c) != gt_upper(c) { m1 = m1 + 1 } 34 c = c + 1 35 } 36 if m1 == 0 { pass = pass + 1; aw("T1 digit/lower/upper (256x3) PASS\n" as *u8) } else { aw("T1 FAIL mismatches=" as *u8); an(m1); aw("\n" as *u8) } 37 38 // T2: is_alpha / is_alnum exhaustive 39 var m2: i64 = 0 40 c = 0 41 while c < 256 { 42 if nx_ascii_is_alpha(c) != gt_alpha(c) { m2 = m2 + 1 } 43 if nx_ascii_is_alnum(c) != gt_alnum(c) { m2 = m2 + 1 } 44 c = c + 1 45 } 46 if m2 == 0 { pass = pass + 1; aw("T2 alpha/alnum PASS\n" as *u8) } else { aw("T2 FAIL mismatches=" as *u8); an(m2); aw("\n" as *u8) } 47 48 // T3: is_id_start / is_id_cont exhaustive (the lexer's identifier rule) 49 var m3: i64 = 0 50 c = 0 51 while c < 256 { 52 if nx_ascii_is_id_start(c) != gt_id_start(c) { m3 = m3 + 1 } 53 if nx_ascii_is_id_cont(c) != gt_id_cont(c) { m3 = m3 + 1 } 54 c = c + 1 55 } 56 if m3 == 0 { pass = pass + 1; aw("T3 id_start/id_cont PASS\n" as *u8) } else { aw("T3 FAIL mismatches=" as *u8); an(m3); aw("\n" as *u8) } 57 58 // T4: is_space / is_print exhaustive 59 var m4: i64 = 0 60 c = 0 61 while c < 256 { 62 if nx_ascii_is_space(c) != gt_space(c) { m4 = m4 + 1 } 63 if nx_ascii_is_print(c) != gt_print(c) { m4 = m4 + 1 } 64 c = c + 1 65 } 66 if m4 == 0 { pass = pass + 1; aw("T4 space/print PASS\n" as *u8) } else { aw("T4 FAIL mismatches=" as *u8); an(m4); aw("\n" as *u8) } 67 68 // T5: is_hex exhaustive (a wrong bound here silently corrupts every hex/base16 decode) 69 var m5: i64 = 0 70 c = 0 71 while c < 256 { if nx_ascii_is_hex(c) != gt_hex(c) { m5 = m5 + 1 } c = c + 1 } 72 if m5 == 0 { pass = pass + 1; aw("T5 hex PASS\n" as *u8) } else { aw("T5 FAIL mismatches=" as *u8); an(m5); aw("\n" as *u8) } 73 74 // T6: to_lower / to_upper -- correct mapping + inverse consistency + idempotence 75 var m6: i64 = 0 76 c = 0 77 while c < 256 { 78 var el: i64 = c; if gt_upper(c)==1 { el = c + 32 } 79 var eu: i64 = c; if gt_lower(c)==1 { eu = c - 32 } 80 if nx_ascii_to_lower(c) != el { m6 = m6 + 1 } 81 if nx_ascii_to_upper(c) != eu { m6 = m6 + 1 } 82 // idempotence: lowering a lowered char is stable 83 if nx_ascii_to_lower(nx_ascii_to_lower(c)) != nx_ascii_to_lower(c) { m6 = m6 + 1 } 84 if nx_ascii_to_upper(nx_ascii_to_upper(c)) != nx_ascii_to_upper(c) { m6 = m6 + 1 } 85 c = c + 1 86 } 87 if m6 == 0 { pass = pass + 1; aw("T6 to_lower/to_upper (map+idempotent) PASS\n" as *u8) } else { aw("T6 FAIL mismatches=" as *u8); an(m6); aw("\n" as *u8) } 88 89 aw("NX-ASCII-KAT " as *u8); an(pass); aw("/6 (exhaustive over all 256 bytes)" as *u8) 90 if pass == 6 { aw(" GREEN\n" as *u8); return 0 } 91 aw(" RED\n" as *u8) 92 return 1 93}