mirror of
https://github.com/hsoft/collapseos.git
synced 2024-11-02 20:20:55 +11:00
Compare commits
5 Commits
1b01f13105
...
43b450ca30
Author | SHA1 | Date | |
---|---|---|---|
|
43b450ca30 | ||
|
501fe96e07 | ||
|
2f71ad6d2f | ||
|
a03c5ac700 | ||
|
972e8221f1 |
@ -89,8 +89,16 @@ this way, it's going to mess with the parser.
|
|||||||
|
|
||||||
### Expressions
|
### Expressions
|
||||||
|
|
||||||
An expression is a bunch of literals or symbols assembled by operators. For
|
An expression is a bunch of literals or symbols assembled by operators.
|
||||||
now, only `+`, `-` and `*` operators are supported. No parenthesis yet.
|
Supported operators are `+`, `-`, `*`, `/`, `%` (modulo), `&` (bitwise and),
|
||||||
|
`|` (bitwise or), `^` (bitwise xor), `{` (shift left), `}` (shift right).
|
||||||
|
Bitwise operator always operate on the whole 16-bits.
|
||||||
|
|
||||||
|
Shift operators break from the `<<` and `>>` tradition because the complexity
|
||||||
|
if two-sized operator is significant and deemed not worth it. The shift
|
||||||
|
operator shift the left operand X times, X being the right operand.
|
||||||
|
|
||||||
|
There is no parenthesis support yet.
|
||||||
|
|
||||||
Symbols have a different meaning depending on the application. In zasm, it's
|
Symbols have a different meaning depending on the application. In zasm, it's
|
||||||
labels and constants. In basic, it's variables.
|
labels and constants. In basic, it's variables.
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
; *** Requirements ***
|
; *** Requirements ***
|
||||||
; findchar
|
; findchar
|
||||||
; multDEBC
|
; multDEBC
|
||||||
|
; callIXI
|
||||||
;
|
;
|
||||||
; *** Defines ***
|
; *** Defines ***
|
||||||
;
|
;
|
||||||
@ -14,6 +15,9 @@
|
|||||||
; **This routine mutates (HL).**
|
; **This routine mutates (HL).**
|
||||||
; We expect (HL) to be disposable: we mutate it to avoid having to make a copy.
|
; We expect (HL) to be disposable: we mutate it to avoid having to make a copy.
|
||||||
; Sets Z on success, unset on error.
|
; Sets Z on success, unset on error.
|
||||||
|
; TODO: the IX output register is a bit awkward. Nearly everywhere, I need
|
||||||
|
; to push \ pop that thing. See if we could return the result in DE
|
||||||
|
; instead.
|
||||||
parseExpr:
|
parseExpr:
|
||||||
push de
|
push de
|
||||||
push hl
|
push hl
|
||||||
@ -38,15 +42,16 @@ _parseExpr:
|
|||||||
; Operator found, string splitted. Left in (HL), right in (DE)
|
; Operator found, string splitted. Left in (HL), right in (DE)
|
||||||
call _resolveLeftAndRight
|
call _resolveLeftAndRight
|
||||||
; Whether _resolveLeftAndRight was a success, we pop our lvl 1 stack
|
; Whether _resolveLeftAndRight was a success, we pop our lvl 1 stack
|
||||||
; out, which contains our operator row. We pop it in HL because we
|
; out, which contains our operator row. We pop it in IX.
|
||||||
; don't need our string anymore. L-R numbers are parsed, and in DE and
|
; L-R numbers are parsed in HL (left) and DE (right).
|
||||||
; IX.
|
pop ix ; <-- lvl 1
|
||||||
pop hl ; <-- lvl 1
|
|
||||||
ret nz
|
ret nz
|
||||||
; Resolving left and right succeeded, proceed!
|
; Resolving left and right succeeded, proceed!
|
||||||
inc hl ; point to routine pointer
|
inc ix ; point to routine pointer
|
||||||
call intoHL
|
call callIXI
|
||||||
jp (hl)
|
push de \ pop ix
|
||||||
|
cp a ; ensure Z
|
||||||
|
ret
|
||||||
|
|
||||||
; Given a string in (HL) and a separator char in A, return a splitted string,
|
; 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
|
; that is, the same (HL) string but with the found A char replaced by a null
|
||||||
@ -90,7 +95,7 @@ _findAndSplit:
|
|||||||
.find:
|
.find:
|
||||||
|
|
||||||
; parse expression on the left (HL) and the right (DE) and put the results in
|
; parse expression on the left (HL) and the right (DE) and put the results in
|
||||||
; DE (left) and IX (right)
|
; HL (left) and DE (right)
|
||||||
_resolveLeftAndRight:
|
_resolveLeftAndRight:
|
||||||
call parseExpr
|
call parseExpr
|
||||||
ret nz ; return immediately if error
|
ret nz ; return immediately if error
|
||||||
@ -98,12 +103,14 @@ _resolveLeftAndRight:
|
|||||||
; IX. What we need to do now is the same thing on (DE) and then apply
|
; IX. What we need to do now is the same thing on (DE) and then apply
|
||||||
; the + operator. Let's save IX somewhere and parse this.
|
; the + operator. Let's save IX somewhere and parse this.
|
||||||
ex de, hl ; right expr now in HL
|
ex de, hl ; right expr now in HL
|
||||||
push ix
|
push ix ; --> lvl 1
|
||||||
pop de ; numeric left expr result in DE
|
call parseExpr
|
||||||
jp parseExpr
|
pop hl ; <-- lvl 1. left
|
||||||
|
push ix \ pop de ; right
|
||||||
|
ret ; Z is parseExpr's result
|
||||||
|
|
||||||
; Routines in here all have the same signature: they take two numbers, DE (left)
|
; 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.
|
; and IX (right), apply the operator and put the resulting number in DE.
|
||||||
; The table has 3 bytes per row: 1 byte for operator and 2 bytes for routine
|
; The table has 3 bytes per row: 1 byte for operator and 2 bytes for routine
|
||||||
; pointer.
|
; pointer.
|
||||||
exprTbl:
|
exprTbl:
|
||||||
@ -113,27 +120,104 @@ exprTbl:
|
|||||||
.dw .minus
|
.dw .minus
|
||||||
.db '*'
|
.db '*'
|
||||||
.dw .mult
|
.dw .mult
|
||||||
|
.db '/'
|
||||||
|
.dw .div
|
||||||
|
.db '%'
|
||||||
|
.dw .mod
|
||||||
|
.db '&'
|
||||||
|
.dw .and
|
||||||
|
.db 0x7c ; '|'
|
||||||
|
.dw .or
|
||||||
|
.db '^'
|
||||||
|
.dw .xor
|
||||||
|
.db '}'
|
||||||
|
.dw .rshift
|
||||||
|
.db '{'
|
||||||
|
.dw .lshift
|
||||||
.db 0 ; end of table
|
.db 0 ; end of table
|
||||||
|
|
||||||
.plus:
|
.plus:
|
||||||
add ix, de
|
add hl, de
|
||||||
cp a ; ensure Z
|
ex de, hl
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.minus:
|
.minus:
|
||||||
push ix
|
or a ; clear carry
|
||||||
pop hl
|
|
||||||
ex de, hl
|
|
||||||
scf \ ccf
|
|
||||||
sbc hl, de
|
sbc hl, de
|
||||||
push hl
|
ex de, hl
|
||||||
pop ix
|
|
||||||
cp a ; ensure Z
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.mult:
|
.mult:
|
||||||
push ix \ pop bc
|
ld b, h
|
||||||
call multDEBC
|
ld c, l
|
||||||
push hl \ pop ix
|
call multDEBC ; --> HL
|
||||||
cp a ; ensure Z
|
ex de, hl
|
||||||
|
ret
|
||||||
|
|
||||||
|
.div:
|
||||||
|
; divide takes HL/DE
|
||||||
|
push bc
|
||||||
|
call divide
|
||||||
|
ld e, c
|
||||||
|
ld d, b
|
||||||
|
pop bc
|
||||||
|
ret
|
||||||
|
|
||||||
|
.mod:
|
||||||
|
call .div
|
||||||
|
ex de, hl
|
||||||
|
ret
|
||||||
|
|
||||||
|
.and:
|
||||||
|
ld a, h
|
||||||
|
and d
|
||||||
|
ld d, a
|
||||||
|
ld a, l
|
||||||
|
and e
|
||||||
|
ld e, a
|
||||||
|
ret
|
||||||
|
.or:
|
||||||
|
ld a, h
|
||||||
|
or d
|
||||||
|
ld d, a
|
||||||
|
ld a, l
|
||||||
|
or e
|
||||||
|
ld e, a
|
||||||
|
ret
|
||||||
|
|
||||||
|
.xor:
|
||||||
|
ld a, h
|
||||||
|
xor d
|
||||||
|
ld d, a
|
||||||
|
ld a, l
|
||||||
|
xor e
|
||||||
|
ld e, a
|
||||||
|
ret
|
||||||
|
|
||||||
|
.rshift:
|
||||||
|
ld a, e
|
||||||
|
and 0xf
|
||||||
|
ret z
|
||||||
|
push bc
|
||||||
|
ld b, a
|
||||||
|
.rshiftLoop:
|
||||||
|
srl h
|
||||||
|
rr l
|
||||||
|
djnz .rshiftLoop
|
||||||
|
ex de, hl
|
||||||
|
pop bc
|
||||||
|
ret
|
||||||
|
|
||||||
|
.lshift:
|
||||||
|
ld a, e
|
||||||
|
and 0xf
|
||||||
|
ret z
|
||||||
|
push bc
|
||||||
|
ld b, a
|
||||||
|
.lshiftLoop:
|
||||||
|
sla l
|
||||||
|
rl h
|
||||||
|
djnz .lshiftLoop
|
||||||
|
ex de, hl
|
||||||
|
pop bc
|
||||||
ret
|
ret
|
||||||
|
Binary file not shown.
Binary file not shown.
@ -42,9 +42,9 @@ sFOO: .db "FOO", 0
|
|||||||
sBAR: .db "BAR", 0
|
sBAR: .db "BAR", 0
|
||||||
|
|
||||||
test:
|
test:
|
||||||
ld hl, 0xffff
|
ld sp, 0xffff
|
||||||
ld sp, hl
|
|
||||||
|
|
||||||
|
; Old-style tests, not touching them now.
|
||||||
ld hl, s1
|
ld hl, s1
|
||||||
call parseExpr
|
call parseExpr
|
||||||
jp nz, fail
|
jp nz, fail
|
||||||
@ -128,10 +128,65 @@ test:
|
|||||||
jp nz, fail
|
jp nz, fail
|
||||||
call nexttest
|
call nexttest
|
||||||
|
|
||||||
|
; New-style tests
|
||||||
|
call testParseExpr
|
||||||
; success
|
; success
|
||||||
xor a
|
xor a
|
||||||
halt
|
halt
|
||||||
|
|
||||||
|
testParseExpr:
|
||||||
|
ld iy, .t1
|
||||||
|
call .testEQ
|
||||||
|
ld iy, .t2
|
||||||
|
call .testEQ
|
||||||
|
ld iy, .t3
|
||||||
|
call .testEQ
|
||||||
|
ld iy, .t4
|
||||||
|
call .testEQ
|
||||||
|
ld iy, .t5
|
||||||
|
call .testEQ
|
||||||
|
ld iy, .t6
|
||||||
|
call .testEQ
|
||||||
|
ld iy, .t7
|
||||||
|
call .testEQ
|
||||||
|
ret
|
||||||
|
|
||||||
|
.testEQ:
|
||||||
|
push iy \ pop hl
|
||||||
|
inc hl \ inc hl
|
||||||
|
call parseExpr
|
||||||
|
jp nz, fail
|
||||||
|
push ix \ pop de
|
||||||
|
ld a, e
|
||||||
|
cp (iy)
|
||||||
|
jp nz, fail
|
||||||
|
ld a, d
|
||||||
|
cp (iy+1)
|
||||||
|
jp nz, fail
|
||||||
|
jp nexttest
|
||||||
|
|
||||||
|
.t1:
|
||||||
|
.dw 7
|
||||||
|
.db "42/6", 0
|
||||||
|
.t2:
|
||||||
|
.dw 1
|
||||||
|
.db "7%3", 0
|
||||||
|
.t3:
|
||||||
|
.dw 0x0907
|
||||||
|
.db "0x99f7&0x0f0f", 0
|
||||||
|
.t4:
|
||||||
|
.dw 0x9fff
|
||||||
|
.db "0x99f7|0x0f0f", 0
|
||||||
|
.t5:
|
||||||
|
.dw 0x96f8
|
||||||
|
.db "0x99f7^0x0f0f", 0
|
||||||
|
.t6:
|
||||||
|
.dw 0x133e
|
||||||
|
.db "0x99f7}3", 0
|
||||||
|
.t7:
|
||||||
|
.dw 0xcfb8
|
||||||
|
.db "0x99f7{3", 0
|
||||||
|
|
||||||
nexttest:
|
nexttest:
|
||||||
ld a, (testNum)
|
ld a, (testNum)
|
||||||
inc a
|
inc a
|
||||||
|
Loading…
Reference in New Issue
Block a user