nx_sequence_ambig_test.nx source
↩ module page · 137 lines · 5044 B
1// nx_sequence_ambig_test.nx -- KAT for N sidecar bitset.
2//
3// expect_exit: 0
4//
5// license_tier: ORIGINAL
6
7import "nx_syscalls.nx"
8import "nx_const.nx"
9import "nx_sequence.nx"
10import "nx_sequence_ambig.nx"
11
12func main() -> i64 {
13
14 let bases: *u8 = sys_mmap(16)
15 let nbits: *u8 = sys_mmap(16)
16 let ascii: *u8 = sys_mmap(32)
17
18 // ============================================================
19 // Section A -- bit accessors round-trip.
20 // ============================================================
21
22 if dna_is_n(nbits, 0) != 0 { return 1 }
23 dna_set_n(nbits, 0, 1)
24 if dna_is_n(nbits, 0) != 1 { return 2 }
25 if (nbits[0] & 0xff) != 0x80 { return 3 } // bit 7 set = pos 0 MSB-first
26
27 dna_set_n(nbits, 2, 1)
28 if dna_is_n(nbits, 2) != 1 { return 4 }
29 if (nbits[0] & 0xff) != 0xA0 { return 5 } // bits 7,5 set = 1010 0000
30
31 dna_set_n(nbits, 0, 0)
32 if dna_is_n(nbits, 0) != 0 { return 6 }
33 if dna_is_n(nbits, 2) != 1 { return 7 } // unchanged
34 if (nbits[0] & 0xff) != 0x20 { return 8 } // only bit 5 set
35
36 // Cross-byte: position 9 sits in nbits[1] bit 6.
37 dna_set_n(nbits, 9, 1)
38 if dna_is_n(nbits, 9) != 1 { return 9 }
39 if (nbits[1] & 0xff) != 0x40 { return 10 }
40
41 // ============================================================
42 // Section B -- pack "ACNGT" (5 bases, N at pos 2).
43 // bases packing (N -> A code):
44 // byte 0 = A(00) C(01) A(00 for N) G(10) = 00 01 00 10 = 0x12
45 // byte 1 = T(11 high bits) + padding = 11 00 00 00 = 0xC0
46 // nbits[0] = bit 5 set (pos 2) = 0x20
47 // ============================================================
48
49 let b2: *u8 = sys_mmap(8)
50 let n2: *u8 = sys_mmap(8)
51 ascii[0] = 0x41 // A
52 ascii[1] = 0x43 // C
53 ascii[2] = NX_ASCII_DNA_N & 0xff // N
54 ascii[3] = 0x47 // G
55 ascii[4] = 0x54 // T
56 if dna_pack_ambig(ascii, 5, b2, n2) != 0 { return 20 }
57 if (b2[0] & 0xff) != 0x12 { return 21 }
58 if (b2[1] & 0xff) != 0xC0 { return 22 }
59 if (n2[0] & 0xff) != 0x20 { return 23 }
60
61 // dna_is_n queries.
62 if dna_is_n(n2, 0) != 0 { return 24 }
63 if dna_is_n(n2, 1) != 0 { return 25 }
64 if dna_is_n(n2, 2) != 1 { return 26 }
65 if dna_is_n(n2, 3) != 0 { return 27 }
66 if dna_is_n(n2, 4) != 0 { return 28 }
67
68 // ============================================================
69 // Section C -- round-trip via unpack restores 'N'.
70 // ============================================================
71
72 let asc_rt: *u8 = sys_mmap(16)
73 dna_unpack_ambig(b2, n2, 5, asc_rt)
74 if (asc_rt[0] & 0xff) != 0x41 { return 30 } // A
75 if (asc_rt[1] & 0xff) != 0x43 { return 31 } // C
76 if (asc_rt[2] & 0xff) != (NX_ASCII_DNA_N & 0xff) { return 32 } // N restored
77 if (asc_rt[3] & 0xff) != 0x47 { return 33 } // G
78 if (asc_rt[4] & 0xff) != 0x54 { return 34 } // T
79
80 // ============================================================
81 // Section D -- lowercase 'n' also accepted.
82 // ============================================================
83
84 let b3: *u8 = sys_mmap(8)
85 let n3: *u8 = sys_mmap(8)
86 ascii[0] = 0x41 // A
87 ascii[1] = 0x6E // 'n' lowercase
88 ascii[2] = 0x54 // T
89 if dna_pack_ambig(ascii, 3, b3, n3) != 0 { return 40 }
90 if dna_is_n(n3, 0) != 0 { return 41 }
91 if dna_is_n(n3, 1) != 1 { return 42 }
92 if dna_is_n(n3, 2) != 0 { return 43 }
93
94 // ============================================================
95 // Section E -- IUPAC partial-ambiguity codes REFUSED (G0.5b).
96 // Y / R / K / M / S / W / B / D / H / V all return -1.
97 // ============================================================
98
99 let b4: *u8 = sys_mmap(8)
100 let n4: *u8 = sys_mmap(8)
101 ascii[0] = 0x41 // A
102 ascii[1] = 0x59 // Y (C or T) -- not supported in G0.5a
103 if dna_pack_ambig(ascii, 2, b4, n4) != -1 { return 50 }
104
105 ascii[1] = 0x52 // R (A or G)
106 if dna_pack_ambig(ascii, 2, b4, n4) != -1 { return 51 }
107
108 ascii[1] = 0x4B // K (G or T)
109 if dna_pack_ambig(ascii, 2, b4, n4) != -1 { return 52 }
110
111 ascii[1] = 0x4D // M (A or C)
112 if dna_pack_ambig(ascii, 2, b4, n4) != -1 { return 53 }
113
114 // ============================================================
115 // Section F -- all-N pack.
116 // "NNNN" packed: bases byte = AAAA = 0x00; nbits = 11110000 = 0xF0.
117 // ============================================================
118
119 let b5: *u8 = sys_mmap(8)
120 let n5: *u8 = sys_mmap(8)
121 ascii[0] = NX_ASCII_DNA_N & 0xff
122 ascii[1] = NX_ASCII_DNA_N & 0xff
123 ascii[2] = NX_ASCII_DNA_N & 0xff
124 ascii[3] = NX_ASCII_DNA_N & 0xff
125 if dna_pack_ambig(ascii, 4, b5, n5) != 0 { return 60 }
126 if (b5[0] & 0xff) != 0x00 { return 61 }
127 if (n5[0] & 0xff) != 0xF0 { return 62 }
128
129 // ============================================================
130 // Section G -- empty input.
131 // ============================================================
132
133 if dna_pack_ambig(ascii, 0, b5, n5) != 0 { return 70 }
134 if dna_pack_ambig(ascii, -1, b5, n5) != -1 { return 71 }
135
136 return 0
137}