From 072aad775a5e1e795860f05dcff6586e2d013904 Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Fri, 17 May 2019 13:14:16 -0400 Subject: [PATCH] zasm: don't match prefixes in symFind Only match when full names match. --- apps/zasm/symbol.asm | 7 +-- apps/zasm/tok.asm | 1 + apps/zasm/util_z.asm | 26 ++++++++++ tools/tests/unit/test_expr.asm | 88 ++++++++++++++++++++++++++++++++ tools/tests/unit/test_symbol.asm | 53 +++++++++++++++++++ 5 files changed, 169 insertions(+), 6 deletions(-) create mode 100644 tools/tests/unit/test_expr.asm create mode 100644 tools/tests/unit/test_symbol.asm diff --git a/apps/zasm/symbol.asm b/apps/zasm/symbol.asm index 4bb5491..5e77a10 100644 --- a/apps/zasm/symbol.asm +++ b/apps/zasm/symbol.asm @@ -217,17 +217,12 @@ symFind: push bc push de - ; First, what's our strlen? - call strlen - ld c, a ; let's save that - ex hl, de ; it's easier if HL is haystack and DE is ; needle. ld b, 0 ld hl, (SYM_CTX_NAMES) .loop: - ld a, c ; recall strlen - call strncmp + call strcmp jr z, .match ; ok, next! call _symNext diff --git a/apps/zasm/tok.asm b/apps/zasm/tok.asm index 6fdb458..3049def 100644 --- a/apps/zasm/tok.asm +++ b/apps/zasm/tok.asm @@ -64,6 +64,7 @@ isLabel: ; We have a match! ; Remove trailing ':' xor a ; Z is set + dec hl ld (hl), a jr .end .nomatch: diff --git a/apps/zasm/util_z.asm b/apps/zasm/util_z.asm index 22958ec..bc98d33 100644 --- a/apps/zasm/util_z.asm +++ b/apps/zasm/util_z.asm @@ -91,6 +91,32 @@ strncmpI: ; early, set otherwise) ret +; Compares strings pointed to by HL and DE until one of them hits its null char. +; If equal, Z is set. If not equal, Z is reset. +strcmp: + push hl + push de + +.loop: + ld a, (de) + cp (hl) + jr nz, .end ; not equal? break early. NZ is carried out + ; to the called + cp 0 ; If our chars are null, stop the cmp + jr z, .end ; The positive result will be carried to the + ; caller + inc hl + inc de + jr .loop + +.end: + pop de + pop hl + ; Because we don't call anything else than CP that modify the Z flag, + ; our Z value will be that of the last cp (reset if we broke the loop + ; early, set otherwise) + ret + ; If string at (HL) starts with ( and ends with ), "enter" into the parens ; (advance HL and put a null char at the end of the string) and set Z. ; Otherwise, do nothing and reset Z. diff --git a/tools/tests/unit/test_expr.asm b/tools/tests/unit/test_expr.asm new file mode 100644 index 0000000..6e4938c --- /dev/null +++ b/tools/tests/unit/test_expr.asm @@ -0,0 +1,88 @@ +.equ RAMSTART 0x4000 +jp test + +#include "core.asm" +#include "parse.asm" +#include "util_z.asm" +#include "parse_z.asm" +.equ SYM_RAMSTART RAMSTART +#include "symbol.asm" +#include "expr.asm" + +; Pretend that we aren't in first pass +zasmIsFirstPass: + jp unsetZ + +testNum: .db 1 + +s1: .db "2+2", 0 +s2: .db "0x4001+0x22", 0 +s3: .db "FOO+BAR", 0 + +sFOO: .db "FOO", 0 +sBAR: .db "BAR", 0 + +test: + ld hl, 0xffff + ld sp, hl + + ld hl, s1 + call parseExpr + jp nz, fail + ld a, ixh + or a + jp nz, fail + ld a, ixl + cp 4 + jp nz, fail + call nexttest + + ld hl, s2 + call parseExpr + jp nz, fail + ld a, ixh + cp 0x40 + jp nz, fail + ld a, ixl + cp 0x23 + jp nz, fail + call nexttest + + ; before the next test, let's set up FOO and BAR symbols + call symInit + ld hl, sFOO + ld de, 0x4000 + call symRegister + jp nz, fail + ld hl, sBAR + ld de, 0x20 + call symRegister + jp nz, fail + + ld hl, s3 + call parseExpr + jp nz, fail + ld a, ixh + cp 0x40 + jp nz, fail + ld a, ixl + cp 0x20 + jp nz, fail + call nexttest + + ; success + xor a + halt + +nexttest: + ld a, (testNum) + inc a + ld (testNum), a + ret + +fail: + ld a, (testNum) + halt + + + diff --git a/tools/tests/unit/test_symbol.asm b/tools/tests/unit/test_symbol.asm new file mode 100644 index 0000000..809b869 --- /dev/null +++ b/tools/tests/unit/test_symbol.asm @@ -0,0 +1,53 @@ +.equ RAMSTART 0x4000 +jp test + +#include "core.asm" +#include "util_z.asm" +.equ SYM_RAMSTART RAMSTART +#include "symbol.asm" + +testNum: .db 1 + +sFOO: .db "FOO", 0 +sFOOBAR: .db "FOOBAR", 0 + +test: + ld hl, 0xffff + ld sp, hl + + ; Check that we compare whole strings (a prefix will not match a longer + ; string). + call symInit + ld hl, sFOOBAR + ld de, 42 + call symRegister + jp nz, fail + ld hl, sFOO + ld de, 43 + call symRegister + jp nz, fail + + ld hl, sFOO + call symFind + jp nz, fail + cp 1 ; don't match FOOBAR + jp nz, fail + call nexttest + + ; success + xor a + halt + +nexttest: + ld a, (testNum) + inc a + ld (testNum), a + ret + +fail: + ld a, (testNum) + halt + + + +