Mercurial > hg > index.cgi
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. |