mirror of
https://github.com/hsoft/collapseos.git
synced 2024-11-24 00:08:06 +11:00
lib/parse: make parseLiteral a little tighter
Sub-parsers are seldom used by themselves, except for parseDecimal. I'm tightening the code of this unit for two reasons: 1. Optimization 2. Upcoming API change where HL won't be preserved anymore, but will point to char following the last parse char. This will allow us to simplify lib/expr.
This commit is contained in:
parent
15628da7de
commit
d0f031939f
@ -74,6 +74,8 @@ There are decimal, hexadecimal and binary literals. A "straight" number is
|
|||||||
parsed as a decimal. Hexadecimal literals must be prefixed with `0x` (`0xf4`).
|
parsed as a decimal. Hexadecimal literals must be prefixed with `0x` (`0xf4`).
|
||||||
Binary must be prefixed with `0b` (`0b01100110`).
|
Binary must be prefixed with `0b` (`0b01100110`).
|
||||||
|
|
||||||
|
A decimal literal cannot start with `0`, with the exception of the `0` literal.
|
||||||
|
|
||||||
Decimals and hexadecimal are "flexible". Whether they're written in a byte or
|
Decimals and hexadecimal are "flexible". Whether they're written in a byte or
|
||||||
a word, you don't need to prefix them with zeroes. Watch out for overflow,
|
a word, you don't need to prefix them with zeroes. Watch out for overflow,
|
||||||
however.
|
however.
|
||||||
|
@ -140,15 +140,11 @@ parseDecimal:
|
|||||||
pop hl ; <-- lvl 1, orig
|
pop hl ; <-- lvl 1, orig
|
||||||
jp unsetZ
|
jp unsetZ
|
||||||
|
|
||||||
; Parse string at (HL) as a hexadecimal value and return value in DE under the
|
; Parse string at (HL) as a hexadecimal value without the "0x" prefix and
|
||||||
; same conditions as parseLiteral.
|
; return value in DE.
|
||||||
|
; Sets Z on success.
|
||||||
parseHexadecimal:
|
parseHexadecimal:
|
||||||
call hasHexPrefix
|
|
||||||
ret nz
|
|
||||||
push hl
|
push hl
|
||||||
ld d, 0
|
|
||||||
inc hl ; get rid of "0x"
|
|
||||||
inc hl
|
|
||||||
call strlen
|
call strlen
|
||||||
cp 3
|
cp 3
|
||||||
jr c, .single
|
jr c, .single
|
||||||
@ -182,29 +178,12 @@ parseHexadecimal:
|
|||||||
pop hl
|
pop hl
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; Sets Z if (HL) has a '0x' prefix.
|
; Parse string at (HL) as a binary value (010101) without the "0b" prefix and
|
||||||
hasHexPrefix:
|
; return value in E. D is always zero.
|
||||||
ld a, (hl)
|
|
||||||
cp '0'
|
|
||||||
ret nz
|
|
||||||
push hl
|
|
||||||
inc hl
|
|
||||||
ld a, (hl)
|
|
||||||
cp 'x'
|
|
||||||
pop hl
|
|
||||||
ret
|
|
||||||
|
|
||||||
; Parse string at (HL) as a binary value (0b010101) and return value in E.
|
|
||||||
; D is always zero.
|
|
||||||
; Sets Z on success.
|
; Sets Z on success.
|
||||||
parseBinaryLiteral:
|
parseBinaryLiteral:
|
||||||
call hasBinPrefix
|
|
||||||
ret nz
|
|
||||||
push bc
|
push bc
|
||||||
push hl
|
push hl
|
||||||
ld d, 0
|
|
||||||
inc hl ; get rid of "0b"
|
|
||||||
inc hl
|
|
||||||
call strlen
|
call strlen
|
||||||
or a
|
or a
|
||||||
jr z, .error ; empty, error
|
jr z, .error ; empty, error
|
||||||
@ -237,49 +216,6 @@ parseBinaryLiteral:
|
|||||||
pop bc
|
pop bc
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; Sets Z if (HL) has a '0b' prefix.
|
|
||||||
hasBinPrefix:
|
|
||||||
ld a, (hl)
|
|
||||||
cp '0'
|
|
||||||
ret nz
|
|
||||||
push hl
|
|
||||||
inc hl
|
|
||||||
ld a, (hl)
|
|
||||||
cp 'b'
|
|
||||||
pop hl
|
|
||||||
ret
|
|
||||||
|
|
||||||
; Parse string at (HL) and, if it is a char literal, sets Z and return
|
|
||||||
; corresponding value in E. D is always zero.
|
|
||||||
;
|
|
||||||
; A valid char literal starts with ', ends with ' and has one character in the
|
|
||||||
; middle. No escape sequence are accepted, but ''' will return the apostrophe
|
|
||||||
; character.
|
|
||||||
parseCharLiteral:
|
|
||||||
ld a, 0x27 ; apostrophe (') char
|
|
||||||
cp (hl)
|
|
||||||
ret nz
|
|
||||||
|
|
||||||
push hl
|
|
||||||
inc hl
|
|
||||||
inc hl
|
|
||||||
cp (hl)
|
|
||||||
jr nz, .end ; not ending with an apostrophe
|
|
||||||
inc hl
|
|
||||||
ld a, (hl)
|
|
||||||
or a ; cp 0
|
|
||||||
jr nz, .end ; string has to end there
|
|
||||||
; Valid char, good
|
|
||||||
ld d, a ; A is zero, take advantage of that
|
|
||||||
dec hl
|
|
||||||
dec hl
|
|
||||||
ld a, (hl)
|
|
||||||
ld e, a
|
|
||||||
cp a ; ensure Z
|
|
||||||
.end:
|
|
||||||
pop hl
|
|
||||||
ret
|
|
||||||
|
|
||||||
; Parses the string at (HL) and returns the 16-bit value in DE. The string
|
; Parses the string at (HL) and returns the 16-bit value in DE. The string
|
||||||
; can be a decimal literal (1234), a hexadecimal literal (0x1234) or a char
|
; can be a decimal literal (1234), a hexadecimal literal (0x1234) or a char
|
||||||
; literal ('X').
|
; literal ('X').
|
||||||
@ -287,11 +223,57 @@ parseCharLiteral:
|
|||||||
; As soon as the number doesn't fit 16-bit any more, parsing stops and the
|
; As soon as the number doesn't fit 16-bit any more, parsing stops and the
|
||||||
; number is invalid. If the number is valid, Z is set, otherwise, unset.
|
; number is invalid. If the number is valid, Z is set, otherwise, unset.
|
||||||
parseLiteral:
|
parseLiteral:
|
||||||
call parseCharLiteral
|
ld de, 0 ; pre-fill
|
||||||
ret z
|
ld a, (hl)
|
||||||
call parseHexadecimal
|
cp 0x27 ; apostrophe
|
||||||
ret z
|
jr z, .char
|
||||||
call parseBinaryLiteral
|
cp '0'
|
||||||
ret z
|
jr z, .hexOrBin
|
||||||
jp parseDecimal
|
jp parseDecimal
|
||||||
|
|
||||||
|
; Parse string at (HL) and, if it is a char literal, sets Z and return
|
||||||
|
; corresponding value in E. D is always zero.
|
||||||
|
;
|
||||||
|
; A valid char literal starts with ', ends with ' and has one character in the
|
||||||
|
; middle. No escape sequence are accepted, but ''' will return the apostrophe
|
||||||
|
; character.
|
||||||
|
.char:
|
||||||
|
push hl
|
||||||
|
inc hl
|
||||||
|
inc hl
|
||||||
|
cp (hl)
|
||||||
|
jr nz, .charEnd ; not ending with an apostrophe
|
||||||
|
inc hl
|
||||||
|
ld a, (hl)
|
||||||
|
or a ; cp 0
|
||||||
|
jr nz, .charEnd ; string has to end there
|
||||||
|
; Valid char, good
|
||||||
|
dec hl
|
||||||
|
dec hl
|
||||||
|
ld e, (hl)
|
||||||
|
cp a ; ensure Z
|
||||||
|
.charEnd:
|
||||||
|
pop hl
|
||||||
|
ret
|
||||||
|
|
||||||
|
.hexOrBin:
|
||||||
|
inc hl
|
||||||
|
ld a, (hl)
|
||||||
|
inc hl ; already place it for hex or bin
|
||||||
|
cp 'x'
|
||||||
|
jr z, .hex
|
||||||
|
cp 'b'
|
||||||
|
jr z, .bin
|
||||||
|
; special case: single '0'. set Z if we hit have null terminating.
|
||||||
|
or a
|
||||||
|
.hexOrBinEnd:
|
||||||
|
dec hl \ dec hl ; replace HL
|
||||||
|
ret ; Z already set
|
||||||
|
|
||||||
|
.hex:
|
||||||
|
call parseHexadecimal
|
||||||
|
jr .hexOrBinEnd
|
||||||
|
|
||||||
|
.bin:
|
||||||
|
call parseBinaryLiteral
|
||||||
|
jr .hexOrBinEnd
|
||||||
|
Loading…
Reference in New Issue
Block a user