1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8 ;; reset all labels, reinit label manager
13 ld hl,(LABMAN_FIRST_LABEL)
19 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21 ;; increment pass counter, perform pass bookkeeping
22 ;; calling this more than once is UB
23 ;; returns current pass in A
33 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
37 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
38 ;; data buffer format:
40 ;; label-name ; end of table if the first byte is zero
44 ;; name has highest bit of the last char set
45 ;; flags are used for forward references
46 ;; #00: fully resolved label
47 ;; #FF: forward-referenced label (it was used, but the value is unknown yet)
48 ;; at the end of the first pass, any labels with #FF are undefined
49 ;; on the second pass, no new labels are created
52 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
57 ;; IY: text input buffer
59 ;; IY: text input buffer after the label
60 ;; HL: points to label data area
64 ;; HL: points after the last label
66 ;; AF is dead, other registers are preserved
70 ld hl,(LABMAN_FIRST_LABEL)
76 ld iy,0 ; patched above
88 ; check failed, skip label
94 .skip_label_data_area:
105 ; if ok, carry is set (non-id char)
106 ; inverse it for correct return result
109 jr .skip_label_data_area
117 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
119 ;; this is called by the driver to define a new label
122 ;; IY: text input buffer
124 ;; IY: text input buffer after the label
125 ;; CARRY SET on error
129 ld (LABMAN_NEW_LABEL_FLAG),a
132 jr c,LABMAN_FIND_LABEL_create_new_label
133 ; existing label: check if it is a forward reference
139 ; on second and other passes, this is not an error
143 ld a,BZ80ASM.EXPR_ERR_DUPLICATE_LABEL
144 jp BZ80ASM.PARSE_EXPR_ERROR_A
146 ; reset "forward" flag
148 ; there should be no unresolved labels on the second pass
161 ld iy,0 ; patched above
166 ld a,BZ80ASM.EXPR_ERR_UNRESOLVED_LABEL
167 jp BZ80ASM.PARSE_EXPR_ERROR_A
169 ; assume that label name is good
187 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
190 ;; see full documentation in "bz80asm.zas"
193 ;; IY: text input buffer
195 ;; IY: text input buffer after the label
197 ;; CARRY FLAG: set if label wasn't found
198 ;; expression parser will bomb out in this case
202 ld (LABMAN_NEW_LABEL_FLAG),a
205 jr c,.create_new_label
206 ; old label, return value
213 @LABMAN_FIND_LABEL_create_new_label:
215 ; allowed only on the first pass
227 ld a,EXPR_ERR_NO_LOCAL_LABELS_YET
228 jp BZ80ASM.PARSE_EXPR_ERROR_A
230 ld a,BZ80ASM.EXPR_ERR_BAD_SYNTAX
231 jp BZ80ASM.PARSE_EXPR_ERROR_A
234 push hl ; we'll use this later to print a name
235 ; HL points to the memory where our new label should be put
236 ; copy label name there
257 ; set "forward reference" flag
259 @LABMAN_NEW_LABEL_FLAG equ $-1
260 ; put zero to mark new label area end
264 ; now print new label
282 ; reset carry (just to be sure)
286 msg_newlabel: defx "NEWLABEL:<"
289 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
290 ;; check if A is an alpha char
291 ;; carry set: not an alpha char
307 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
308 ;; check if A is a decimal digit
309 ;; carry set: not a digit char
318 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
319 ;; check if A is a valid identifier char (including digits)
320 ;; carry set: not an id char