comparison src/expr.s @ 84:f959c92bc329

New first pass implementation of number parsing, untested Rewrite number parsing using recently constructed infrastructure. The result is untested.
author William Astle <lost@l-w.ca>
date Sun, 08 Oct 2023 00:17:20 -0600
parents bb50ac9fdf37
children b0422868a7b1
comparison
equal deleted inserted replaced
83:a492441bfc56 84:f959c92bc329
86 ; 13. If not digit, go handle return at step 10 86 ; 13. If not digit, go handle return at step 10
87 ; 14. Multiply exponent accumulator by 10 and add digit value; raise error on overflow or go back to step 12 87 ; 14. Multiply exponent accumulator by 10 and add digit value; raise error on overflow or go back to step 12
88 ; 15. Read a character and go to step 7 88 ; 15. Read a character and go to step 7
89 ; 89 ;
90 ; If the result ends up being larger than a floating point value can hold, return Overflow 90 ; If the result ends up being larger than a floating point value can hold, return Overflow
91 eval_number 91 eval_number jmp val_parsenum ; if we don't recognize anything else, just parse a numer
92 if 0
93 ldb #valtype_int ; flag result as an integer
94 stb val0+val.type
95 ldx zero ; blank out the value except type
96 stx val0
97 stx val0+2
98 stx val0+4
99 bra eval_number1 ; go do the parsing
100 eval_number0 jsr nextchar ; fetch next input
101 beq eval_number6 ; brif end of expression - bail
102 eval_number1 cmpa #'- ; negative (ascii sign)?
103 beq eval_number3 ; brif so
104 cmpa #tok_minus ; negative (operator negative)?
105 bne eval_number2 ; brif not
106 eval_number3 com val0+val.fpssign ; invert sign (multiple negatives will flip this multiple times)
107 bra eval_number0 ; deal with next input
108 eval_number2 cmpa #'+ ; unary +?
109 beq eval_number0 ; brif so - skip it
110 cmpa #tok_plus ; unary + (operator plus)?
111 beq eval_number0 ; brif so - skip it
112 eval_number5 cmpa #'. ; decimal point?
113 beq eval_number8 ; brif decimal - force float
114 cmpa #'0 ; is it a number?
115 blo eval_number6 ; brif below digit
116 cmpa #'9 ; is it still a number?
117 bhi eval_number6 ; brif above digit
118 suba #'0 ; offset to binary digit value
119 pshs a ; save digit value
120 ldx val0+val.int ; get current value for later (for quick multiply by 10)
121 ldd val0+val.int+2
122 pshs d,x ; stored with words swapped on stack for efficiency for later
123 lsl val0+val.int+3 ; times 2
124 rol val0+val.int+2
125 rol val0+val.int+1
126 rol val0+val.int
127 rol val0+val.fpsexp ; overflow into fp exponent
128 lsl val0+val.int+3 ; times 4
129 rol val0+val.int+2
130 rol val0+val.int+1
131 rol val0+val.int
132 rol val0+val.fpsexp ; brif overflowed
133 ldd val0+val.int+2 ; times 5 (add original value)
134 addd ,s++
135 std val0+val.int+2
136 ldd val0+val.int
137 adcb 1,s
138 adca ,s++
139 std val0+val.int
140 ldb val0+val.fpsexp ; and handle overflow bits
141 adcb #0
142 stb val0+val.fpsexp
143 lsl val0+val.int+3 ; times 10
144 rol val0+val.int+2
145 rol val0+val.int+1
146 rol val0+val.int
147 rol val0+val.fpsexp
148 ldd val0+val.int+2 ; get low word
149 addb ,s+ ; add in current digit
150 adca #0
151 std val0+val.int+2
152 ldd val0+val.int
153 adcb #0
154 adca #0
155 std val0+val.int
156 lda val0+val.fpsexp ; and handle overflow
157 adca #0
158 sta val0+val.fpsexp
159 bne eval_number11 ; if we overflowed, go continue parsing as floating point
160 lda val0+val.int ; get back high byte and check for overflow
161 bpl eval_number4 ; brif we haven't wrapped negative
162 cmpd #0x8000 ; is it valid negative two's complement?
163 bhi eval_number11 ; brif not - we're in floating point territory
164 ldd val0+val.int+2 ; is it still valid two's complement (max negative)?
165 bne eval_number11 ; brif not - we're in floating point territory
166 eval_number4 jsr nextchar ; fetch next input character
167 bra eval_number5 ; go handle it
168 eval_number6 cmpa #'E ; base 10 exponent?
169 beq eval_number8 ; brif so
170 cmpa #'e ; base 10 exponent in lower case?
171 beq eval_number8 ; brif so
172 ldb val0+val.fpssign ; did we want a negative value?
173 beq eval_number7 ; brif not
174 jsr val_negint32 ; negate the 32 bit integer to correct two's complement
175 eval_number7 clr val0+val.fpssign ; clear sign bits for book keeping
176 rts
177 eval_number11 jsr nextchar ; each the character already processed
178 eval_number8 lda #0x9f ; exponent if binary point is to the right of the mantissa
179 clr val0extra ; clear extra precision bits for val0
180 ldb #valtype_float ; flag value as floating point
181 stb val0+val.type
182 ldb val0+val.fpsexp ; do we have overflow bits to shift?
183 beq eval_number10 ; brif not
184 eval_number9 inca ; bump exponent to account for extra bits
185 lsrb ; shift some bits over
186 ror val0+val.fpssig
187 ror val0+val.fpssig+1
188 ror val0+val.fpssig+2
189 ror val0+val.fpssig+3
190 ror val0extra
191 tstb ; all bits shifted into mantissa?
192 bne eval_number9 ; brif not
193 eval_number10 sta val0+val.fpsexp ; save adjusted exponent
194 ldx #val0 ; normalize the result for further operations
195 jsr fp_normalize
196 clr ,-s ; flag for decimal point seen
197 clr ,-s ; current decimal exponent value
198 jsr curchar ; get current input character
199 bra eval_number20 ; go evaluate the floating point value
200 eval_number40 jsr nextchar ; fetch next input
201 eval_number20 bcs eval_number29 ; brif digit
202 cmpa #'. ; is it a decimal?
203 bne eval_number21 ; brif not
204 com 1,s ; flag decimal seen
205 bne eval_number40
206 jmp SNERROR ; brif unexpected second decimal point
207 eval_number21 cmpa #'E ; decimal exponent?
208 beq eval_number26 ; brif so
209 cmpa #'e ; decimal exponent lower case?
210 beq eval_number26
211 eval_number22 ldb ,s ; get decimal exponent count and set flags
212 beq eval_number25 ; brif no adjustment needed
213 bmi eval_number24 ; brif we need to divide
214 eval_number23 jsr fp_mul10 ; multiply by 10
215 dec ,s ; done?
216 bne eval_number23 ; brif not
217 rts
218 eval_number24 jsr fp_div10 ; divide by 10
219 inc ,s ; done?
220 bne eval_number24 ; brif not
221 eval_number25 rts
222 eval_number26 clrb ; blank out decimal exponent accumulator
223 clr ,-s ; set sign positive
224 jsr nextchar ; get next input
225 bcs eval_number28 ; brif digit - positive exponent
226 cmpa #'+ ; positive?
227 beq eval_number27 ; brif so - skip it
228 cmpa #tok_plus ; positive (plus operator)?
229 beq eval_number27
230 cmpa #'- ; negative?
231 beq eval_number30 ; brif so
232 cmpa #tok_minus ; negative (minus operator)?
233 bne eval_number31 ; brif not
234 eval_number30 com ,s ; get sign negative
235 eval_number27 jsr nextchar ; get next character
236 bcs eval_number28 ; brif digit
237 eval_number31 lda ,s+ ; get negative flag, set flags, and clean up the stack
238 beq eval_number32 ; brif positive
239 negb ; we have a negative decimal exponent - handle it
240 eval_number32 addb ,s ; add in decimal exponent adjustment
241 stb ,s ; save it for cleanup
242 bra eval_number22 ; go finish up
243 eval_number28 suba #'0 ; digit-ize it
244 pshs a ; save it for later
245 lda #10 ; multiply value by 10 and add digit
246 mul
247 addb ,s+
248 bpl eval_number27 ; go handle another digit if we didn't overflow negative
249 OVERROR ldb #err_ov ; flag overflow
250 jmp ERROR
251 eval_number29 ldb ,s ; get exponent adjustment
252 addb 1,s ; subtract if decimal point was seen for later fixup
253 stb 1,s
254 suba #'0 ; digit-ize the character
255 pshs a ; save it for later
256 jsr fp_mul10 ; multiply by 10
257 jsr val0toval1 ; save residue
258 puls b ; get back digit value
259 clra ; make it floating point
260 std val0+val.int+2
261 sta val0+val.int+1
262 sta val0+val.int
263 jsr val_int32tofloat ; convert to floating point
264 jsr fp_add ; add val1 to val0
265 bra eval_number40 ; go handle another character
266 endc
267 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 92 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
268 ; Operator table 93 ; Operator table
269 ; 94 ;
270 ; Each entry starts with the precedence value followed by the handler routine. Each handler will receive its left 95 ; Each entry starts with the precedence value followed by the handler routine. Each handler will receive its left
271 ; operand in val1 and its right operand in val0 and should return its result in val0. 96 ; operand in val1 and its right operand in val0 and should return its result in val0.