zasm: improve .equ duplicate detection handling

Things are a bit more straightforward now.
This commit is contained in:
Virgil Dupras 2019-07-22 22:49:43 -04:00
parent 9ea72dc1d0
commit cc7a4bae58
3 changed files with 25 additions and 30 deletions

View File

@ -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

View File

@ -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:

View File

@ -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