diff --git a/apps/lib/ari.asm b/apps/lib/ari.asm index b5ade17..8f40838 100644 --- a/apps/lib/ari.asm +++ b/apps/lib/ari.asm @@ -25,3 +25,20 @@ divide: sbc a, d ld h, a ret + +; DE * BC -> DE (high) and HL (low) +multDEBC: + ld hl, 0 + ld a, 0x10 +.loop: + add hl, hl + rl e + rl d + jr nc, .noinc + add hl, bc + jr nc, .noinc + inc de +.noinc: + dec a + jr nz, .loop + ret diff --git a/apps/lib/expr.asm b/apps/lib/expr.asm index ce8f1b5..e144d46 100644 --- a/apps/lib/expr.asm +++ b/apps/lib/expr.asm @@ -23,16 +23,30 @@ parseExpr: ret _parseExpr: - ld a, '+' + ld de, exprTbl +.loop: + ld a, (de) + or a + jp z, EXPR_PARSE ; no operator, just parse the literal + push de ; --> lvl 1. save operator row call _findAndSplit - jp z, _applyPlus - ld a, '-' - call _findAndSplit - jp z, _applyMinus - ld a, '*' - call _findAndSplit - jp z, _applyMult - jp EXPR_PARSE + jr z, .found + pop de ; <-- lvl 1 + inc de \ inc de \ inc de + jr .loop +.found: + ; Operator found, string splitted. Left in (HL), right in (DE) + call _resolveLeftAndRight + ; Whether _resolveLeftAndRight was a success, we pop our lvl 1 stack + ; out, which contains our operator row. We pop it in HL because we + ; don't need our string anymore. L-R numbers are parsed, and in DE and + ; IX. + pop hl ; <-- lvl 1 + ret nz + ; Resolving left and right succeeded, proceed! + inc hl ; point to routine pointer + call intoHL + jp (hl) ; Given a string in (HL) and a separator char in A, return a splitted string, ; that is, the same (HL) string but with the found A char replaced by a null @@ -88,20 +102,25 @@ _resolveLeftAndRight: pop de ; numeric left expr result in DE jp parseExpr -; Parse expr in (HL) and expr in (DE) and apply + operator to both sides. -; Put result in IX. -_applyPlus: - call _resolveLeftAndRight - ret nz - ; Good! let's do the math! IX has our right part, DE has our left one. +; Routines in here all have the same signature: they take two numbers, DE (left) +; and IX (right), apply the operator and put the resulting number in IX. +; The table has 3 bytes per row: 1 byte for operator and 2 bytes for routine +; pointer. +exprTbl: + .db '+' + .dw .plus + .db '-' + .dw .minus + .db '*' + .dw .mult + .db 0 ; end of table + +.plus: add ix, de cp a ; ensure Z ret -; Same as _applyPlus but with - -_applyMinus: - call _resolveLeftAndRight - ret nz +.minus: push ix pop hl ex de, hl @@ -112,9 +131,7 @@ _applyMinus: cp a ; ensure Z ret -_applyMult: - call _resolveLeftAndRight - ret nz +.mult: push ix \ pop bc call multDEBC push hl \ pop ix diff --git a/apps/lib/util.asm b/apps/lib/util.asm index b5be841..3cad42a 100644 --- a/apps/lib/util.asm +++ b/apps/lib/util.asm @@ -73,20 +73,3 @@ strlen: pop hl pop bc ret - -; DE * BC -> DE (high) and HL (low) -multDEBC: - ld hl, 0 - ld a, 0x10 -.loop: - add hl, hl - rl e - rl d - jr nc, .noinc - add hl, bc - jr nc, .noinc - inc de -.noinc: - dec a - jr nz, .loop - ret diff --git a/apps/zasm/glue.asm b/apps/zasm/glue.asm index f577ff6..291df8c 100644 --- a/apps/zasm/glue.asm +++ b/apps/zasm/glue.asm @@ -66,6 +66,7 @@ jp zasmMain .inc "core.asm" .inc "zasm/const.asm" .inc "lib/util.asm" +.inc "lib/ari.asm" .inc "lib/parse.asm" .inc "lib/args.asm" .inc "zasm/util.asm" diff --git a/tools/tests/unit/test_basic_parse.asm b/tools/tests/unit/test_basic_parse.asm index 5bf0dab..6949da5 100644 --- a/tools/tests/unit/test_basic_parse.asm +++ b/tools/tests/unit/test_basic_parse.asm @@ -3,6 +3,7 @@ jp test .inc "core.asm" .inc "str.asm" .inc "lib/util.asm" +.inc "lib/ari.asm" .inc "lib/parse.asm" .equ EXPR_PARSE parseLiteral .inc "lib/expr.asm" diff --git a/tools/tests/unit/test_expr.asm b/tools/tests/unit/test_expr.asm index 5b580cf..a906ad5 100644 --- a/tools/tests/unit/test_expr.asm +++ b/tools/tests/unit/test_expr.asm @@ -12,6 +12,7 @@ jp test .inc "core.asm" .inc "str.asm" .inc "lib/util.asm" +.inc "lib/ari.asm" .inc "zasm/util.asm" .inc "zasm/const.asm" .inc "lib/parse.asm" diff --git a/tools/tests/unit/test_lib_ari.asm b/tools/tests/unit/test_lib_ari.asm new file mode 100644 index 0000000..b81ba28 --- /dev/null +++ b/tools/tests/unit/test_lib_ari.asm @@ -0,0 +1,35 @@ +jp test + +.inc "core.asm" +.inc "lib/ari.asm" + +testNum: .db 1 + +test: + ld sp, 0xffff + + ld de, 12 + ld bc, 4 + call multDEBC + ld a, l + cp 48 + 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_util_z.asm b/tools/tests/unit/test_util_z.asm index 7dfd10d..fd461f0 100644 --- a/tools/tests/unit/test_util_z.asm +++ b/tools/tests/unit/test_util_z.asm @@ -12,14 +12,6 @@ test: ld hl, 0xffff ld sp, hl - ld de, 12 - ld bc, 4 - call multDEBC - ld a, l - cp 48 - jp nz, fail - call nexttest - ld hl, sFoo call strlen cp 3 diff --git a/tools/tests/unit/test_z_instr.asm b/tools/tests/unit/test_z_instr.asm index 04d2248..96bf755 100644 --- a/tools/tests/unit/test_z_instr.asm +++ b/tools/tests/unit/test_z_instr.asm @@ -4,6 +4,7 @@ jp runTests .inc "core.asm" .inc "str.asm" .inc "zasm/const.asm" +.inc "lib/ari.asm" .inc "lib/util.asm" .inc "zasm/util.asm" .inc "lib/parse.asm"