1
0
mirror of https://github.com/hsoft/collapseos.git synced 2024-11-03 00:30:55 +11:00

Compare commits

..

No commits in common. "43b450ca306a3725f80c42d9b1b939de3db4e8a1" and "1b01f131057fdf45f299aab07d15efdb60545c97" have entirely different histories.

5 changed files with 29 additions and 176 deletions

View File

@ -89,16 +89,8 @@ this way, it's going to mess with the parser.
### Expressions ### Expressions
An expression is a bunch of literals or symbols assembled by operators. An expression is a bunch of literals or symbols assembled by operators. For
Supported operators are `+`, `-`, `*`, `/`, `%` (modulo), `&` (bitwise and), now, only `+`, `-` and `*` operators are supported. No parenthesis yet.
`|` (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.

View File

@ -1,7 +1,6 @@
; *** Requirements *** ; *** Requirements ***
; findchar ; findchar
; multDEBC ; multDEBC
; callIXI
; ;
; *** Defines *** ; *** Defines ***
; ;
@ -15,9 +14,6 @@
; **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
@ -42,16 +38,15 @@ _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 IX. ; out, which contains our operator row. We pop it in HL because we
; L-R numbers are parsed in HL (left) and DE (right). ; don't need our string anymore. L-R numbers are parsed, and in DE and
pop ix ; <-- lvl 1 ; IX.
pop hl ; <-- lvl 1
ret nz ret nz
; Resolving left and right succeeded, proceed! ; Resolving left and right succeeded, proceed!
inc ix ; point to routine pointer inc hl ; point to routine pointer
call callIXI call intoHL
push de \ pop ix jp (hl)
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
@ -95,7 +90,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
; HL (left) and DE (right) ; DE (left) and IX (right)
_resolveLeftAndRight: _resolveLeftAndRight:
call parseExpr call parseExpr
ret nz ; return immediately if error ret nz ; return immediately if error
@ -103,14 +98,12 @@ _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 ; --> lvl 1 push ix
call parseExpr pop de ; numeric left expr result in DE
pop hl ; <-- lvl 1. left jp parseExpr
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 DE. ; 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 ; The table has 3 bytes per row: 1 byte for operator and 2 bytes for routine
; pointer. ; pointer.
exprTbl: exprTbl:
@ -120,104 +113,27 @@ 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 hl, de add ix, de
ex de, hl cp a ; ensure Z
ret ret
.minus: .minus:
or a ; clear carry push ix
sbc hl, de pop hl
ex de, hl ex de, hl
scf \ ccf
sbc hl, de
push hl
pop ix
cp a ; ensure Z
ret ret
.mult: .mult:
ld b, h push ix \ pop bc
ld c, l call multDEBC
call multDEBC ; --> HL push hl \ pop ix
ex de, hl cp a ; ensure Z
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.

View File

@ -42,9 +42,9 @@ sFOO: .db "FOO", 0
sBAR: .db "BAR", 0 sBAR: .db "BAR", 0
test: test:
ld sp, 0xffff ld hl, 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,65 +128,10 @@ 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