nx_array_ops_test.nx source
↩ module page · 222 lines · 7357 B
1// nx_array_ops_test.nx -- smoke for language-level array primitives.
2
3import "nx_syscalls.nx"
4import "nx_tier.nx"
5import "nx_array_ops.nx"
6
7func _fill_arr(arr: *nx_int, vals: *nx_int, n: nx_int) -> nx_int {
8 var i: nx_int = 0
9 while i < n {
10 arr[i] = vals[i]
11 i = i + 1
12 }
13 return 0
14}
15
16func main() -> nx_int {
17 // === Test 1: REDUCE SUM / PRODUCT / MIN / MAX ===
18 let a1: *nx_int = (sys_mmap(8 * NX_SIZEOF_NX_INT)) as *nx_int
19 a1[0] = 1
20 a1[1] = 2
21 a1[2] = 3
22 a1[3] = 4
23 a1[4] = 5
24 if nx_array_reduce(a1, 5, NX_REDUCE_SUM) != 15 { return 1 }
25 if nx_array_reduce(a1, 5, NX_REDUCE_PRODUCT) != 120 { return 2 }
26 if nx_array_reduce(a1, 5, NX_REDUCE_MIN) != 1 { return 3 }
27 if nx_array_reduce(a1, 5, NX_REDUCE_MAX) != 5 { return 4 }
28 if nx_array_reduce(a1, 5, NX_REDUCE_COUNT) != 5 { return 5 }
29 // Convenience wrappers
30 if nx_array_sum(a1, 5) != 15 { return 6 }
31 if nx_array_min(a1, 5) != 1 { return 7 }
32 if nx_array_max(a1, 5) != 5 { return 8 }
33 if nx_array_mean(a1, 5) != 3 { return 9 }
34 if nx_array_range(a1, 5) != 4 { return 10 }
35
36 // === Test 2: REDUCE on empty array ===
37 if nx_array_sum(a1, 0) != 0 { return 20 }
38 if nx_array_reduce(a1, 0, NX_REDUCE_PRODUCT) != 1 { return 21 } // identity
39
40 // === Test 3: REDUCE bitwise AND / OR / XOR ===
41 let a3: *nx_int = (sys_mmap(8 * NX_SIZEOF_NX_INT)) as *nx_int
42 a3[0] = 5 // 101
43 a3[1] = 3 // 011
44 a3[2] = 7 // 111
45 if nx_array_reduce(a3, 3, NX_REDUCE_AND) != 1 { return 30 } // 101 & 011 & 111 = 001
46 if nx_array_reduce(a3, 3, NX_REDUCE_OR) != 7 { return 31 } // 101 | 011 | 111 = 111
47 if nx_array_reduce(a3, 3, NX_REDUCE_XOR) != 1 { return 32 } // 101 ^ 011 ^ 111 = 001
48
49 // === Test 4: VARIANCE ===
50 // [2, 4, 4, 4, 5, 5, 7, 9] -> mean 5; pop variance 4
51 let a4: *nx_int = (sys_mmap(16 * NX_SIZEOF_NX_INT)) as *nx_int
52 a4[0] = 2
53 a4[1] = 4
54 a4[2] = 4
55 a4[3] = 4
56 a4[4] = 5
57 a4[5] = 5
58 a4[6] = 7
59 a4[7] = 9
60 if nx_array_variance_pop(a4, 8) != 4 { return 40 }
61
62 // === Test 5: FILTER on simple predicates ===
63 let a5: *nx_int = (sys_mmap(8 * NX_SIZEOF_NX_INT)) as *nx_int
64 a5[0] = -3
65 a5[1] = 4
66 a5[2] = 0
67 a5[3] = -1
68 a5[4] = 7
69 a5[5] = 8
70 let out5: *nx_int = (sys_mmap(8 * NX_SIZEOF_NX_INT)) as *nx_int
71
72 // GT_ZERO: keep 4, 7, 8
73 let n_gt: nx_int = nx_array_filter(a5, 6, NX_FILTER_GT_ZERO, 0, out5, 8)
74 if n_gt != 3 { return 50 }
75 if out5[0] != 4 { return 51 }
76 if out5[1] != 7 { return 52 }
77 if out5[2] != 8 { return 53 }
78
79 // LT_ZERO: keep -3, -1
80 let n_lt: nx_int = nx_array_filter(a5, 6, NX_FILTER_LT_ZERO, 0, out5, 8)
81 if n_lt != 2 { return 54 }
82
83 // EVEN: keep 4, 0, 8
84 let n_ev: nx_int = nx_array_filter(a5, 6, NX_FILTER_EVEN, 0, out5, 8)
85 if n_ev != 3 { return 55 }
86
87 // GT_PARAM with param=5: keep 7, 8
88 let n_gt5: nx_int = nx_array_filter(a5, 6, NX_FILTER_GT_PARAM, 5, out5, 8)
89 if n_gt5 != 2 { return 56 }
90
91 // count_matching shortcut
92 if nx_array_count_matching(a5, 6, NX_FILTER_NON_ZERO, 0) != 5 { return 57 }
93
94 // === Test 6: MAP operations ===
95 let a6: *nx_int = (sys_mmap(8 * NX_SIZEOF_NX_INT)) as *nx_int
96 a6[0] = -2
97 a6[1] = 0
98 a6[2] = 3
99 let out6: *nx_int = (sys_mmap(8 * NX_SIZEOF_NX_INT)) as *nx_int
100
101 // ABS: [2, 0, 3]
102 nx_array_map(a6, 3, NX_MAP_ABS, 0, out6)
103 if out6[0] != 2 { return 60 }
104 if out6[1] != 0 { return 61 }
105 if out6[2] != 3 { return 62 }
106
107 // SQUARE: [4, 0, 9]
108 nx_array_map(a6, 3, NX_MAP_SQUARE, 0, out6)
109 if out6[0] != 4 { return 63 }
110 if out6[2] != 9 { return 64 }
111
112 // MUL_PARAM with param=10: [-20, 0, 30]
113 nx_array_map(a6, 3, NX_MAP_MUL_PARAM, 10, out6)
114 if out6[0] != -20 { return 65 }
115 if out6[2] != 30 { return 66 }
116
117 // SIGN: [-1, 0, +1]
118 nx_array_map(a6, 3, NX_MAP_SIGN, 0, out6)
119 if out6[0] != -1 { return 67 }
120 if out6[1] != 0 { return 68 }
121 if out6[2] != 1 { return 69 }
122
123 // === Test 7: FIND / CONTAINS / argmin / argmax ===
124 let a7: *nx_int = (sys_mmap(8 * NX_SIZEOF_NX_INT)) as *nx_int
125 a7[0] = 7
126 a7[1] = 3
127 a7[2] = 9
128 a7[3] = 1
129 a7[4] = 5
130
131 if nx_array_find(a7, 5, 9) != 2 { return 70 }
132 if nx_array_find(a7, 5, 42) != -1 { return 71 }
133 if nx_array_contains(a7, 5, 5) != 1 { return 72 }
134 if nx_array_contains(a7, 5, 42) != 0 { return 73 }
135 if nx_array_argmin(a7, 5) != 3 { return 74 } // 1 is at index 3
136 if nx_array_argmax(a7, 5) != 2 { return 75 } // 9 is at index 2
137
138 // === Test 8: ALL / ANY ===
139 if nx_array_all(a1, 5, NX_FILTER_GT_ZERO, 0) != 1 { return 80 }
140 if nx_array_all(a5, 6, NX_FILTER_GT_ZERO, 0) != 0 { return 81 }
141 if nx_array_any(a5, 6, NX_FILTER_GT_ZERO, 0) != 1 { return 82 }
142 let zero_arr: *nx_int = (sys_mmap(4 * NX_SIZEOF_NX_INT)) as *nx_int
143 if nx_array_any(zero_arr, 4, NX_FILTER_NON_ZERO, 0) != 0 { return 83 }
144
145 // === Test 9: REVERSE (in-place) ===
146 let a9: *nx_int = (sys_mmap(8 * NX_SIZEOF_NX_INT)) as *nx_int
147 a9[0] = 1
148 a9[1] = 2
149 a9[2] = 3
150 a9[3] = 4
151 nx_array_reverse(a9, 4)
152 if a9[0] != 4 { return 90 }
153 if a9[1] != 3 { return 91 }
154 if a9[2] != 2 { return 92 }
155 if a9[3] != 1 { return 93 }
156
157 // === Test 10: SORT ASC ===
158 let a10: *nx_int = (sys_mmap(8 * NX_SIZEOF_NX_INT)) as *nx_int
159 a10[0] = 5
160 a10[1] = 2
161 a10[2] = 8
162 a10[3] = 1
163 a10[4] = 9
164 a10[5] = 3
165 nx_array_sort_asc(a10, 6)
166 if a10[0] != 1 { return 100 }
167 if a10[1] != 2 { return 101 }
168 if a10[2] != 3 { return 102 }
169 if a10[3] != 5 { return 103 }
170 if a10[4] != 8 { return 104 }
171 if a10[5] != 9 { return 105 }
172
173 // === Test 11: SORT DESC ===
174 a10[0] = 5
175 a10[1] = 2
176 a10[2] = 8
177 a10[3] = 1
178 a10[4] = 9
179 a10[5] = 3
180 nx_array_sort_desc(a10, 6)
181 if a10[0] != 9 { return 110 }
182 if a10[5] != 1 { return 111 }
183
184 // === Test 12: MEDIAN ===
185 let a12: *nx_int = (sys_mmap(8 * NX_SIZEOF_NX_INT)) as *nx_int
186 a12[0] = 5
187 a12[1] = 2
188 a12[2] = 8
189 a12[3] = 1
190 a12[4] = 9
191 let scratch: *nx_int = (sys_mmap(8 * NX_SIZEOF_NX_INT)) as *nx_int
192 // sorted = [1, 2, 5, 8, 9]; middle index 2 -> 5
193 if nx_array_median(a12, 5, scratch) != 5 { return 120 }
194
195 // === Test 13: PERCENTILE ===
196 // 50th percentile (q10=512) on [1,2,5,8,9] -> idx = floor(0.5 * 4) = 2 -> 5
197 if nx_array_percentile(a12, 5, 512, scratch) != 5 { return 130 }
198 // 0th -> 1
199 if nx_array_percentile(a12, 5, 0, scratch) != 1 { return 131 }
200 // 100th -> 9
201 if nx_array_percentile(a12, 5, 1024, scratch) != 9 { return 132 }
202
203 // === Test 14: UNIQUE_COUNT ===
204 let a14: *nx_int = (sys_mmap(8 * NX_SIZEOF_NX_INT)) as *nx_int
205 a14[0] = 1
206 a14[1] = 2
207 a14[2] = 1
208 a14[3] = 3
209 a14[4] = 2
210 a14[5] = 4
211 if nx_array_unique_count(a14, 6) != 4 { return 140 } // {1,2,3,4}
212
213 // === Test 15: sealed-enum validity ===
214 if nx_array_reduce_op_is_valid(NX_REDUCE_SUM) != 1 { return 150 }
215 if nx_array_reduce_op_is_valid(99) != 0 { return 151 }
216 if nx_array_filter_pred_is_valid(NX_FILTER_EVEN) != 1 { return 152 }
217 if nx_array_filter_pred_is_valid(99) != 0 { return 153 }
218 if nx_array_map_op_is_valid(NX_MAP_SQUARE) != 1 { return 154 }
219 if nx_array_map_op_is_valid(99) != 0 { return 155 }
220
221 return 0
222}