Mercurial > hg > index.cgi
comparison src/number.s @ 87:3bfd978ddb39
Make corrections in floating point parsing.
author | William Astle <lost@l-w.ca> |
---|---|
date | Mon, 16 Oct 2023 16:48:46 -0600 |
parents | de42b8f77bc2 |
children | a8467c798450 |
comparison
equal
deleted
inserted
replaced
86:de42b8f77bc2 | 87:3bfd978ddb39 |
---|---|
141 sta fpaextra+3 | 141 sta fpaextra+3 |
142 jsr curchar ; get back current input | 142 jsr curchar ; get back current input |
143 bra val_parsenum1 | 143 bra val_parsenum1 |
144 val_parsenum0 jsr nextchar ; fetch next input | 144 val_parsenum0 jsr nextchar ; fetch next input |
145 val_parsenum1 bcs val_parsenum3 ; brif digit - short ciruit other checks | 145 val_parsenum1 bcs val_parsenum3 ; brif digit - short ciruit other checks |
146 cmpa #'. ; does it start with a decimal? | |
147 beq val_parsenum5 ; brif so | |
146 cmpa #'+ ; unary plus? | 148 cmpa #'+ ; unary plus? |
147 beq val_parsenum0 ; brif so - it's a no-op but supported for symmetry with unary minus | 149 beq val_parsenum0 ; brif so - it's a no-op but supported for symmetry with unary minus |
148 cmpa #'- ; negative? | 150 cmpa #'- ; negative? |
149 bne val_parsenum5 ; brif not | 151 bne val_parsenum5 ; brif not |
150 com fpa0+fpa.sign ; invert the sign | 152 com fpa0+fpa.sign ; invert the sign |
155 cmpb #11 ; (11 digits holds both 10 digit fp and 32 bit integer) | 157 cmpb #11 ; (11 digits holds both 10 digit fp and 32 bit integer) |
156 bhs val_parsenum4 ; brif so - don't convert it | 158 bhs val_parsenum4 ; brif so - don't convert it |
157 suba #0x30 ; binary-ize the digit | 159 suba #0x30 ; binary-ize the digit |
158 bne val_parsenum3a ; brif not zero | 160 bne val_parsenum3a ; brif not zero |
159 tstb ; no digits? | 161 tstb ; no digits? |
160 beq val_parsenum2 ; brif so - skip leading zeroes | 162 bne val_parsenum3a ; brif not - we've seen something significant |
163 ldb fpaextra+1 ; decimal seen? | |
164 bne val_parsenum2 ; brif not - skip leading zeroes | |
161 val_parsenum3a ldb #0x11 ; put in both digit spots | 165 val_parsenum3a ldb #0x11 ; put in both digit spots |
162 mul | 166 mul |
163 andb fpaextra+3 ; only keep the one we need | 167 andb fpaextra+3 ; only keep the one we need |
164 orb ,x ; merge with existing digit | 168 orb ,x ; merge with existing digit |
165 stb ,x ; put in digit location | 169 stb ,x ; put in digit location |
172 subb fpaextra+1 ; subtract decimal flag (will be 0xff or -1 if decimal seen) | 176 subb fpaextra+1 ; subtract decimal flag (will be 0xff or -1 if decimal seen) |
173 stb fpaextra+2 | 177 stb fpaextra+2 |
174 bra val_parsenum2 ; go handle another digit or whatever | 178 bra val_parsenum2 ; go handle another digit or whatever |
175 val_parsenum5 cmpa #'. ; decimal? | 179 val_parsenum5 cmpa #'. ; decimal? |
176 bne val_parsenum6 ; brif not | 180 bne val_parsenum6 ; brif not |
177 com fpaextra ; flag decimal seen | 181 com fpaextra+1 ; flag decimal seen |
178 lbeq SNERROR ; brif already seen a decimal point - syntax error | 182 lbeq SNERROR ; brif already seen a decimal point - syntax error |
179 bra val_parsenum2 ; go parse more digits | 183 bra val_parsenum2 ; go parse more digits |
180 val_parsenum6 cmpa #'E ; decimal exponent? | 184 val_parsenum6 cmpa #'E ; decimal exponent? |
181 beq val_parsenum7 ; brif so | 185 beq val_parsenum7 ; brif so |
182 cmpa #'e ; lower case exponent indicator? | 186 cmpa #'e ; lower case exponent indicator? |
209 stb fpa0+fpa.exp ; set result exponent | 213 stb fpa0+fpa.exp ; set result exponent |
210 ; Normalization is not required here though rounding might be. Rounding will be handled during floating point return. | 214 ; Normalization is not required here though rounding might be. Rounding will be handled during floating point return. |
211 ; By ensuring there were no leading zeroes converted, the result is already pre-normalized without losing precision due | 215 ; By ensuring there were no leading zeroes converted, the result is already pre-normalized without losing precision due |
212 ; to an aribtrary number of leading zeroes. | 216 ; to an aribtrary number of leading zeroes. |
213 cmpb fpaextra ; is the exponent less than the number of digits? | 217 cmpb fpaextra ; is the exponent less than the number of digits? |
214 bgt val_parsenum13 ; brif so - return floating point (signed comparison!) | 218 blt val_parsenum13 ; brif so - return floating point (signed comparison!) |
215 cmpb #10 ; is exponent in the range for a binary integer? | 219 cmpb #10 ; is exponent in the range for a binary integer? |
216 bgt val_parsenum13 ; brif not - return floating point | 220 bgt val_parsenum13 ; brif not - return floating point |
217 ; Compare with 2147483648, the maximum *negative* value; note that this is a floating point comparison because we | 221 ; Compare with 2147483648, the maximum *negative* value; note that this is a floating point comparison because we |
218 ; already normalized everything above and it handles exponents properly | 222 ; already normalized everything above and it handles exponents properly |
219 lda fpa0+fpa.exp ; compare exponents (unbiased), exponent adjusted for above code | 223 lda fpa0+fpa.exp ; compare exponents (unbiased), exponent adjusted for above code |
232 ldb fpa0+fpa.sign ; negative? | 236 ldb fpa0+fpa.sign ; negative? |
233 bpl val_parsenum14 ; brif not - doesn't fit in integer | 237 bpl val_parsenum14 ; brif not - doesn't fit in integer |
234 val_parsenum13 lda #valtype_float ; set return value to floating point | 238 val_parsenum13 lda #valtype_float ; set return value to floating point |
235 sta val0+val.type | 239 sta val0+val.type |
236 lda fpa0+fpa.exp ; put the bias into the exponent but subtract one for leading digit | 240 lda fpa0+fpa.exp ; put the bias into the exponent but subtract one for leading digit |
237 adda #63 | 241 adda #64 |
238 sta fpa0+fpa.exp | 242 sta fpa0+fpa.exp |
239 ldy #val0+val.value ; normalize/round and return the result | 243 ldy #val0+val.value ; normalize/round and return the result |
240 jmp fps_normalize | 244 jmp fps_normalize |
241 val_parsenum14 lda #valtype_int ; set value type to integer | 245 val_parsenum14 lda #valtype_int ; set value type to integer |
242 sta val0+val.type | 246 sta val0+val.type |