|
- ; Parse an expression yielding a truth value from (HL) and set A accordingly.
- ; 0 for False, nonzero for True.
- ; How it evaluates truth is that it looks for =, <, >, >= or <= in (HL) and,
- ; if it finds it, evaluate left and right expressions separately. Then it
- ; compares both sides and set A accordingly.
- ; If comparison operators aren't found, the whole string is sent to parseExpr
- ; and zero means False, nonzero means True.
- ; **This routine mutates (HL).**
- ; Z for success.
- parseTruth:
- push ix
- push de
- ld a, '='
- call .maybeFind
- jr z, .foundEQ
- ld a, '<'
- call .maybeFind
- jr z, .foundLT
- ld a, '>'
- call .maybeFind
- jr z, .foundGT
- jr .simple
- .success:
- cp a ; ensure Z
- .end:
- pop de
- pop ix
- ret
-
- .maybeFind:
- push hl ; --> lvl 1
- call findchar
- jr nz, .notFound
- ; found! We want to keep new HL around. Let's pop old HL in DE
- pop de ; <-- lvl 1
- ret
- .notFound:
- ; not found, restore HL
- pop hl ; <-- lvl 1
- ret
-
- .simple:
- call parseExpr
- jr nz, .end
- push ix \ pop de
- ld a, d
- or e
- jr .success
-
- .foundEQ:
- ; we found an '=' char and HL is pointing to it. DE is pointing to the
- ; beginning of our string. Let's separate those two strings.
- ; But before we do that, to we have a '<' or a '>' at the left of (HL)?
- dec hl
- ld a, (hl)
- cp '<'
- jr z, .foundLTE
- cp '>'
- jr z, .foundGTE
- inc hl
- ; Ok, we are a straight '='. Proceed.
- call .splitLR
- ; HL now point to right-hand, DE to left-hand
- call .parseLeftRight
- jr nz, .end ; error, stop
- xor a ; clear carry and prepare value for False
- sbc hl, de
- jr nz, .success ; NZ? equality not met. A already 0, return.
- ; Z? equality met, make A=1, set Z
- inc a
- jr .success
-
- .foundLTE:
- ; Almost the same as '<', but we have two sep chars
- call .splitLR
- inc hl ; skip the '=' char
- call .parseLeftRight
- jr nz, .end
- ld a, 1 ; prepare for True
- sbc hl, de
- jr nc, .success ; Left <= Right, True
- ; Left > Right, False
- dec a
- jr .success
-
- .foundGTE:
- ; Almost the same as '<='
- call .splitLR
- inc hl ; skip the '=' char
- call .parseLeftRight
- jr nz, .end
- ld a, 1 ; prepare for True
- sbc hl, de
- jr z, .success ; Left == Right, True
- jr c, .success ; Left > Right, True
- ; Left < Right, False
- dec a
- jr .success
-
- .foundLT:
- ; Same thing as EQ, but for '<'
- call .splitLR
- call .parseLeftRight
- jr nz, .end
- xor a
- sbc hl, de
- jr z, .success ; Left == Right, False
- jr c, .success ; Left > Right, False
- ; Left < Right, True
- inc a
- jr .success
-
- .foundGT:
- ; Same thing as EQ, but for '>'
- call .splitLR
- call .parseLeftRight
- jr nz, .end
- xor a
- sbc hl, de
- jr nc, .success ; Left <= Right, False
- ; Left > Right, True
- inc a
- jr .success
-
- .splitLR:
- xor a
- ld (hl), a
- inc hl
- ret
-
- ; Given string pointers in (HL) and (DE), evaluate those two expressions and
- ; place their corresponding values in HL and DE.
- .parseLeftRight:
- ; let's start with HL
- call parseExpr
- ret nz
- push ix ; --> lvl 1. save (HL) value in stack.
- ex de, hl
- call parseExpr
- ret nz
- push ix \ pop de
- pop hl ; <-- lvl 1. restore.
- ret
|