From 3350c34a74844e21ea69077e01efff3bae64bdcd Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Tue, 23 Mar 2021 17:31:08 -0700 Subject: . --- html/linux/311decimal-int.subx.html | 698 ++++++++++++++++++++++++++++++++++++ 1 file changed, 698 insertions(+) create mode 100644 html/linux/311decimal-int.subx.html (limited to 'html/linux/311decimal-int.subx.html') diff --git a/html/linux/311decimal-int.subx.html b/html/linux/311decimal-int.subx.html new file mode 100644 index 00000000..f6180bdb --- /dev/null +++ b/html/linux/311decimal-int.subx.html @@ -0,0 +1,698 @@ + + + + +Mu - linux/311decimal-int.subx + + + + + + + + + + +https://github.com/akkartik/mu/blob/main/linux/311decimal-int.subx +
+  1 # Helpers for decimal ints.
+  2 
+  3 # if slice doesn't contain a decimal number, return 0
+  4 parse-decimal-int-from-slice:  # in: (addr slice) -> out/eax: int
+  5     # . prologue
+  6     55/push-ebp
+  7     89/<- %ebp 4/r32/esp
+  8     # . save registers
+  9     51/push-ecx
+ 10     # ecx = in
+ 11     8b/-> *(ebp+8) 1/r32/ecx
+ 12     #
+ 13     (parse-decimal-int-helper *ecx *(ecx+4))  # => eax
+ 14 $parse-decimal-int-from-slice:end:
+ 15     # . restore registers
+ 16     59/pop-to-ecx
+ 17     # . epilogue
+ 18     89/<- %esp 5/r32/ebp
+ 19     5d/pop-to-ebp
+ 20     c3/return
+ 21 
+ 22 # if slice doesn't contain a decimal number, return 0
+ 23 parse-decimal-int:  # in: (addr array byte) -> result/eax: int
+ 24     # . prologue
+ 25     55/push-ebp
+ 26     89/<- %ebp 4/r32/esp
+ 27     # . save registers
+ 28     51/push-ecx
+ 29     52/push-edx
+ 30     # eax = in
+ 31     8b/-> *(ebp+8) 0/r32/eax
+ 32     # var start/ecx: (addr byte) = &in->data
+ 33     8d/copy-address *(eax+4) 1/r32/ecx
+ 34     # var end/edx: (addr byte) = &in->data[in->size]
+ 35     8b/-> *eax 2/r32/edx
+ 36     8d/copy-address *(eax+edx+4) 2/r32/edx
+ 37     #
+ 38     (parse-decimal-int-helper %ecx %edx)  # => eax
+ 39 $parse-decimal-int:end:
+ 40     # . restore registers
+ 41     5a/pop-to-edx
+ 42     59/pop-to-ecx
+ 43     # . epilogue
+ 44     89/<- %esp 5/r32/ebp
+ 45     5d/pop-to-ebp
+ 46     c3/return
+ 47 
+ 48 parse-decimal-int-from-stream:  # in: (addr stream byte) -> result/eax: int
+ 49     # . prologue
+ 50     55/push-ebp
+ 51     89/<- %ebp 4/r32/esp
+ 52     # . save registers
+ 53     51/push-ecx
+ 54     52/push-edx
+ 55     # eax = in
+ 56     8b/-> *(ebp+8) 0/r32/eax
+ 57     # var start/ecx: (addr byte) = &in->data[in->read]
+ 58     8b/-> *(eax+4) 1/r32/ecx
+ 59     8d/copy-address *(eax+ecx+0xc) 1/r32/ecx
+ 60     # var end/edx: (addr byte) = &in->data[in->write]
+ 61     8b/-> *eax 2/r32/edx
+ 62     8d/copy-address *(eax+edx+0xc) 2/r32/edx
+ 63     # trim a trailing newline
+ 64     {
+ 65       # speculatively trim
+ 66       4a/decrement-edx
+ 67       # if it's a newline, break
+ 68       8a/byte-> *edx 0/r32/eax
+ 69       81 4/subop/and %eax 0xff/imm32
+ 70       3d/compare-eax-and 0xa/imm32/newline
+ 71       74/jump-if-= break/disp8
+ 72       # not a newline, so restore it
+ 73       42/increment-edx
+ 74     }
+ 75     #
+ 76     (parse-decimal-int-helper %ecx %edx)  # => eax
+ 77 $parse-decimal-int-from-stream:end:
+ 78     # . restore registers
+ 79     5a/pop-to-edx
+ 80     59/pop-to-ecx
+ 81     # . epilogue
+ 82     89/<- %esp 5/r32/ebp
+ 83     5d/pop-to-ebp
+ 84     c3/return
+ 85 
+ 86 parse-decimal-int-helper:  # start: (addr byte), end: (addr byte) -> result/eax: int
+ 87     # . prologue
+ 88     55/push-ebp
+ 89     89/<- %ebp 4/r32/esp
+ 90     # . save registers
+ 91     51/push-ecx
+ 92     52/push-edx
+ 93     53/push-ebx
+ 94     56/push-esi
+ 95     57/push-edi
+ 96     # var curr/esi: (addr byte) = start
+ 97     8b/-> *(ebp+8) 6/r32/esi
+ 98     # edi = end
+ 99     8b/-> *(ebp+0xc) 7/r32/edi
+100     # var negate?/edx: boolean = false
+101     ba/copy-to-edx 0/imm32/false
+102     # if (*curr == '-') ++curr, negate = true
+103     {
+104 $parse-decimal-int-helper:negative:
+105       b8/copy-to-eax 0/imm32
+106       8a/copy-byte *esi 0/r32/AL
+107       3d/compare-eax-and 0x2d/imm32/-
+108       75/jump-if-!= break/disp8
+109       # . ++curr
+110       46/increment-esi
+111       # . negate = true
+112       ba/copy-to-edx  1/imm32/true
+113     }
+114     # spill negate?
+115     52/push-edx
+116     # var result/eax: int = 0
+117     b8/copy-to-eax 0/imm32
+118     # var digit/ecx: int = 0
+119     b9/copy-to-ecx 0/imm32
+120     # const TEN/ebx: int = 10
+121     bb/copy-to-ebx 0xa/imm32
+122     {
+123 $parse-decimal-int-helper:loop:
+124       # if (curr >= in->end) break
+125       39/compare %esi 7/r32/edi
+126       73/jump-if-addr>= break/disp8
+127       # if !decimal-digit?(*curr) return 0
+128       8a/copy-byte *esi 1/r32/CL
+129       50/push-eax
+130       (decimal-digit? %ecx)  # => eax
+131       {
+132         3d/compare-eax-and 0/imm32/false
+133         75/jump-if-!= break/disp8
+134         58/pop-to-eax
+135         b8/copy-to-eax 0/imm32
+136         eb/jump $parse-decimal-int-helper:negate/disp8
+137       }
+138       58/pop-to-eax
+139       # digit = from-decimal-char(*curr)
+140       81 5/subop/subtract %ecx 0x30/imm32/zero
+141       # TODO: error checking
+142       # result = result * 10 + digit
+143       ba/copy-to-edx 0/imm32
+144       f7 4/subop/multiply-into-edx-eax %ebx
+145       # TODO: check edx for overflow
+146       01/add %eax 1/r32/ecx
+147       # ++curr
+148       46/increment-esi
+149       #
+150       eb/jump loop/disp8
+151     }
+152 $parse-decimal-int-helper:negate:
+153     # if (negate?) result = -result
+154     5a/pop-to-edx
+155     {
+156       81 7/subop/compare %edx 0/imm32/false
+157       74/jump-if-= break/disp8
+158       f7 3/subop/negate %eax
+159     }
+160 $parse-decimal-int-helper:end:
+161     # . restore registers
+162     5f/pop-to-edi
+163     5e/pop-to-esi
+164     5b/pop-to-ebx
+165     5a/pop-to-edx
+166     59/pop-to-ecx
+167     # . epilogue
+168     89/<- %esp 5/r32/ebp
+169     5d/pop-to-ebp
+170     c3/return
+171 
+172 test-parse-decimal-int-from-slice-single-digit:
+173     # . prologue
+174     55/push-ebp
+175     89/<- %ebp 4/r32/esp
+176     # . save registers
+177     50/push-eax
+178     51/push-ecx
+179     # (eax..ecx) = "3"
+180     b8/copy-to-eax "3"/imm32
+181     8b/-> *eax 1/r32/ecx
+182     8d/copy-address *(eax+ecx+4) 1/r32/ecx
+183     05/add-to-eax 4/imm32
+184     # var slice/ecx: slice = {eax, ecx}
+185     51/push-ecx
+186     50/push-eax
+187     89/<- %ecx 4/r32/esp
+188     #
+189     (parse-decimal-int-from-slice %ecx)  # => eax
+190     (check-ints-equal %eax 3 "F - test-parse-decimal-int-from-slice-single-digit")
+191 $test-parse-decimal-int-helper-single-digit:end:
+192     # . restore registers
+193     59/pop-to-ecx
+194     58/pop-to-eax
+195     # . epilogue
+196     89/<- %esp 5/r32/ebp
+197     5d/pop-to-ebp
+198     c3/return
+199 
+200 test-parse-decimal-int-from-slice-multi-digit:
+201     # . prologue
+202     55/push-ebp
+203     89/<- %ebp 4/r32/esp
+204     # . save registers
+205     50/push-eax
+206     51/push-ecx
+207     # (eax..ecx) = "34"
+208     b8/copy-to-eax "34"/imm32
+209     8b/-> *eax 1/r32/ecx
+210     8d/copy-address *(eax+ecx+4) 1/r32/ecx
+211     05/add-to-eax 4/imm32
+212     # var slice/ecx: slice = {eax, ecx}
+213     51/push-ecx
+214     50/push-eax
+215     89/<- %ecx 4/r32/esp
+216     #
+217     (parse-decimal-int-from-slice %ecx)  # => eax
+218     (check-ints-equal %eax 0x22 "F - test-parse-decimal-int-from-slice-multi-digit")  # 34 in hex
+219 $test-parse-decimal-int-helper-multi-digit:end:
+220     # . restore registers
+221     59/pop-to-ecx
+222     58/pop-to-eax
+223     # . epilogue
+224     89/<- %esp 5/r32/ebp
+225     5d/pop-to-ebp
+226     c3/return
+227 
+228 test-parse-decimal-int-from-slice-zero:
+229     # . prologue
+230     55/push-ebp
+231     89/<- %ebp 4/r32/esp
+232     # . save registers
+233     50/push-eax
+234     51/push-ecx
+235     # (eax..ecx) = "00"
+236     b8/copy-to-eax "00"/imm32
+237     8b/-> *eax 1/r32/ecx
+238     8d/copy-address *(eax+ecx+4) 1/r32/ecx
+239     05/add-to-eax 4/imm32
+240     # var slice/ecx: slice = {eax, ecx}
+241     51/push-ecx
+242     50/push-eax
+243     89/<- %ecx 4/r32/esp
+244     #
+245     (parse-decimal-int-from-slice %ecx)  # => eax
+246     (check-ints-equal %eax 0 "F - test-parse-decimal-int-from-slice-zero")
+247 $test-parse-decimal-int-helper-zero:end:
+248     # . restore registers
+249     59/pop-to-ecx
+250     58/pop-to-eax
+251     # . epilogue
+252     89/<- %esp 5/r32/ebp
+253     5d/pop-to-ebp
+254     c3/return
+255 
+256 test-parse-decimal-int-from-slice-negative:
+257     # . prologue
+258     55/push-ebp
+259     89/<- %ebp 4/r32/esp
+260     # . save registers
+261     50/push-eax
+262     51/push-ecx
+263     # (eax..ecx) = "-3"
+264     b8/copy-to-eax "-3"/imm32
+265     8b/-> *eax 1/r32/ecx
+266     8d/copy-address *(eax+ecx+4) 1/r32/ecx
+267     05/add-to-eax 4/imm32
+268     # var slice/ecx: slice = {eax, ecx}
+269     51/push-ecx
+270     50/push-eax
+271     89/<- %ecx 4/r32/esp
+272     #
+273     (parse-decimal-int-from-slice %ecx)  # => eax
+274     (check-ints-equal %eax -3 "F - test-parse-decimal-int-from-slice-negative")
+275 $test-parse-decimal-int-helper-negative:end:
+276     # . restore registers
+277     59/pop-to-ecx
+278     58/pop-to-eax
+279     # . epilogue
+280     89/<- %esp 5/r32/ebp
+281     5d/pop-to-ebp
+282     c3/return
+283 
+284 test-parse-decimal-int-from-slice-multi-digit-negative:
+285     # . prologue
+286     55/push-ebp
+287     89/<- %ebp 4/r32/esp
+288     # . save registers
+289     50/push-eax
+290     51/push-ecx
+291     # (eax..ecx) = "-32"
+292     b8/copy-to-eax "-32"/imm32
+293     8b/-> *eax 1/r32/ecx
+294     8d/copy-address *(eax+ecx+4) 1/r32/ecx
+295     05/add-to-eax 4/imm32
+296     # var slice/ecx: slice = {eax, ecx}
+297     51/push-ecx
+298     50/push-eax
+299     89/<- %ecx 4/r32/esp
+300     #
+301     (parse-decimal-int-from-slice %ecx)  # => eax
+302     (check-ints-equal %eax -0x20 "F - test-parse-decimal-int-from-slice-multi-digit-negative")  # -32 in hex
+303 $test-parse-decimal-int-helper-multi-digit-negative:end:
+304     # . restore registers
+305     59/pop-to-ecx
+306     58/pop-to-eax
+307     # . epilogue
+308     89/<- %esp 5/r32/ebp
+309     5d/pop-to-ebp
+310     c3/return
+311 
+312 decimal-size:  # n: int -> result/eax: int
+313     # pseudocode:
+314     #   edi = 0
+315     #   eax = n
+316     #   if eax < 0
+317     #     ++edi  # for '-'
+318     #     negate eax
+319     #   while true
+320     #     edx = 0
+321     #     eax, edx = eax/10, eax%10
+322     #     ++edi
+323     #     if (eax == 0) break
+324     #   eax = edi
+325     #
+326     # . prologue
+327     55/push-ebp
+328     89/<- %ebp 4/r32/esp
+329     # . save registers
+330     51/push-ecx
+331     52/push-edx
+332     57/push-edi
+333     # edi = 0
+334     bf/copy-to-edi 0/imm32
+335     # eax = n
+336     8b/-> *(ebp+8) 0/r32/eax
+337     # if (n < 0) negate n, increment edi
+338     {
+339       3d/compare-eax-with 0/imm32
+340       7d/jump-if->= break/disp8
+341       f7 3/subop/negate %eax
+342       47/increment-edi
+343     }
+344     # const ten/ecx = 10
+345     b9/copy-to-ecx  0xa/imm32
+346     {
+347       ba/copy-to-edx 0/imm32
+348       f7 7/subop/idiv-edx-eax-by %ecx  # eax = edx:eax/10; edx = edx:eax%10
+349       47/increment-edi
+350       3d/compare-eax-and 0/imm32
+351       75/jump-if-!= loop/disp8
+352     }
+353 $decimal-size:end:
+354     89/<- %eax 7/r32/edi
+355     # . restore registers
+356     5f/pop-to-edi
+357     5a/pop-to-edx
+358     59/pop-to-ecx
+359     # . epilogue
+360     89/<- %esp 5/r32/ebp
+361     5d/pop-to-ebp
+362     c3/return
+363 
+364 test-decimal-size-of-zero:
+365     # . prologue
+366     55/push-ebp
+367     89/<- %ebp 4/r32/esp
+368     #
+369     (decimal-size 0)  # => eax
+370     (check-ints-equal %eax 1 "F - test-decimal-size-of-zero")
+371 $test-decimal-size-of-zero:end:
+372     # . epilogue
+373     89/<- %esp 5/r32/ebp
+374     5d/pop-to-ebp
+375     c3/return
+376 
+377 test-decimal-size-single-digit:
+378     # . prologue
+379     55/push-ebp
+380     89/<- %ebp 4/r32/esp
+381     #
+382     (decimal-size 4)  # => eax
+383     (check-ints-equal %eax 1 "F - test-decimal-size-single-digit")
+384 $test-decimal-size-single-digit:end:
+385     # . epilogue
+386     89/<- %esp 5/r32/ebp
+387     5d/pop-to-ebp
+388     c3/return
+389 
+390 test-decimal-size-multi-digit:
+391     # . prologue
+392     55/push-ebp
+393     89/<- %ebp 4/r32/esp
+394     #
+395     (decimal-size 0xa)  # => eax
+396     (check-ints-equal %eax 2 "F - test-decimal-size-multi-digit")
+397 $test-decimal-size-multi-digit:end:
+398     # . epilogue
+399     89/<- %esp 5/r32/ebp
+400     5d/pop-to-ebp
+401     c3/return
+402 
+403 test-decimal-size-single-digit-negative:
+404     # . prologue
+405     55/push-ebp
+406     89/<- %ebp 4/r32/esp
+407     #
+408     (decimal-size -4)  # => eax
+409     (check-ints-equal %eax 2 "F - test-decimal-size-single-digit-negative")
+410 $test-decimal-size-single-digit-negative:end:
+411     # . epilogue
+412     89/<- %esp 5/r32/ebp
+413     5d/pop-to-ebp
+414     c3/return
+415 
+416 test-decimal-size-multi-digit-negative:
+417     # . prologue
+418     55/push-ebp
+419     89/<- %ebp 4/r32/esp
+420     #
+421     (decimal-size -0xa)  # => eax
+422     (check-ints-equal %eax 3 "F - test-decimal-size-multi-digit-negative")
+423 $test-decimal-size-multi-digit-negative:end:
+424     # . epilogue
+425     89/<- %esp 5/r32/ebp
+426     5d/pop-to-ebp
+427     c3/return
+428 
+429 _parse-array-of-decimal-ints:  # ad: (addr allocation-descriptor), s: (addr array byte), out: (addr handle array int)
+430     # pseudocode
+431     #   end = &s->data[s->size]
+432     #   curr = s->data
+433     #   size = 0
+434     #   while true
+435     #     if (curr >= end) break
+436     #     curr = skip-chars-matching-in-slice(curr, end, ' ')
+437     #     if (curr >= end) break
+438     #     curr = skip-chars-not-matching-in-slice(curr, end, ' ')
+439     #     ++size
+440     #   allocate-array(ad, size*4, out)
+441     #   var slice: slice = {s->data, 0}
+442     #   curr = lookup(out)->data
+443     #   while true
+444     #     if (slice->start >= end) break
+445     #     slice->start = skip-chars-matching-in-slice(slice->start, end, ' ')
+446     #     if (slice->start >= end) break
+447     #     slice->end = skip-chars-not-matching-in-slice(slice->start, end, ' ')
+448     #     *curr = parse-hex-int-from-slice(slice)
+449     #     curr += 4
+450     #     slice->start = slice->end
+451     #   return result
+452     #
+453     # . prologue
+454     55/push-ebp
+455     89/<- %ebp 4/r32/esp
+456     # . save registers
+457     50/push-eax
+458     51/push-ecx
+459     52/push-edx
+460     53/push-ebx
+461     56/push-esi
+462     57/push-edi
+463     # esi = s
+464     8b/-> *(ebp+0xc) 6/r32/esi
+465     # var curr/ecx: (addr byte) = s->data
+466     8d/copy-address *(esi+4) 1/r32/ecx
+467     # var end/edx: (addr byte) = &s->data[s->size]
+468     # . edx = s->size
+469     8b/-> *esi 2/r32/edx
+470     # . edx += curr
+471     01/add-to %edx 1/r32/ecx
+472     # var size/ebx: int = 0
+473     31/xor-with %ebx 3/r32/ebx
+474 $_parse-array-of-decimal-ints:loop1:
+475     # if (curr >= end) break
+476     39/compare %ecx 2/r32/edx
+477     73/jump-if-addr>= $_parse-array-of-decimal-ints:break1/disp8
+478     # curr = skip-chars-matching-in-slice(curr, end, ' ')
+479     (skip-chars-matching-in-slice %ecx %edx 0x20)  # => eax
+480     89/<- %ecx 0/r32/eax
+481     # if (curr >= end) break
+482     39/compare %ecx 2/r32/edx
+483     73/jump-if-addr>= $_parse-array-of-decimal-ints:break1/disp8
+484     # curr = skip-chars-not-matching-in-slice(curr, end, ' ')
+485     (skip-chars-not-matching-in-slice %ecx %edx 0x20)  # => eax
+486     89/<- %ecx 0/r32/eax
+487     # size += 4
+488     81 0/subop/add %ebx 4/imm32
+489     eb/jump $_parse-array-of-decimal-ints:loop1/disp8
+490 $_parse-array-of-decimal-ints:break1:
+491     (allocate-array *(ebp+8) %ebx *(ebp+0x10))
+492 $_parse-array-of-decimal-ints:pass2:
+493     # var slice/edi: slice = {s->data, 0}
+494     68/push 0/imm32/end
+495     8d/copy-address *(esi+4) 7/r32/edi
+496     57/push-edi
+497     89/<- %edi 4/r32/esp
+498     # curr = lookup(out)->data
+499     8b/-> *(ebp+0x10) 0/r32/eax
+500     (lookup *eax *(eax+4))  # => eax
+501     8d/copy-address *(eax+4) 1/r32/ecx
+502 $_parse-array-of-decimal-ints:loop2:
+503     # if (slice->start >= end) break
+504     39/compare *edi 2/r32/edx
+505     73/jump-if-addr>= $_parse-array-of-decimal-ints:end/disp8
+506     # slice->start = skip-chars-matching-in-slice(slice->start, end, ' ')
+507     (skip-chars-matching-in-slice *edi %edx 0x20)  # => eax
+508     89/<- *edi 0/r32/eax
+509     # if (slice->start >= end) break
+510     39/compare *edi 2/r32/edx
+511     73/jump-if-addr>= $_parse-array-of-decimal-ints:end/disp8
+512     # slice->end = skip-chars-not-matching-in-slice(slice->start, end, ' ')
+513     (skip-chars-not-matching-in-slice *edi %edx 0x20)  # => eax
+514     89/<- *(edi+4) 0/r32/eax
+515     # *curr = parse-hex-int-from-slice(slice)
+516     (parse-decimal-int-from-slice %edi)
+517     89/<- *ecx 0/r32/eax
+518     # curr += 4
+519     81 0/subop/add %ecx 4/imm32
+520     # slice->start = slice->end
+521     8b/-> *(edi+4) 0/r32/eax
+522     89/<- *edi 0/r32/eax
+523     eb/jump $_parse-array-of-decimal-ints:loop2/disp8
+524 $_parse-array-of-decimal-ints:end:
+525     # . reclaim locals
+526     81 0/subop/add %esp 8/imm32
+527     # . restore registers
+528     5f/pop-to-edi
+529     5e/pop-to-esi
+530     5b/pop-to-ebx
+531     5a/pop-to-edx
+532     59/pop-to-ecx
+533     58/pop-to-eax
+534     # . epilogue
+535     89/<- %esp 5/r32/ebp
+536     5d/pop-to-ebp
+537     c3/return
+538 
+539 test-parse-array-of-decimal-ints:
+540     # . prologue
+541     55/push-ebp
+542     89/<- %ebp 4/r32/esp
+543     # var h/esi: (handle array int)
+544     68/push 0/imm32
+545     68/push 0/imm32
+546     89/<- %esi 4/r32/esp
+547     # var ecx: (array int) = [1, 2, 3]
+548     68/push 3/imm32
+549     68/push 2/imm32
+550     68/push 1/imm32
+551     68/push 0xc/imm32/size
+552     89/<- %ecx 4/r32/esp
+553     #
+554     (_parse-array-of-decimal-ints Heap "1 2 3" %esi)
+555     (lookup *esi *(esi+4))  # => eax
+556     (array-equal? %ecx %eax)  # => eax
+557     (check-ints-equal %eax 1 "F - test-parse-array-of-decimal-ints")
+558     # . epilogue
+559     89/<- %esp 5/r32/ebp
+560     5d/pop-to-ebp
+561     c3/return
+562 
+563 test-parse-array-of-decimal-ints-empty:
+564     # - empty string = empty array
+565     # . prologue
+566     55/push-ebp
+567     89/<- %ebp 4/r32/esp
+568     # var h/esi: handle
+569     68/push 0/imm32
+570     68/push 0/imm32
+571     89/<- %esi 4/r32/esp
+572     #
+573     (_parse-array-of-decimal-ints Heap "" %esi)
+574     (lookup *esi *(esi+4))  # => eax
+575     (check-ints-equal *eax 0 "F - test-parse-array-of-decimal-ints-empty")
+576     # . epilogue
+577     89/<- %esp 5/r32/ebp
+578     5d/pop-to-ebp
+579     c3/return
+580 
+581 test-parse-array-of-decimal-ints-just-whitespace:
+582     # - just whitespace = empty array
+583     # . prologue
+584     55/push-ebp
+585     89/<- %ebp 4/r32/esp
+586     # var h/esi: handle
+587     68/push 0/imm32
+588     68/push 0/imm32
+589     89/<- %esi 4/r32/esp
+590     #
+591     (_parse-array-of-decimal-ints Heap Space %esi)
+592     (lookup *esi *(esi+4))  # => eax
+593     (check-ints-equal *eax 0 "F - test-parse-array-of-decimal-ints-just-whitespace")
+594     # . epilogue
+595     89/<- %esp 5/r32/ebp
+596     5d/pop-to-ebp
+597     c3/return
+598 
+599 test-parse-array-of-decimal-ints-extra-whitespace:
+600     # . prologue
+601     55/push-ebp
+602     89/<- %ebp 4/r32/esp
+603     # var h/esi: handle
+604     68/push 0/imm32
+605     68/push 0/imm32
+606     89/<- %esi 4/r32/esp
+607     # var ecx: (array int) = [1, 2, 3]
+608     68/push 3/imm32
+609     68/push 2/imm32
+610     68/push 1/imm32
+611     68/push 0xc/imm32/size
+612     89/<- %ecx 4/r32/esp
+613     #
+614     (_parse-array-of-decimal-ints Heap " 1 2  3  " %esi)
+615     (lookup *esi *(esi+4))  # => eax
+616     (array-equal? %ecx %eax)  # => eax
+617     (check-ints-equal %eax 1 "F - test-parse-array-of-decimal-ints-extra-whitespace")
+618     # . epilogue
+619     89/<- %esp 5/r32/ebp
+620     5d/pop-to-ebp
+621     c3/return
+622 
+623 parse-array-of-decimal-ints:  # s: (addr array byte), out: (addr handle array int)
+624     # . prologue
+625     55/push-ebp
+626     89/<- %ebp 4/r32/esp
+627     #
+628     (_parse-array-of-decimal-ints Heap *(ebp+8) *(ebp+0xc))
+629 $parse-array-of-decimal-ints:end:
+630     # . epilogue
+631     89/<- %esp 5/r32/ebp
+632     5d/pop-to-ebp
+633     c3/return
+634 
+
+ + + -- cgit 1.4.1-2-gfad0