code wiki / (root) / nx_cigar_test.nx

nx_cigar_test.nx source

↩ module page · 174 lines · 7647 B

1// nx_cigar_test.nx -- KAT for CIGAR compression + ASCII serialiser. 2// 3// expect_exit: 0 4// 5// license_tier: ORIGINAL 6 7import "nx_syscalls.nx" 8import "nx_const.nx" 9import "nx_cigar.nx" 10 11func main() -> i64 { 12 13 let ops: *u8 = sys_mmap(64) 14 let codes: *u8 = sys_mmap(64) 15 let lens: *i64 = sys_mmap(128) as *i64 16 let ascii_buf: *u8 = sys_mmap(128) 17 let digits_buf: *u8 = sys_mmap(32) 18 19 // ============================================================ 20 // Section A -- nx_i64_to_ascii_digits. 21 // ============================================================ 22 23 if nx_i64_to_ascii_digits(0, digits_buf) != 1 { return 1 } 24 if (digits_buf[0] & 0xff) != 0x30 { return 2 } // '0' 25 26 if nx_i64_to_ascii_digits(7, digits_buf) != 1 { return 3 } 27 if (digits_buf[0] & 0xff) != 0x37 { return 4 } // '7' 28 29 if nx_i64_to_ascii_digits(42, digits_buf) != 2 { return 5 } 30 if (digits_buf[0] & 0xff) != 0x34 { return 6 } // '4' 31 if (digits_buf[1] & 0xff) != 0x32 { return 7 } // '2' 32 33 if nx_i64_to_ascii_digits(12345, digits_buf) != 5 { return 8 } 34 if (digits_buf[0] & 0xff) != 0x31 { return 9 } // '1' 35 if (digits_buf[1] & 0xff) != 0x32 { return 10 } // '2' 36 if (digits_buf[2] & 0xff) != 0x33 { return 11 } // '3' 37 if (digits_buf[3] & 0xff) != 0x34 { return 12 } // '4' 38 if (digits_buf[4] & 0xff) != 0x35 { return 13 } // '5' 39 40 if nx_i64_to_ascii_digits(-1, digits_buf) != 0 { return 14 } // refused 41 42 // ============================================================ 43 // Section B -- nx_cigar_code_to_ascii. 44 // ============================================================ 45 46 if nx_cigar_code_to_ascii(NX_CIGAR_M) != 0x4D { return 20 } 47 if nx_cigar_code_to_ascii(NX_CIGAR_I) != 0x49 { return 21 } 48 if nx_cigar_code_to_ascii(NX_CIGAR_D) != 0x44 { return 22 } 49 if nx_cigar_code_to_ascii(NX_CIGAR_N) != 0x4E { return 23 } 50 if nx_cigar_code_to_ascii(NX_CIGAR_S) != 0x53 { return 24 } 51 if nx_cigar_code_to_ascii(NX_CIGAR_EQ) != 0x3D { return 25 } 52 if nx_cigar_code_to_ascii(NX_CIGAR_X) != 0x58 { return 26 } 53 if nx_cigar_code_to_ascii(99) != 0x3F { return 27 } // '?' fallback 54 55 // ============================================================ 56 // Section C -- cigar_compress: single-op run. 57 // "MMMM" (4 ops) -> [(M, 4)], 1 group. 58 // ============================================================ 59 60 ops[0] = NX_CIGAR_M & 0xff 61 ops[1] = NX_CIGAR_M & 0xff 62 ops[2] = NX_CIGAR_M & 0xff 63 ops[3] = NX_CIGAR_M & 0xff 64 let n1: i64 = cigar_compress(ops, 4, codes, lens, 16) 65 if n1 != 1 { return 30 } 66 if (codes[0] & 0xff) != NX_CIGAR_M { return 31 } 67 if lens[0] != 4 { return 32 } 68 69 // ============================================================ 70 // Section D -- cigar_compress: multi-op runs. 71 // "MMMIIIIDD" (9 ops) -> [(M,3), (I,4), (D,2)], 3 groups. 72 // ============================================================ 73 74 ops[0]=NX_CIGAR_M & 0xff; ops[1]=NX_CIGAR_M & 0xff; ops[2]=NX_CIGAR_M & 0xff 75 ops[3]=NX_CIGAR_I & 0xff; ops[4]=NX_CIGAR_I & 0xff; ops[5]=NX_CIGAR_I & 0xff; ops[6]=NX_CIGAR_I & 0xff 76 ops[7]=NX_CIGAR_D & 0xff; ops[8]=NX_CIGAR_D & 0xff 77 let n2: i64 = cigar_compress(ops, 9, codes, lens, 16) 78 if n2 != 3 { return 40 } 79 if (codes[0] & 0xff) != NX_CIGAR_M { return 41 } 80 if lens[0] != 3 { return 42 } 81 if (codes[1] & 0xff) != NX_CIGAR_I { return 43 } 82 if lens[1] != 4 { return 44 } 83 if (codes[2] & 0xff) != NX_CIGAR_D { return 45 } 84 if lens[2] != 2 { return 46 } 85 86 // ============================================================ 87 // Section E -- cigar_compress: alternating ops (worst case). 88 // "MIMDM" -> 5 groups each length 1. 89 // ============================================================ 90 91 ops[0]=NX_CIGAR_M & 0xff 92 ops[1]=NX_CIGAR_I & 0xff 93 ops[2]=NX_CIGAR_M & 0xff 94 ops[3]=NX_CIGAR_D & 0xff 95 ops[4]=NX_CIGAR_M & 0xff 96 let n3: i64 = cigar_compress(ops, 5, codes, lens, 16) 97 if n3 != 5 { return 50 } 98 if lens[0] != 1 { return 51 } 99 if lens[4] != 1 { return 52 } 100 if (codes[0] & 0xff) != NX_CIGAR_M { return 53 } 101 if (codes[1] & 0xff) != NX_CIGAR_I { return 54 } 102 if (codes[2] & 0xff) != NX_CIGAR_M { return 55 } 103 if (codes[3] & 0xff) != NX_CIGAR_D { return 56 } 104 if (codes[4] & 0xff) != NX_CIGAR_M { return 57 } 105 106 // ============================================================ 107 // Section F -- empty + capacity overflow. 108 // ============================================================ 109 110 if cigar_compress(ops, 0, codes, lens, 16) != 0 { return 60 } 111 if cigar_compress(ops, -1, codes, lens, 16) != -1 { return 61 } 112 if cigar_compress(ops, 5, codes, lens, 0) != -1 { return 62 } 113 if cigar_compress(ops, 5, codes, lens, 2) != -1 { return 63 } // 5 alt groups need 5 cap 114 115 // ============================================================ 116 // Section G -- cigar_serialize: single group. 117 // [(M, 4)] -> "4M" (2 bytes). 118 // ============================================================ 119 120 codes[0] = NX_CIGAR_M & 0xff 121 lens[0] = 4 122 let s1: i64 = cigar_serialize(codes, lens, 1, ascii_buf, 64) 123 if s1 != 2 { return 70 } 124 if (ascii_buf[0] & 0xff) != 0x34 { return 71 } // '4' 125 if (ascii_buf[1] & 0xff) != 0x4D { return 72 } // 'M' 126 127 // ============================================================ 128 // Section H -- cigar_serialize: multi-group + multi-digit lengths. 129 // [(M, 12), (I, 1), (D, 3)] -> "12M1I3D" (7 bytes). 130 // ============================================================ 131 132 codes[0]=NX_CIGAR_M & 0xff; lens[0]=12 133 codes[1]=NX_CIGAR_I & 0xff; lens[1]=1 134 codes[2]=NX_CIGAR_D & 0xff; lens[2]=3 135 let s2: i64 = cigar_serialize(codes, lens, 3, ascii_buf, 64) 136 if s2 != 7 { return 80 } 137 if (ascii_buf[0] & 0xff) != 0x31 { return 81 } // '1' 138 if (ascii_buf[1] & 0xff) != 0x32 { return 82 } // '2' 139 if (ascii_buf[2] & 0xff) != 0x4D { return 83 } // 'M' 140 if (ascii_buf[3] & 0xff) != 0x31 { return 84 } // '1' 141 if (ascii_buf[4] & 0xff) != 0x49 { return 85 } // 'I' 142 if (ascii_buf[5] & 0xff) != 0x33 { return 86 } // '3' 143 if (ascii_buf[6] & 0xff) != 0x44 { return 87 } // 'D' 144 145 // ============================================================ 146 // Section I -- end-to-end: "MIMM" (the G1.0c gap-path backtrace 147 // for AGCT/ACT) compresses to [(M,1),(I,1),(M,2)] = 3 groups 148 // and serialises to "1M1I2M" (6 bytes). 149 // ============================================================ 150 151 ops[0]=NX_CIGAR_M & 0xff 152 ops[1]=NX_CIGAR_I & 0xff 153 ops[2]=NX_CIGAR_M & 0xff 154 ops[3]=NX_CIGAR_M & 0xff 155 let n4: i64 = cigar_compress(ops, 4, codes, lens, 16) 156 if n4 != 3 { return 90 } 157 let s3: i64 = cigar_serialize(codes, lens, n4, ascii_buf, 64) 158 if s3 != 6 { return 91 } 159 if (ascii_buf[0] & 0xff) != 0x31 { return 92 } // '1' 160 if (ascii_buf[1] & 0xff) != 0x4D { return 93 } // 'M' 161 if (ascii_buf[2] & 0xff) != 0x31 { return 94 } // '1' 162 if (ascii_buf[3] & 0xff) != 0x49 { return 95 } // 'I' 163 if (ascii_buf[4] & 0xff) != 0x32 { return 96 } // '2' 164 if (ascii_buf[5] & 0xff) != 0x4D { return 97 } // 'M' 165 166 // ============================================================ 167 // Section J -- empty serialise + capacity overflow. 168 // ============================================================ 169 170 if cigar_serialize(codes, lens, 0, ascii_buf, 64) != 0 { return 100 } 171 if cigar_serialize(codes, lens, 3, ascii_buf, 3) != -1 { return 101 } // "12M" alone is 3 bytes, can't fit "1I" 172 173 return 0 174}