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
ret z
; Not a number. Try PC
push de
push de ; --> lvl 1
ld de, .sDollar
call strcmp
pop de
pop de ; <-- lvl 1
jr z, .returnPC
; Not PC either, try symbol
call symSelect
call symFind
push de ; --> lvl 1
call symFindVal ; --> DE
jr nz, .notfound
; Found! let's fetch value
push de
call symGetVal
; value in DE. We need it in IX
push de \ pop ix
pop de
pop de ; <-- lvl 1
cp a ; ensure Z
ret
.notfound:
pop de ; <-- lvl 1
; 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.
; Otherwise return error. Z is already unset, so in fact, this is the

View File

@ -238,12 +238,6 @@ symRegister:
ld a, ERR_DUPSYM
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
; corresponding entry in (SYM_CTX_VALUES).
; If we find something, Z is set, otherwise unset.
@ -277,7 +271,21 @@ symFind:
pop ix
ret
; For a given symbol name in (HL), find it in the appropriate symbol register
; 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.
symGetVal:
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:
zasmIsFirstPass:
symSelect:
symFind:
symGetVal:
symFindVal:
jp fail
testNum: .db 1

View File

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

View File

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