make room for a task before fractional numbers
[mu.git] / 515parse-float.mu
blob40bbb194307b53d96365ea60c9f0ab3a19407024
1 # no support for scientific notation yet
2 fn parse-float-decimal in: (addr stream byte) -> _/xmm1: float {
3   var zero: float
4   var result/xmm1: float <- copy zero
5   var first-iter?/ecx: int <- copy 1/true
6   rewind-stream in
7   var negative?/edx: int <- copy 0/false
8   # first loop: integer part
9   var ten/eax: int <- copy 0xa
10   var ten-f/xmm2: float <- convert ten
11   {
12     var done?/eax: boolean <- stream-empty? in
13     compare done?, 0/false
14     break-if-!=
15     var key/eax: byte <- read-byte in
16     compare key, 0x2e/decimal-point
17     break-if-=
18     $parse-float-decimal:body: {
19       compare key, 0x2d/-
20       {
21         break-if-!=
22         compare first-iter?, 0/false
23         {
24           break-if-!=
25           abort "parse-float-decimal: '-' only allowed in first position"
26         }
27         negative? <- copy 1/true
28         break $parse-float-decimal:body
29       }
30       compare key, 0x30/0
31       {
32         break-if->=
33         abort "parse-float-decimal: invalid character < '0'"
34       }
35       compare key, 0x39/9
36       {
37         break-if-<=
38         abort "parse-float-decimal: invalid character > '9'"
39       }
40       # key is now a digit
41       var digit-value/eax: int <- copy key
42       digit-value <- subtract 0x30
43       var digit-value-f/xmm3: float <- convert digit-value
44       result <- multiply ten-f
45       result <- add digit-value-f
46     }
47     first-iter? <- copy 0/false
48     loop
49   }
50   # second loop: fraction
51   var current-position/xmm0: float <- rational 1, 0xa
52   {
53     var done?/eax: boolean <- stream-empty? in
54     compare done?, 0/false
55     break-if-!=
56     var key/eax: byte <- read-byte in
57     compare key, 0x30/0
58     {
59       break-if->=
60       abort "parse-float-decimal: invalid fraction character < '0'"
61     }
62     compare key, 0x39/9
63     {
64       break-if-<=
65       abort "parse-float-decimal: invalid fraction character > '9'"
66     }
67     # key is now a digit
68     var digit-value/eax: int <- copy key
69     digit-value <- subtract 0x30
70     var digit-value-f/xmm3: float <- convert digit-value
71     digit-value-f <- multiply current-position
72     result <- add digit-value-f
73     current-position <- divide ten-f
74     #
75     first-iter? <- copy 0/false
76     loop
77   }
78   # finally, the sign
79   compare negative?, 0/false
80   {
81     break-if-=
82     var minus-one/eax: int <- copy -1
83     var minus-one-f/xmm2: float <- convert minus-one
84     result <- multiply minus-one-f
85   }
86   return result
89 fn test-parse-float-decimal-zero {
90   var s-storage: (stream byte 0x10)
91   var s/esi: (addr stream byte) <- address s-storage
92   write s, "00"
93   var x/xmm1: float <- parse-float-decimal s
94   var expected/eax: int <- copy 0
95   var expected-f/xmm0: float <- convert expected
96   compare x, expected-f
97   {
98     break-if-=
99     draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "F - test-parse-float-decimal-zero", 3/fg 0/bg
100     move-cursor-to-left-margin-of-next-line 0/screen
101     count-test-failure
102   }
103   draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg=cyan, 0/bg
106 fn test-parse-float-decimal-integer {
107   var s-storage: (stream byte 0x10)
108   var s/esi: (addr stream byte) <- address s-storage
109   write s, "34"
110   var x/xmm1: float <- parse-float-decimal s
111   var expected/eax: int <- copy 0x22/34
112   var expected-f/xmm0: float <- convert expected
113   compare x, expected-f
114   {
115     break-if-=
116     draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "F - test-parse-float-decimal-integer", 3/fg 0/bg
117     move-cursor-to-left-margin-of-next-line 0/screen
118     count-test-failure
119   }
120   draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg=cyan, 0/bg
123 fn test-parse-float-decimal-negative-integer {
124   var s-storage: (stream byte 0x10)
125   var s/esi: (addr stream byte) <- address s-storage
126   write s, "-34"
127   var x/xmm1: float <- parse-float-decimal s
128   var expected/eax: int <- copy -0x22/-34
129   var expected-f/xmm0: float <- convert expected
130   compare x, expected-f
131   {
132     break-if-=
133     draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "F - test-parse-float-decimal-negative-integer", 3/fg 0/bg
134     move-cursor-to-left-margin-of-next-line 0/screen
135     count-test-failure
136   }
137   draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg=cyan, 0/bg
140 fn test-parse-float-decimal-fraction {
141   var s-storage: (stream byte 0x10)
142   var s/esi: (addr stream byte) <- address s-storage
143   write s, "3.4"
144   var x/xmm1: float <- parse-float-decimal s
145   var expected-f/xmm0: float <- rational 0x22/34, 0xa/10
146   compare x, expected-f
147   {
148     break-if-=
149     draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "F - test-parse-float-decimal-fraction", 3/fg 0/bg
150     move-cursor-to-left-margin-of-next-line 0/screen
151     count-test-failure
152   }
153   draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg=cyan, 0/bg
156 fn test-parse-float-decimal-negative-fraction {
157   var s-storage: (stream byte 0x10)
158   var s/esi: (addr stream byte) <- address s-storage
159   write s, "-3.4"
160   var x/xmm1: float <- parse-float-decimal s
161   var expected-f/xmm0: float <- rational -0x22/-34, 0xa/10
162   compare x, expected-f
163   {
164     break-if-=
165     draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "F - test-parse-float-decimal-negative-fraction", 3/fg 0/bg
166     move-cursor-to-left-margin-of-next-line 0/screen
167     count-test-failure
168   }
169   draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg=cyan, 0/bg