1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2 ;; parse integer number (without sign)
3 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5 ;; this is advanced number parser
6 ;; it understands alot of suffixes and prefixes:
7 ;; $ -- lone "$" means "current PC"
18 ;; everything is case-insensitive
19 ;; you can separate digits with underscores
20 ;; (i.e. "12_34_5" will work, underscores are simply ignored)
23 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25 ;; parse a number, push it onto the stack
26 ;; understands prefixes and suffixes
31 ;; IY: text buffer after the expression
34 ;; OR: (cannot parse as a number)
40 call PARSER_SKIP_BLANKS
43 push iy ; we will need to rollback on error
44 ; A already contains a char, loaded by `PARSER_SKIP_BLANKS`
48 jr z,.maybe_lone_dollar
53 ; no, leading zero doesn't mean "octal", this is stupid
54 ; but we may have prefixes like "0x" and such
56 jr z,.maybe_zero_prefix
57 ; check if we have a digit here
58 call PARSER_CONV_DIGIT
59 jr c,.not_a_number_carry_set
61 ; nope, do not allow it, all numbers must start with a digit
62 ;jr nc,.must_be_hex_with_sfx
64 jr c,.not_a_number_carry_set
66 ; done with prefixes, try decimal number
67 ; we'll switch to suffix checking on hex digit
73 jr nc,.must_be_hex_with_sfx
90 and %11011111 ; cheap uppercase
92 jr z,.must_be_hex_with_sfx
97 ; no suffix, we're done
105 .not_a_number_carry_set:
114 jr c,.not_a_number_carry_set
118 ; lone dollar means "PC"
121 ; the only case we may gen an error here is
122 ; when our dollar isn't followed by a digit
124 ; lone dollar is good too
125 ; IY points right after the dollar here
136 ; things like "0BEEFh" should be parsed as hex
140 jr c,.must_be_hex_with_sfx
143 and %11011111 ; cheap uppercase
145 jr z,.must_be_hex_with_sfx
155 ; check for '0x' and such
159 ; there's no need to skip it, as it will be
160 ; skipped by the corresponding subroutine
162 ; so IY will point to the actual number
163 and %11011111 ; cheap uppercase
167 jr z,.maybe_binprefix
170 ; do not reparse '0', no need to backup
171 jr .do_normal_decimal
173 .must_be_hex_with_sfx:
174 ; reparse as hex, and check for suffix
178 jr c,.not_a_number_carry_set
181 and %11011111 ; cheap uppercase
186 ; reparse as bin, skip suffix (it is guaranteed to be there)
190 .done_guaranteed_suffix:
191 jr c,.not_a_number_carry_set
197 ; reparse as bin, skip suffix (it is guaranteed to be there)
201 jr .done_guaranteed_suffix
204 ld hl,0 ; accumulator
205 ; check first digit (as this is general parser)
206 call .getDigitNoUnder
218 jr nc,.parse_as_hex_loop
219 ; clear carry flag (it is always set here)
224 ld hl,0 ; accumulator
225 ; check first digit (as this is general parser)
227 call .getDigitNoUnderBin
236 jr nc,.parse_as_bin_loop
237 ; clear carry flag (it is always set here)
242 ld hl,0 ; accumulator
243 ; check first digit (as this is general parser)
245 call .getDigitNoUnderOct
255 jr nc,.parse_as_oct_loop
256 ; clear carry flag (it is always set here)
298 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
299 ;; converts 'A' to digit (assume hex)
300 ;; carry set: not a digit char (and A is destroyed)
309 and %11011111 ; cheap uppercase