zasm: improve .equ duplicate detection handling
Things are a bit more straightforward now.
This commit is contained in:
parent
9ea72dc1d0
commit
cc7a4bae58
@ -122,6 +122,12 @@ handleDW:
|
||||
handleEQU:
|
||||
call zasmIsLocalPass ; Are we in local pass? Then ignore all .equ.
|
||||
jr z, .skip ; they mess up duplicate symbol detection.
|
||||
; We register constants on both first and second pass for one little
|
||||
; reason: .org. Normally, we'd register constants on second pass only
|
||||
; so that we have values for forward label references, but we need .org
|
||||
; to be effective during the first pass and .org needs to support
|
||||
; expressions. So, we double-parse .equ, clearing the const registry
|
||||
; before the second pass.
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
|
@ -64,6 +64,10 @@ zasmMain:
|
||||
call ioPrintLN
|
||||
xor a
|
||||
ld (ZASM_FIRST_PASS), a
|
||||
; before parsing the file for the second pass, let's clear the const
|
||||
; registry. See comment in handleEQU.
|
||||
ld ix, SYM_CONST_REGISTRY
|
||||
call symClear
|
||||
call zasmParseFile
|
||||
.end:
|
||||
jp ioLineNo ; --> HL, --> DE, returns
|
||||
@ -209,9 +213,8 @@ _beginLocalPass:
|
||||
; Set local pass
|
||||
ld (ZASM_LOCAL_PASS), a
|
||||
; Empty local label registry
|
||||
xor a
|
||||
ld (SYM_LOC_NAMES), a
|
||||
ret
|
||||
ld ix, SYM_LOCAL_REGISTRY
|
||||
jp symClear
|
||||
|
||||
|
||||
_endLocalPass:
|
||||
|
@ -169,7 +169,7 @@ symRegister:
|
||||
push de ; --> lvl 2. it's our value.
|
||||
|
||||
call _symFind
|
||||
jr z, .alreadyThere
|
||||
jr z, .duplicateError
|
||||
|
||||
|
||||
; First, let's get our strlen
|
||||
@ -223,32 +223,6 @@ symRegister:
|
||||
pop hl ; <-- lvl 1
|
||||
ret
|
||||
|
||||
.alreadyThere:
|
||||
; We are in a tricky situation with regards to our handling of the
|
||||
; duplicate symbol error. Normally, it should be straightforward: We
|
||||
; only register labels during first pass and evaluate constants during
|
||||
; the second. Easy.
|
||||
; We can *almost* do that... but we have ".org". .org affects label
|
||||
; values and supports expressions, which means that we have to evaluate
|
||||
; constants during first pass. But because we can possibly have forward
|
||||
; references in ".equ", some constants are going to have a bad value.
|
||||
; Therefore, we really can't evaluate all constants during the first
|
||||
; pass.
|
||||
; With this situation, how do you manage detection of duplicate symbols?
|
||||
; By limiting the "duplicate error" condition to the first pass. During,
|
||||
; first pass, sure, we don't have our proper values, but we have all our
|
||||
; symbol names. So, if we end up in .alreadyThere during first pass,
|
||||
; then it's an error condition. If it's not first pass, then we need
|
||||
; to update our value.
|
||||
|
||||
call zasmIsFirstPass
|
||||
jr z, .duplicateError
|
||||
; Second pass. Don't error out, just update value, which DE points to.
|
||||
pop hl ; <-- lvl 2, the value to register
|
||||
call writeHLinDE
|
||||
pop hl ; <-- lvl 1
|
||||
cp a ; ensure Z
|
||||
ret
|
||||
.duplicateError:
|
||||
pop de ; <-- lvl 2
|
||||
pop hl ; <-- lvl 1
|
||||
@ -321,3 +295,15 @@ symFindVal:
|
||||
.end:
|
||||
pop ix
|
||||
ret
|
||||
|
||||
; Clear registry at IX
|
||||
symClear:
|
||||
push af
|
||||
push hl
|
||||
ld l, (ix)
|
||||
ld h, (ix+1)
|
||||
xor a
|
||||
ld (hl), a
|
||||
pop hl
|
||||
pop af
|
||||
ret
|
||||
|
Loading…
Reference in New Issue
Block a user