Browse Source

zasm: improve .equ duplicate detection handling

Things are a bit more straightforward now.
pull/10/head
Virgil Dupras 5 years ago
parent
commit
cc7a4bae58
3 changed files with 25 additions and 30 deletions
  1. +6
    -0
      apps/zasm/directive.asm
  2. +6
    -3
      apps/zasm/main.asm
  3. +13
    -27
      apps/zasm/symbol.asm

+ 6
- 0
apps/zasm/directive.asm 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


+ 6
- 3
apps/zasm/main.asm 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:


+ 13
- 27
apps/zasm/symbol.asm 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

Loading…
Cancel
Save