1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2 ;; math expression parser
3 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6 ;; set this to the address of error routine
7 ;; note that you cannot return from it, you HAVE to abort everything
8 ;; also note that machine stack is undefined, and SP should be set
9 ;; to some initial value
10 ;; "undefined" means that machine stack can contain alot of garbage,
11 ;; but will never be underflowed
13 ;; this function is called with error code in A
17 ;; expected number, but got something incomprehensible
18 EXPR_ERR_NUMBER_EXPECTED equ 1
19 ;; expected string, but got something incomprehensible
20 EXPR_ERR_STRING_EXPECTED equ 2
21 ;; expected ")", but got something strange
22 EXPR_ERR_RPAREN_EXPECTED equ 3
23 ;; expected ")", but got something strange
24 EXPR_ERR_DIVISION_BY_ZERO equ 4
26 ;; offset your own error codes with this
27 EXPR_ERR_USERDEF equ 5
35 ld a,EXPR_ERR_NUMBER_EXPECTED
39 ld a,EXPR_ERR_STRING_EXPECTED
42 PARSE_EXPR_ERROR_0DIV:
43 ld a,EXPR_ERR_DIVISION_BY_ZERO
46 PARSE_EXPR_ERROR_RPAREN:
47 ld a,EXPR_ERR_RPAREN_EXPECTED
51 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
53 ;; parse an integer expression
57 ;; IY: text buffer after the expression
58 ;; HL: expression value
59 ;; everything other (including all alternate registers) is dead
68 call PARSER_SKIP_BLANKS
69 jp z,PARSE_EXPR_ERROR_INT
70 ; sign for the first argument
71 ld c,#FF ; use this, as we need bit 1 to be set
80 ; do negate if necessary
83 bit 1,c ; '+' has bit 1 set, '-' hasn't
93 call PARSER_SKIP_BLANKS
95 ; (iy+0) and (iy+1) should be equal
104 inc iy ; skip operation part
108 ; HL: number to shift
141 ; check for operation
142 call PARSER_SKIP_BLANKS
166 ; check for operation
167 call PARSER_SKIP_BLANKS
182 ex af,af' ; save operation
186 jp z,PARSE_EXPR_ERROR_0DIV
187 call PARSER_UDIV_BC_DE
191 jr z,.muldiv_next ; remainder already in hl
196 call PARSER_UMUL_BC_DE
199 ;; parse term, also process unaries and parens
201 call PARSER_SKIP_BLANKS
202 jp z,PARSE_EXPR_ERROR_INT
203 inc iy ; skip operation
212 ; this must be number
215 ; here we can check labels
216 jp c,PARSE_EXPR_ERROR_INT
221 ;; C contains matching rparen
224 call PARSER_SKIP_BLANKS
225 jp z,PARSE_EXPR_ERROR_RPAREN
228 jp nz,PARSE_EXPR_ERROR_RPAREN
243 ;; call subroutine at BC
246 ;; DE: subroutine result
247 ;; i.e. HL is op0, DE is op1
250 push af ; A holds operation
251 inc iy ; skip operation
252 ld hl,.go_down_bc_ret
263 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
267 ;; BC,DE,A,flags: dead
287 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
313 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
315 ;; parse a string expression
320 ;; HL: string buffer start
321 ;; E: parsed string length
322 ;; everything other (including all alternate registers) is dead
325 call PARSER_SKIP_BLANKS
326 jp z,PARSE_EXPR_ERROR_STR
330 jp nz,PARSE_EXPR_ERROR_STR
339 jp z,PARSE_EXPR_ERROR_STR
353 ;; string accumulator
357 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
359 ;; returns current char in A
360 ;; sets zero flag on EOL
364 ;; IY: text buffer at non-blank or EOL
365 ;; A: non-blank or EOL char
366 ;; zero flag is set on EOL
376 jr c,PARSER_SKIP_BLANKS