1
0
mirror of https://github.com/hsoft/collapseos.git synced 2024-11-26 07:18:05 +11:00

Compare commits

..

2 Commits

Author SHA1 Message Date
Virgil Dupras
1b01f13105 lib/expr: refactor for easier operator addition 2019-11-22 14:45:12 -05:00
Virgil Dupras
fd5b2ab856 Put app-common documentation in apps/README.md 2019-11-22 14:01:16 -05:00
12 changed files with 140 additions and 77 deletions

View File

@ -61,3 +61,38 @@ relevant parts of the app's glue unit in your kernel's glue unit. This is often
simpler and more efficient. However, if your shell is a big program, it might
run into zasm's limits. In that case, you'd have to assemble your shell
separately.
## Common features
The folder `lib/` contains code shared in more than one apps and this has the
effect that some concepts are exactly the same in many application. They are
therefore sharing documentation, here.
### Number literals
There are decimal, hexadecimal and binary literals. A "straight" number is
parsed as a decimal. Hexadecimal literals must be prefixed with `0x` (`0xf4`).
Binary must be prefixed with `0b` (`0b01100110`).
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,
however.
Binary literals are also "flexible" (`0b110` is fine), but can't go over a byte.
There is also the char literal (`'X'`), that is, two quotes with a character in
the middle. The value of that character is interpreted as-is, without any
encoding involved. That is, whatever binary code is written in between those
two quotes, it's what is evaluated. Only a single byte at once can be evaluated
thus. There is no escaping. `'''` results in `0x27`. You can't express a newline
this way, it's going to mess with the parser.
### Expressions
An expression is a bunch of literals or symbols assembled by operators. For
now, only `+`, `-` and `*` operators are supported. No parenthesis yet.
Symbols have a different meaning depending on the application. In zasm, it's
labels and constants. In basic, it's variables.
Expressions can't contain spaces.

View File

@ -49,12 +49,11 @@ by typing a whitespace.
Only 16-bit integers (unsigned for now) are supported in this BASIC. When
printed, they're printed in decimal form. When expressing number literals, you
can do so either in decimal (`42`), hexadecimal (`0x2a`), binary (`0b101010`)
or char ('a', resulting in number 97).
can do so either in multiple forms. . See "Number literals" in `apps/README.md`
for details.
Expressions are accepted wherever a number is expected. For example,
`print 2+3` will print `5`. Expressions can't have whitespace inside them and
don't support (yet) parentheses. Supported operators are `+`, `-`, `*` and `/`.
`print 2+3` will print `5`. See "Expressions" in `apps/README.md`.
Inside a `if` command, "truth" expressions are accepted (`=`, `<`, `>`, `<=`,
`>=`). A thruth expression that doesn't contain a truth operator evaluates the

View File

@ -25,3 +25,20 @@ divide:
sbc a, d
ld h, a
ret
; DE * BC -> DE (high) and HL (low)
multDEBC:
ld hl, 0
ld a, 0x10
.loop:
add hl, hl
rl e
rl d
jr nc, .noinc
add hl, bc
jr nc, .noinc
inc de
.noinc:
dec a
jr nz, .loop
ret

View File

@ -23,16 +23,30 @@ parseExpr:
ret
_parseExpr:
ld a, '+'
ld de, exprTbl
.loop:
ld a, (de)
or a
jp z, EXPR_PARSE ; no operator, just parse the literal
push de ; --> lvl 1. save operator row
call _findAndSplit
jp z, _applyPlus
ld a, '-'
call _findAndSplit
jp z, _applyMinus
ld a, '*'
call _findAndSplit
jp z, _applyMult
jp EXPR_PARSE
jr z, .found
pop de ; <-- lvl 1
inc de \ inc de \ inc de
jr .loop
.found:
; Operator found, string splitted. Left in (HL), right in (DE)
call _resolveLeftAndRight
; Whether _resolveLeftAndRight was a success, we pop our lvl 1 stack
; out, which contains our operator row. We pop it in HL because we
; don't need our string anymore. L-R numbers are parsed, and in DE and
; IX.
pop hl ; <-- lvl 1
ret nz
; Resolving left and right succeeded, proceed!
inc hl ; point to routine pointer
call intoHL
jp (hl)
; 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
@ -88,20 +102,25 @@ _resolveLeftAndRight:
pop de ; numeric left expr result in DE
jp parseExpr
; Parse expr in (HL) and expr in (DE) and apply + operator to both sides.
; Put result in IX.
_applyPlus:
call _resolveLeftAndRight
ret nz
; Good! let's do the math! IX has our right part, DE has our left one.
; 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.
; The table has 3 bytes per row: 1 byte for operator and 2 bytes for routine
; pointer.
exprTbl:
.db '+'
.dw .plus
.db '-'
.dw .minus
.db '*'
.dw .mult
.db 0 ; end of table
.plus:
add ix, de
cp a ; ensure Z
ret
; Same as _applyPlus but with -
_applyMinus:
call _resolveLeftAndRight
ret nz
.minus:
push ix
pop hl
ex de, hl
@ -112,9 +131,7 @@ _applyMinus:
cp a ; ensure Z
ret
_applyMult:
call _resolveLeftAndRight
ret nz
.mult:
push ix \ pop bc
call multDEBC
push hl \ pop ix

View File

@ -73,20 +73,3 @@ strlen:
pop hl
pop bc
ret
; DE * BC -> DE (high) and HL (low)
multDEBC:
ld hl, 0
ld a, 0x10
.loop:
add hl, hl
rl e
rl d
jr nc, .noinc
add hl, bc
jr nc, .noinc
inc de
.noinc:
dec a
jr nz, .loop
ret

View File

@ -28,28 +28,13 @@ The resulting `zasm` binary takes asm code in stdin and spits binary in stdout.
## Literals
There are decimal, hexadecimal and binary literals. A "straight" number is
parsed as a decimal. Hexadecimal literals must be prefixed with `0x` (`0xf4`).
Binary must be prefixed with `0b` (`0b01100110`).
See "Number literals" in `apps/README.md`.
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,
however.
Binary literals are also "flexible" (`0b110` is fine), but can't go over a byte.
There is also the char literal (`'X'`), that is, two qutes with a character in
the middle. The value of that character is interpreted as-is, without any
encoding involved. That is, whatever binary code is written in between those
two quotes, it's what is evaluated. Only a single byte at once can be evaluated
thus. There is no escaping. `'''` results in `0x27`. You can't express a newline
this way, it's going to mess with the parser.
Then comes our last literal, the string literal. It's a chain of characters
surrounded by double quotes. Example: `"foo"`. This literal can only be used
in the `.db` directive and is equivalent to each character being single-quoted
and separated by commas (`'f', 'o', 'o'`). No null char is inserted in the
resulting value (unlike what C does).
On top of common literal logic, zasm also has string literals. It's a chain of
characters surrounded by double quotes. Example: `"foo"`. This literal can only
be used in the `.db` directive and is equivalent to each character being
single-quoted and separated by commas (`'f', 'o', 'o'`). No null char is
inserted in the resulting value (unlike what C does).
## Labels
@ -100,11 +85,7 @@ of declaration order.
## Expressions
Wherever a constant is expected, an expression can be written. An expression
is a bunch of literals or symbols assembled by operators. For now, only `+`, `-`
and `*` operators are supported. No parenthesis yet.
Expressions can't contain spaces.
See "Expressions" in `apps/README.md`.
## The Program Counter

View File

@ -66,6 +66,7 @@ jp zasmMain
.inc "core.asm"
.inc "zasm/const.asm"
.inc "lib/util.asm"
.inc "lib/ari.asm"
.inc "lib/parse.asm"
.inc "lib/args.asm"
.inc "zasm/util.asm"

View File

@ -3,6 +3,7 @@ jp test
.inc "core.asm"
.inc "str.asm"
.inc "lib/util.asm"
.inc "lib/ari.asm"
.inc "lib/parse.asm"
.equ EXPR_PARSE parseLiteral
.inc "lib/expr.asm"

View File

@ -12,6 +12,7 @@ jp test
.inc "core.asm"
.inc "str.asm"
.inc "lib/util.asm"
.inc "lib/ari.asm"
.inc "zasm/util.asm"
.inc "zasm/const.asm"
.inc "lib/parse.asm"

View File

@ -0,0 +1,35 @@
jp test
.inc "core.asm"
.inc "lib/ari.asm"
testNum: .db 1
test:
ld sp, 0xffff
ld de, 12
ld bc, 4
call multDEBC
ld a, l
cp 48
jp nz, fail
call nexttest
; success
xor a
halt
nexttest:
ld a, (testNum)
inc a
ld (testNum), a
ret
fail:
ld a, (testNum)
halt

View File

@ -12,14 +12,6 @@ test:
ld hl, 0xffff
ld sp, hl
ld de, 12
ld bc, 4
call multDEBC
ld a, l
cp 48
jp nz, fail
call nexttest
ld hl, sFoo
call strlen
cp 3

View File

@ -4,6 +4,7 @@ jp runTests
.inc "core.asm"
.inc "str.asm"
.inc "zasm/const.asm"
.inc "lib/ari.asm"
.inc "lib/util.asm"
.inc "zasm/util.asm"
.inc "lib/parse.asm"