lib/expr: refactor for easier operator addition
This commit is contained in:
parent
fd5b2ab856
commit
1b01f13105
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
35
tools/tests/unit/test_lib_ari.asm
Normal file
35
tools/tests/unit/test_lib_ari.asm
Normal file
@ -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
|
||||
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user