zasm: fix bug with registry selection

During expression parsing, if a local label was parsed, it would
select the local registry and keep that selection, making
subsequent global labels register in the wrong place.
This commit is contained in:
Virgil Dupras 2019-07-20 18:07:52 -04:00
parent a7afbe091e
commit fe15bafeca
10 changed files with 43 additions and 25 deletions

View File

@ -169,24 +169,22 @@ parseNumberOrSymbol:
call parseLiteral call parseLiteral
ret z ret z
; Not a number. Try PC ; Not a number. Try PC
push de push de ; --> lvl 1
ld de, .sDollar ld de, .sDollar
call strcmp call strcmp
pop de pop de ; <-- lvl 1
jr z, .returnPC jr z, .returnPC
; Not PC either, try symbol ; Not PC either, try symbol
call symSelect push de ; --> lvl 1
call symFind call symFindVal ; --> DE
jr nz, .notfound jr nz, .notfound
; Found! let's fetch value
push de
call symGetVal
; value in DE. We need it in IX ; value in DE. We need it in IX
push de \ pop ix push de \ pop ix
pop de pop de ; <-- lvl 1
cp a ; ensure Z cp a ; ensure Z
ret ret
.notfound: .notfound:
pop de ; <-- lvl 1
; If not found, check if we're in first pass. If we are, it doesn't ; If not found, check if we're in first pass. If we are, it doesn't
; matter that we didn't find our symbol. Return success anyhow. ; matter that we didn't find our symbol. Return success anyhow.
; Otherwise return error. Z is already unset, so in fact, this is the ; Otherwise return error. Z is already unset, so in fact, this is the

View File

@ -238,12 +238,6 @@ symRegister:
ld a, ERR_DUPSYM ld a, ERR_DUPSYM
jp unsetZ ; return jp unsetZ ; return
; Select global or local registry according to label name in (HL)
symSelect:
call symIsLabelLocal
jp z, symSelectLocalRegistry
jp symSelectGlobalRegistry
; Find name (HL) in (SYM_CTX_NAMES) and make (SYM_CTX_PTR) point to the ; Find name (HL) in (SYM_CTX_NAMES) and make (SYM_CTX_PTR) point to the
; corresponding entry in (SYM_CTX_VALUES). ; corresponding entry in (SYM_CTX_VALUES).
; If we find something, Z is set, otherwise unset. ; If we find something, Z is set, otherwise unset.
@ -277,7 +271,21 @@ symFind:
pop ix pop ix
ret ret
; Return value that (SYM_CTX_PTR) is pointing at in DE. ; For a given symbol name in (HL), find it in the appropriate symbol register
symGetVal: ; and return its value in DE. If (HL) is a local label, the local register is
; searched. Otherwise, the global one. It is assumed that this routine is
; always called when the global registry is selected. Therefore, we always
; reselect it afterwards.
symFindVal:
call symIsLabelLocal
jp nz, .notLocal
call symSelectLocalRegistry
.notLocal:
call symFind
jr nz, .end
; Found! let's fetch value
; Return value that (SYM_CTX_PTR) is pointing at in DE.
ld de, (SYM_CTX_PTR) ld de, (SYM_CTX_PTR)
jp intoDE call intoDE
.end:
jp symSelectGlobalRegistry

Binary file not shown.

Binary file not shown.

View File

@ -11,8 +11,7 @@ jp test
zasmGetPC: zasmGetPC:
zasmIsFirstPass: zasmIsFirstPass:
symSelect: symSelect:
symFind: symFindVal:
symGetVal:
jp fail jp fail
testNum: .db 1 testNum: .db 1

View File

@ -34,9 +34,8 @@ test:
jp nz, fail jp nz, fail
ld hl, sFOO ld hl, sFOO
call symFind ; don't match FOOBAR call symFindVal ; don't match FOOBAR
jp nz, fail jp nz, fail
call symGetVal
ld a, d ld a, d
or a or a
jp nz, fail jp nz, fail

View File

@ -2,7 +2,6 @@
set -e set -e
TMPFILE=$(mktemp)
KERNEL=../../../kernel KERNEL=../../../kernel
APPS=../../../apps APPS=../../../apps
ZASM=../../zasm.sh ZASM=../../zasm.sh
@ -10,9 +9,8 @@ ASMFILE=${APPS}/zasm/instr.asm
cmpas() { cmpas() {
FN=$1 FN=$1
shift 1
EXPECTED=$(xxd ${FN}.expected) EXPECTED=$(xxd ${FN}.expected)
ACTUAL=$(cat ${FN} | $ZASM "$@" | xxd) ACTUAL=$(cat ${FN} | $ZASM "${KERNEL}" "${APPS}" | xxd)
if [ "$ACTUAL" == "$EXPECTED" ]; then if [ "$ACTUAL" == "$EXPECTED" ]; then
echo ok echo ok
else else
@ -24,9 +22,14 @@ cmpas() {
fi fi
} }
if [[ ! -z $1 ]]; then
cmpas $1
exit 0
fi
for fn in *.asm; do for fn in *.asm; do
echo "Comparing ${fn}" echo "Comparing ${fn}"
cmpas $fn "${KERNEL}" "${APPS}" cmpas $fn
done done
./errtests.sh ./errtests.sh

Binary file not shown.

View File

@ -0,0 +1,11 @@
; test some weird label bug zasm had at some point. Simply to refer to a local
; label in a .dw directive would mess up future label references.
foo:
inc a
.bar:
inc b
.baz:
.dw .bar
loop:
jr loop

Binary file not shown.