mirror of
https://github.com/hsoft/collapseos.git
synced 2024-11-27 22:08:05 +11:00
basic: add variables
Things are getting cereal...
This commit is contained in:
parent
9c9484fb88
commit
9d6cbe577c
@ -14,10 +14,12 @@
|
|||||||
.inc "lib/ari.asm"
|
.inc "lib/ari.asm"
|
||||||
.inc "lib/parse.asm"
|
.inc "lib/parse.asm"
|
||||||
.inc "lib/fmt.asm"
|
.inc "lib/fmt.asm"
|
||||||
.equ EXPR_PARSE parseLiteral
|
.equ EXPR_PARSE parseLiteralOrVar
|
||||||
.inc "lib/expr.asm"
|
.inc "lib/expr.asm"
|
||||||
.inc "basic/tok.asm"
|
.inc "basic/tok.asm"
|
||||||
.equ BUF_RAMSTART USER_RAMSTART
|
.equ VAR_RAMSTART USER_RAMSTART
|
||||||
|
.inc "basic/var.asm"
|
||||||
|
.equ BUF_RAMSTART VAR_RAMEND
|
||||||
.inc "basic/buf.asm"
|
.inc "basic/buf.asm"
|
||||||
.equ BAS_RAMSTART BUF_RAMEND
|
.equ BAS_RAMSTART BUF_RAMEND
|
||||||
.inc "basic/main.asm"
|
.inc "basic/main.asm"
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
; *** Code ***
|
; *** Code ***
|
||||||
basStart:
|
basStart:
|
||||||
ld (BAS_INITSP), sp
|
ld (BAS_INITSP), sp
|
||||||
|
call varInit
|
||||||
call bufInit
|
call bufInit
|
||||||
xor a
|
xor a
|
||||||
ld hl, .welcome
|
ld hl, .welcome
|
||||||
@ -51,8 +52,20 @@ basLoop:
|
|||||||
; If found, jump to it. If not found, unset Z. We expect commands to set Z
|
; If found, jump to it. If not found, unset Z. We expect commands to set Z
|
||||||
; on success. Therefore, when calling basCallCmd results in NZ, we're not sure
|
; on success. Therefore, when calling basCallCmd results in NZ, we're not sure
|
||||||
; where the error come from, but well...
|
; where the error come from, but well...
|
||||||
|
; Before being evaluated, (HL) is copied in BAS_SCRATCHPAD because some
|
||||||
|
; evaluation routines (such as parseExpr) mutate the string it evaluates.
|
||||||
|
; TODO: straighten this situation up. Mutating a string like this breaks
|
||||||
|
; expectations.
|
||||||
basCallCmd:
|
basCallCmd:
|
||||||
; First, get cmd length
|
push de ; --> lvl 1
|
||||||
|
ld de, BAS_SCRATCHPAD
|
||||||
|
call strcpy
|
||||||
|
ex de, hl ; HL now points to scratchpad
|
||||||
|
pop de ; <-- lvl 1
|
||||||
|
; let's see if it's a variable assignment.
|
||||||
|
call varTryAssign
|
||||||
|
ret z ; Done!
|
||||||
|
; Second, get cmd length
|
||||||
call fnWSIdx
|
call fnWSIdx
|
||||||
cp 7
|
cp 7
|
||||||
jp nc, unsetZ ; Too long, can't possibly fit anything.
|
jp nc, unsetZ ; Too long, can't possibly fit anything.
|
||||||
|
97
apps/basic/var.asm
Normal file
97
apps/basic/var.asm
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
; *** Variables ***
|
||||||
|
; A list of words for each member of the A-Z range.
|
||||||
|
.equ VAR_TBL VAR_RAMSTART
|
||||||
|
.equ VAR_RAMEND @+52
|
||||||
|
|
||||||
|
; *** Code ***
|
||||||
|
|
||||||
|
varInit:
|
||||||
|
ld b, VAR_RAMEND-VAR_RAMSTART
|
||||||
|
ld hl, VAR_RAMSTART
|
||||||
|
xor a
|
||||||
|
.loop:
|
||||||
|
ld (hl), a
|
||||||
|
inc hl
|
||||||
|
djnz .loop
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Check if A is a valid variable letter (a-z or A-Z). If it is, set A to a
|
||||||
|
; valid VAR_TBL index and set Z. Otherwise, unset Z (and A is destroyed)
|
||||||
|
varChk:
|
||||||
|
call upcase
|
||||||
|
sub 'A'
|
||||||
|
ret c ; Z unset
|
||||||
|
cp 27 ; 'Z' + 1
|
||||||
|
jr c, .isVar
|
||||||
|
; A > 'Z'
|
||||||
|
dec a ; unset Z
|
||||||
|
ret
|
||||||
|
.isVar:
|
||||||
|
cp a ; set Z
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Try to interpret line at (HL) and see if it's a variable assignment. If it
|
||||||
|
; is, proceed with the assignment and set Z. Otherwise, NZ.
|
||||||
|
varTryAssign:
|
||||||
|
inc hl
|
||||||
|
ld a, (hl)
|
||||||
|
dec hl
|
||||||
|
cp '='
|
||||||
|
ret nz
|
||||||
|
ld a, (hl)
|
||||||
|
call varChk
|
||||||
|
ret nz
|
||||||
|
; We have a variable! Its table index is currently in A.
|
||||||
|
push ix ; --> lvl 1
|
||||||
|
push hl ; --> lvl 2
|
||||||
|
push af ; --> lvl 3. save for later
|
||||||
|
; Let's start by evaluating that expression
|
||||||
|
inc hl \ inc hl
|
||||||
|
call parseExpr ; --> number in IX
|
||||||
|
jr nz, .exprErr
|
||||||
|
pop af ; <-- lvl 3
|
||||||
|
add a, a ; * 2 because each element is a word
|
||||||
|
ld hl, VAR_TBL
|
||||||
|
call addHL
|
||||||
|
; HL placed, write number
|
||||||
|
push de ; --> lvl 3
|
||||||
|
push ix \ pop de
|
||||||
|
ld (hl), e
|
||||||
|
inc hl
|
||||||
|
ld (hl), d
|
||||||
|
pop de ; <-- lvl 3
|
||||||
|
xor a ; ensure Z
|
||||||
|
.end:
|
||||||
|
pop hl ; <-- lvl 2
|
||||||
|
pop ix ; <-- lvl 1
|
||||||
|
ret
|
||||||
|
.exprErr:
|
||||||
|
pop af ; <-- lvl 3
|
||||||
|
jr .end
|
||||||
|
|
||||||
|
; Check if value at (HL) is a variable. If yes, returns its associated value.
|
||||||
|
; Otherwise, jump to parseLiteral.
|
||||||
|
parseLiteralOrVar:
|
||||||
|
inc hl
|
||||||
|
ld a, (hl)
|
||||||
|
dec hl
|
||||||
|
or a
|
||||||
|
; if more than one in length, it can't be a variable
|
||||||
|
jp nz, parseLiteral
|
||||||
|
ld a, (hl)
|
||||||
|
call varChk
|
||||||
|
jp nz, parseLiteral
|
||||||
|
; It's a variable, resolve!
|
||||||
|
add a, a ; * 2 because each element is a word
|
||||||
|
push hl ; --> lvl 1
|
||||||
|
ld hl, VAR_TBL
|
||||||
|
call addHL
|
||||||
|
push de ; --> lvl 2
|
||||||
|
ld e, (hl)
|
||||||
|
inc hl
|
||||||
|
ld d, (hl)
|
||||||
|
push de \ pop ix
|
||||||
|
pop de ; <-- lvl 2
|
||||||
|
pop hl ; <-- lvl 1
|
||||||
|
cp a ; ensure Z
|
||||||
|
ret
|
Loading…
Reference in New Issue
Block a user