mirror of
https://github.com/hsoft/collapseos.git
synced 2024-11-27 15:08:05 +11:00
zasm: add ERR_DUPSYM and ERR_OOM error conditions
This commit is contained in:
parent
b298e607bd
commit
e414e600ea
@ -13,3 +13,9 @@
|
|||||||
.equ ERR_OVFL 0x04
|
.equ ERR_OVFL 0x04
|
||||||
|
|
||||||
.equ ERR_FILENOTFOUND 0x05
|
.equ ERR_FILENOTFOUND 0x05
|
||||||
|
|
||||||
|
; Duplicate symbol
|
||||||
|
.equ ERR_DUPSYM 0x06
|
||||||
|
|
||||||
|
; Out of memory
|
||||||
|
.equ ERR_OOM 0x07
|
||||||
|
@ -104,6 +104,8 @@ handleDW:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
handleEQU:
|
handleEQU:
|
||||||
|
call zasmIsLocalPass ; Are we in local pass? Then ignore all .equ.
|
||||||
|
jr z, .skip ; they mess up duplicate symbol detection.
|
||||||
push hl
|
push hl
|
||||||
push de
|
push de
|
||||||
push bc
|
push bc
|
||||||
@ -124,8 +126,7 @@ handleEQU:
|
|||||||
jr nz, .badarg
|
jr nz, .badarg
|
||||||
ld hl, DIREC_SCRATCHPAD
|
ld hl, DIREC_SCRATCHPAD
|
||||||
push ix \ pop de
|
push ix \ pop de
|
||||||
call symRegister ; TODO: handle duplicate symbol error, OOM, etc.
|
call symRegister ; A and Z set
|
||||||
cp a ; ensure Z
|
|
||||||
jr .end
|
jr .end
|
||||||
.badfmt:
|
.badfmt:
|
||||||
ld a, ERR_BAD_FMT
|
ld a, ERR_BAD_FMT
|
||||||
@ -139,6 +140,10 @@ handleEQU:
|
|||||||
pop de
|
pop de
|
||||||
pop hl
|
pop hl
|
||||||
ret
|
ret
|
||||||
|
.skip:
|
||||||
|
; consume args and return
|
||||||
|
call readWord
|
||||||
|
jp readWord
|
||||||
|
|
||||||
handleORG:
|
handleORG:
|
||||||
call readWord
|
call readWord
|
||||||
|
@ -120,8 +120,7 @@ _parseInstr:
|
|||||||
|
|
||||||
_parseDirec:
|
_parseDirec:
|
||||||
ld a, c ; D_*
|
ld a, c ; D_*
|
||||||
call parseDirective
|
jp parseDirective
|
||||||
ret
|
|
||||||
|
|
||||||
_parseLabel:
|
_parseLabel:
|
||||||
; The string in (scratchpad) is a label with its trailing ':' removed.
|
; The string in (scratchpad) is a label with its trailing ':' removed.
|
||||||
|
@ -11,11 +11,6 @@
|
|||||||
; and continue second pass as usual.
|
; and continue second pass as usual.
|
||||||
|
|
||||||
; *** Constants ***
|
; *** Constants ***
|
||||||
; Duplicate symbol in registry
|
|
||||||
.equ SYM_ERR_DUPLICATE 0x01
|
|
||||||
; Symbol registry buffer is full
|
|
||||||
.equ SYM_ERR_FULLBUF 0x02
|
|
||||||
|
|
||||||
; Maximum number of symbols we can have in the global registry
|
; Maximum number of symbols we can have in the global registry
|
||||||
.equ SYM_MAXCOUNT 0x200
|
.equ SYM_MAXCOUNT 0x200
|
||||||
; Maximum number of symbols we can have in the local registry
|
; Maximum number of symbols we can have in the local registry
|
||||||
@ -153,7 +148,7 @@ symNamesEnd:
|
|||||||
; Register label in (HL) (minus the ending ":") into the symbol registry and
|
; Register label in (HL) (minus the ending ":") into the symbol registry and
|
||||||
; set its value in that registry to DE.
|
; set its value in that registry to DE.
|
||||||
; If successful, Z is set and A is the symbol index. Otherwise, Z is unset and
|
; If successful, Z is set and A is the symbol index. Otherwise, Z is unset and
|
||||||
; A is an error code (SYM_ERR_*).
|
; A is an error code (ERR_*).
|
||||||
symRegister:
|
symRegister:
|
||||||
call symFind
|
call symFind
|
||||||
jr z, .alreadyThere
|
jr z, .alreadyThere
|
||||||
@ -167,7 +162,7 @@ symRegister:
|
|||||||
ld c, a ; save that strlen for later
|
ld c, a ; save that strlen for later
|
||||||
|
|
||||||
call symNamesEnd
|
call symNamesEnd
|
||||||
jr nz, .error
|
jr nz, .outOfMemory
|
||||||
|
|
||||||
; Is our new name going to make us go out of bounds?
|
; Is our new name going to make us go out of bounds?
|
||||||
push hl
|
push hl
|
||||||
@ -178,7 +173,7 @@ symRegister:
|
|||||||
call cpHLDE
|
call cpHLDE
|
||||||
pop de
|
pop de
|
||||||
pop hl
|
pop hl
|
||||||
jr nc, .error ; HL >= DE
|
jr nc, .outOfMemory ; HL >= DE
|
||||||
|
|
||||||
; Success. At this point, we have:
|
; Success. At this point, we have:
|
||||||
; HL -> where we want to add the string
|
; HL -> where we want to add the string
|
||||||
@ -201,16 +196,37 @@ symRegister:
|
|||||||
; list. DE is already correctly placed, A is already zero
|
; list. DE is already correctly placed, A is already zero
|
||||||
ld (de), a
|
ld (de), a
|
||||||
|
|
||||||
|
cp a ; ensure Z
|
||||||
; Nothing to pop. We've already popped our stack in the lines above.
|
; Nothing to pop. We've already popped our stack in the lines above.
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.error:
|
.outOfMemory:
|
||||||
|
ld a, ERR_OOM
|
||||||
call unsetZ
|
call unsetZ
|
||||||
pop de
|
pop de
|
||||||
pop hl
|
pop hl
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.alreadyThere:
|
.alreadyThere:
|
||||||
|
; We are in a tricky situation with regards to our handling of the
|
||||||
|
; duplicate symbol error. Normally, it should be straightforward: We
|
||||||
|
; only register labels during first pass and evaluate constants during
|
||||||
|
; the second. Easy.
|
||||||
|
; We can *almost* do that... but we have ".org". .org affects label
|
||||||
|
; values and supports expressions, which means that we have to evaluate
|
||||||
|
; constants during first pass. But because we can possibly have forward
|
||||||
|
; references in ".equ", some constants are going to have a bad value.
|
||||||
|
; Therefore, we really can't evaluate all constants during the first
|
||||||
|
; pass.
|
||||||
|
; With this situation, how do you manage detection of duplicate symbols?
|
||||||
|
; By limiting the "duplicate error" condition to the first pass. During,
|
||||||
|
; first pass, sure, we don't have our proper values, but we have all our
|
||||||
|
; symbol names. So, if we end up in .alreadyThere during first pass,
|
||||||
|
; then it's an error condition. If it's not first pass, then we need
|
||||||
|
; to update our value.
|
||||||
|
call zasmIsFirstPass
|
||||||
|
jr z, .duplicateError
|
||||||
|
; Second pass. Don't error out, just update value
|
||||||
push hl
|
push hl
|
||||||
ld hl, (SYM_CTX_PTR)
|
ld hl, (SYM_CTX_PTR)
|
||||||
ex de, hl
|
ex de, hl
|
||||||
@ -218,6 +234,9 @@ symRegister:
|
|||||||
pop hl
|
pop hl
|
||||||
cp a ; ensure Z
|
cp a ; ensure Z
|
||||||
ret
|
ret
|
||||||
|
.duplicateError:
|
||||||
|
ld a, ERR_DUPSYM
|
||||||
|
jp unsetZ ; return
|
||||||
|
|
||||||
; Select global or local registry according to label name in (HL)
|
; Select global or local registry according to label name in (HL)
|
||||||
symSelect:
|
symSelect:
|
||||||
@ -246,7 +265,6 @@ symFind:
|
|||||||
inc ix
|
inc ix
|
||||||
inc ix
|
inc ix
|
||||||
jr .loop
|
jr .loop
|
||||||
; exhausted djnz? no match
|
|
||||||
.nomatch:
|
.nomatch:
|
||||||
call unsetZ
|
call unsetZ
|
||||||
jr .end
|
jr .end
|
||||||
|
@ -4,6 +4,7 @@ jp test
|
|||||||
#include "core.asm"
|
#include "core.asm"
|
||||||
#include "parse.asm"
|
#include "parse.asm"
|
||||||
#include "zasm/util.asm"
|
#include "zasm/util.asm"
|
||||||
|
#include "zasm/const.asm"
|
||||||
#include "zasm/parse.asm"
|
#include "zasm/parse.asm"
|
||||||
.equ SYM_RAMSTART RAMSTART
|
.equ SYM_RAMSTART RAMSTART
|
||||||
#include "zasm/symbol.asm"
|
#include "zasm/symbol.asm"
|
||||||
|
@ -3,9 +3,14 @@ jp test
|
|||||||
|
|
||||||
#include "core.asm"
|
#include "core.asm"
|
||||||
#include "zasm/util.asm"
|
#include "zasm/util.asm"
|
||||||
|
#include "zasm/const.asm"
|
||||||
.equ SYM_RAMSTART RAMSTART
|
.equ SYM_RAMSTART RAMSTART
|
||||||
#include "zasm/symbol.asm"
|
#include "zasm/symbol.asm"
|
||||||
|
|
||||||
|
; Pretend that we aren't in first pass
|
||||||
|
zasmIsFirstPass:
|
||||||
|
jp unsetZ
|
||||||
|
|
||||||
testNum: .db 1
|
testNum: .db 1
|
||||||
|
|
||||||
sFOO: .db "FOO", 0
|
sFOO: .db "FOO", 0
|
||||||
|
@ -16,6 +16,24 @@ chkerr() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chkoom() {
|
||||||
|
echo "Trying OOM error..."
|
||||||
|
local s=""
|
||||||
|
# 300 x 27-29 bytes > 8192 bytes. Large enough to smash the pool.
|
||||||
|
for i in {1..300}; do
|
||||||
|
s+=".equ abcdefghijklmnopqrstuvwxyz$i 42"
|
||||||
|
s+=$'\n'
|
||||||
|
done
|
||||||
|
${ZASM} <<< "$s" > /dev/null
|
||||||
|
local res=$?
|
||||||
|
if [[ $res == 7 ]]; then
|
||||||
|
echo "Good!"
|
||||||
|
else
|
||||||
|
echo "$res != 7"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
chkerr "foo" 1
|
chkerr "foo" 1
|
||||||
chkerr "ld a, foo" 2
|
chkerr "ld a, foo" 2
|
||||||
chkerr "ld a, hl" 2
|
chkerr "ld a, hl" 2
|
||||||
@ -37,3 +55,5 @@ chkerr "#inc foo" 3
|
|||||||
chkerr "ld a, 0x100" 4
|
chkerr "ld a, 0x100" 4
|
||||||
chkerr ".db 0x100" 4
|
chkerr ".db 0x100" 4
|
||||||
chkerr "#inc \"doesnotexist\"" 5
|
chkerr "#inc \"doesnotexist\"" 5
|
||||||
|
chkerr ".equ foo 42 \\ .equ foo 42" 6
|
||||||
|
chkoom
|
||||||
|
Loading…
Reference in New Issue
Block a user