1 # Comparing arrays of numbers.
5 array-equal?: # a: (addr array int), b: (addr array int) -> result/eax: boolean
8 # if (asize != b->size) return false
15 # if (c1 != c2) return false
16 # i+=4, curra+=4, currb+=4
37 8b/-> *(ebp+8) 6/r32/esi
39 8b/-> *(ebp+0xc) 7/r32/edi
40 # var asize/edx: int = a->size
43 # if (asize != b->size) return false
44 39/compare *edi 2/r32/edx
45 75/jump-if-!= $array-equal?:false/disp8
46 # var curra/esi: (addr byte) = a->data
47 81 0/subop/add %esi 4/imm32
48 # var currb/edi: (addr byte) = b->data
49 81 0/subop/add %edi 4/imm32
51 31/xor-with %ecx 1/r32/ecx
55 # if (i >= asize) return true
56 39/compare %ecx 2/r32/edx
57 7d/jump-if->= $array-equal?:true/disp8
58 # var vala/eax: int = *curra
60 # var valb/ebx: int = *currb
62 # if (vala != valb) return false
63 39/compare %eax 3/r32/ebx
64 75/jump-if-!= $array-equal?:false/disp8
66 81 0/subop/add %ecx 4/imm32
68 81 0/subop/add %esi 4/imm32
70 81 0/subop/add %edi 4/imm32
71 eb/jump $array-equal?:loop/disp8
73 b8/copy-to-eax 1/imm32
74 eb/jump $array-equal?:end/disp8
76 b8/copy-to-eax 0/imm32
89 test-compare-empty-with-empty-array:
93 # var ecx: (array _) = []
96 # var edx: (array _) = []
100 (array-equal? %ecx %edx) # => eax
101 (check-ints-equal %eax 1 "F - test-compare-empty-with-empty-array")
107 test-compare-empty-with-non-empty-array: # also checks size-mismatch code path
111 # var ecx: (array int) = [1]
115 # var edx: (array int) = []
119 (array-equal? %ecx %edx) # => eax
120 (check-ints-equal %eax 0 "F - test-compare-empty-with-non-empty-array")
126 test-compare-equal-arrays:
130 # var ecx: (array int) = [1, 2, 3]
134 68/push 0xc/imm32/size
136 # var edx: (array int) = [1, 2, 3]
140 68/push 0xc/imm32/size
143 (array-equal? %ecx %edx) # => eax
144 (check-ints-equal %eax 1 "F - test-compare-equal-arrays")
150 test-compare-inequal-arrays-equal-sizes:
154 # var ecx: (array int) = [1, 4, 3]
158 68/push 0xc/imm32/size
160 # var edx: (array int) = [1, 2, 3]
164 68/push 0xc/imm32/size
167 (array-equal? %ecx %edx) # => eax
168 (check-ints-equal %eax 0 "F - test-compare-inequal-arrays-equal-sizes")
174 _parse-array-of-ints: # ad: (addr allocation-descriptor), s: (addr array byte), out: (addr handle array int)
176 # end = &s->data[s->size]
180 # if (curr >= end) break
181 # curr = skip-chars-matching-in-slice(curr, end, ' ')
182 # if (curr >= end) break
183 # curr = skip-chars-not-matching-in-slice(curr, end, ' ')
185 # allocate-array(ad, size*4, out)
186 # var slice: slice = {s->data, 0}
187 # curr = lookup(out)->data
189 # if (slice->start >= end) break
190 # slice->start = skip-chars-matching-in-slice(slice->start, end, ' ')
191 # if (slice->start >= end) break
192 # slice->end = skip-chars-not-matching-in-slice(slice->start, end, ' ')
193 # *curr = parse-hex-int-from-slice(slice)
195 # slice->start = slice->end
209 8b/-> *(ebp+0xc) 6/r32/esi
210 # var curr/ecx: (addr byte) = s->data
211 8d/copy-address *(esi+4) 1/r32/ecx
212 # var end/edx: (addr byte) = &s->data[s->size]
216 01/add-to %edx 1/r32/ecx
217 # var size/ebx: int = 0
218 31/xor-with %ebx 3/r32/ebx
219 $_parse-array-of-ints:loop1:
220 # if (curr >= end) break
221 39/compare %ecx 2/r32/edx
222 73/jump-if-addr>= $_parse-array-of-ints:break1/disp8
223 # curr = skip-chars-matching-in-slice(curr, end, ' ')
224 (skip-chars-matching-in-slice %ecx %edx 0x20) # => eax
226 # if (curr >= end) break
227 39/compare %ecx 2/r32/edx
228 73/jump-if-addr>= $_parse-array-of-ints:break1/disp8
229 # curr = skip-chars-not-matching-in-slice(curr, end, ' ')
230 (skip-chars-not-matching-in-slice %ecx %edx 0x20) # => eax
233 81 0/subop/add %ebx 4/imm32
234 eb/jump $_parse-array-of-ints:loop1/disp8
235 $_parse-array-of-ints:break1:
236 (allocate-array *(ebp+8) %ebx *(ebp+0x10))
237 $_parse-array-of-ints:pass2:
238 # var slice/edi: slice = {s->data, 0}
240 8d/copy-address *(esi+4) 7/r32/edi
243 # curr = lookup(out)->data
244 8b/-> *(ebp+0x10) 0/r32/eax
245 (lookup *eax *(eax+4)) # => eax
246 8d/copy-address *(eax+4) 1/r32/ecx
247 $_parse-array-of-ints:loop2:
248 # if (slice->start >= end) break
249 39/compare *edi 2/r32/edx
250 73/jump-if-addr>= $_parse-array-of-ints:end/disp8
251 # slice->start = skip-chars-matching-in-slice(slice->start, end, ' ')
252 (skip-chars-matching-in-slice *edi %edx 0x20) # => eax
254 # if (slice->start >= end) break
255 39/compare *edi 2/r32/edx
256 73/jump-if-addr>= $_parse-array-of-ints:end/disp8
257 # slice->end = skip-chars-not-matching-in-slice(slice->start, end, ' ')
258 (skip-chars-not-matching-in-slice *edi %edx 0x20) # => eax
259 89/<- *(edi+4) 0/r32/eax
260 # *curr = parse-hex-int-from-slice(slice)
261 (parse-hex-int-from-slice %edi)
264 81 0/subop/add %ecx 4/imm32
265 # slice->start = slice->end
266 8b/-> *(edi+4) 0/r32/eax
268 eb/jump $_parse-array-of-ints:loop2/disp8
269 $_parse-array-of-ints:end:
271 81 0/subop/add %esp 8/imm32
272 # . restore registers
284 test-parse-array-of-ints:
288 # var h/esi: (handle array int)
292 # var ecx: (array int) = [1, 2, 3]
296 68/push 0xc/imm32/size
299 (_parse-array-of-ints Heap "1 2 3" %esi)
300 (lookup *esi *(esi+4)) # => eax
301 (array-equal? %ecx %eax) # => eax
302 (check-ints-equal %eax 1 "F - test-parse-array-of-ints")
308 test-parse-array-of-ints-empty:
309 # - empty string = empty array
318 (_parse-array-of-ints Heap "" %esi)
319 (lookup *esi *(esi+4)) # => eax
320 (check-ints-equal *eax 0 "F - test-parse-array-of-ints-empty")
326 test-parse-array-of-ints-just-whitespace:
327 # - just whitespace = empty array
336 (_parse-array-of-ints Heap Space %esi)
337 (lookup *esi *(esi+4)) # => eax
338 (check-ints-equal *eax 0 "F - test-parse-array-of-ints-just-whitespace")
344 test-parse-array-of-ints-extra-whitespace:
352 # var ecx: (array int) = [1, 2, 3]
356 68/push 0xc/imm32/size
359 (_parse-array-of-ints Heap " 1 2 3 " %esi)
360 (lookup *esi *(esi+4)) # => eax
361 (array-equal? %ecx %eax) # => eax
362 (check-ints-equal %eax 1 "F - test-parse-array-of-ints-extra-whitespace")
368 parse-array-of-ints: # s: (addr array byte), out: (addr handle array int)
373 (_parse-array-of-ints Heap *(ebp+8) *(ebp+0xc))
374 $parse-array-of-ints:end:
380 # helper for later tests
381 # compare an array with a string representation of an array literal
382 check-array-equal: # a: (addr array int), expected: (addr string), msg: (addr string)
393 # var b/eax: (addr array int) = parse-array-of-ints(Heap, expected)
394 (parse-array-of-ints *(ebp+0xc) %esi)
395 (lookup *esi *(esi+4)) # => eax
397 (array-equal? *(ebp+8) %eax)
398 (check-ints-equal %eax 1 *(ebp+0x10))
399 $check-array-equal:end:
400 # . restore registers
408 test-check-array-equal:
412 # var ecx: (array int) = [1, 2, 3]
416 68/push 0xc/imm32/size
419 (check-array-equal %ecx "1 2 3" "F - test-check-array-equal")
427 # length-prefixed string containing just a single space
428 Space: # (array byte)