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