mirror of
https://github.com/hsoft/collapseos.git
synced 2024-11-23 22:48:05 +11:00
basic: allow multiple commands on the same line
This commit is contained in:
parent
5d33d165a2
commit
51c977f2ed
@ -88,13 +88,22 @@ etc.) always to so in variable `A`.
|
|||||||
Another is that whenever a number is expected, expressions, including the ones
|
Another is that whenever a number is expected, expressions, including the ones
|
||||||
with variables in it, work fine.
|
with variables in it, work fine.
|
||||||
|
|
||||||
|
### One-liners
|
||||||
|
|
||||||
|
The `:` character, when not inside a `""` literal, allows you to cram more than
|
||||||
|
one instruction on the same line.
|
||||||
|
|
||||||
|
Things are special with `if`. All commands following a `if` are bound to that
|
||||||
|
`if`'s condition. `if 0 foo:bar` doesn't execute `bar`.
|
||||||
|
|
||||||
|
Another special thing is `goto`. A `goto` followed by `:` will have the commands
|
||||||
|
following the `:` before the goto occurs.
|
||||||
|
|
||||||
### Commands
|
### Commands
|
||||||
|
|
||||||
There are two types of commands: normal and direct-only. The latter can only
|
There are two types of commands: normal and direct-only. The latter can only
|
||||||
be invoked in direct mode, not through a code listing.
|
be invoked in direct mode, not through a code listing.
|
||||||
|
|
||||||
`bye`: Direct-only. Quits BASIC
|
|
||||||
|
|
||||||
`list`: Direct-only. Prints all lines in the code listing, prefixing them
|
`list`: Direct-only. Prints all lines in the code listing, prefixing them
|
||||||
with their associated line number.
|
with their associated line number.
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ basLDBAS:
|
|||||||
call parseDecimal
|
call parseDecimal
|
||||||
jr nz, .notANumber
|
jr nz, .notANumber
|
||||||
push ix \ pop de
|
push ix \ pop de
|
||||||
call toSep
|
call toSepOrEnd
|
||||||
call rdSep
|
call rdSep
|
||||||
call bufAdd
|
call bufAdd
|
||||||
pop hl ; <-- lvl 1
|
pop hl ; <-- lvl 1
|
||||||
|
@ -41,14 +41,14 @@ basLoop:
|
|||||||
call parseDecimal
|
call parseDecimal
|
||||||
jr z, .number
|
jr z, .number
|
||||||
ld de, basCmds1
|
ld de, basCmds1
|
||||||
call basCallCmd
|
call basCallCmds
|
||||||
jr z, basLoop
|
jr z, basLoop
|
||||||
; Error
|
; Error
|
||||||
call basERR
|
call basERR
|
||||||
jr basLoop
|
jr basLoop
|
||||||
.number:
|
.number:
|
||||||
push ix \ pop de
|
push ix \ pop de
|
||||||
call toSep
|
call toSepOrEnd
|
||||||
call rdSep
|
call rdSep
|
||||||
call bufAdd
|
call bufAdd
|
||||||
jp nz, basERR
|
jp nz, basERR
|
||||||
@ -110,6 +110,27 @@ basCallCmd:
|
|||||||
call rdSep
|
call rdSep
|
||||||
jp (ix)
|
jp (ix)
|
||||||
|
|
||||||
|
; Call a series of ':'-separated commands in (HL) using cmd table in (DE).
|
||||||
|
; Stop processing as soon as one command unsets Z.
|
||||||
|
basCallCmds:
|
||||||
|
; Commands are not guaranteed at all to preserve HL and DE, so we
|
||||||
|
; preserve them ourselves here.
|
||||||
|
push hl ; --> lvl 1
|
||||||
|
push de ; --> lvl 2
|
||||||
|
call basCallCmd
|
||||||
|
pop de ; <-- lvl 2
|
||||||
|
pop hl ; <-- lvl 1
|
||||||
|
ret nz
|
||||||
|
call toEnd
|
||||||
|
ret z ; no more cmds
|
||||||
|
; we met a ':', we have more cmds
|
||||||
|
inc hl
|
||||||
|
call basCallCmds
|
||||||
|
; move the the end of the string so that we don't run cmds following a
|
||||||
|
; ':' twice.
|
||||||
|
call strskip
|
||||||
|
ret
|
||||||
|
|
||||||
basERR:
|
basERR:
|
||||||
ld hl, .sErr
|
ld hl, .sErr
|
||||||
call printstr
|
call printstr
|
||||||
@ -154,7 +175,7 @@ basRUN:
|
|||||||
call bufStr
|
call bufStr
|
||||||
ld de, basCmds2
|
ld de, basCmds2
|
||||||
push ix ; --> lvl 1
|
push ix ; --> lvl 1
|
||||||
call basCallCmd
|
call basCallCmds
|
||||||
pop ix ; <-- lvl 1
|
pop ix ; <-- lvl 1
|
||||||
jp nz, .err
|
jp nz, .err
|
||||||
call .maybeGOTO
|
call .maybeGOTO
|
||||||
@ -258,10 +279,11 @@ basIF:
|
|||||||
ret z
|
ret z
|
||||||
; expr is true, execute next
|
; expr is true, execute next
|
||||||
; (HL) back to beginning of args, skip to next arg
|
; (HL) back to beginning of args, skip to next arg
|
||||||
call toSep
|
call toSepOrEnd
|
||||||
call rdSep
|
call rdSep
|
||||||
|
ret nz
|
||||||
ld de, basCmds2
|
ld de, basCmds2
|
||||||
jp basCallCmd
|
jp basCallCmds
|
||||||
|
|
||||||
basINPUT:
|
basINPUT:
|
||||||
; If our first arg is a string literal, spit it
|
; If our first arg is a string literal, spit it
|
||||||
|
@ -1,10 +1,16 @@
|
|||||||
; Sets Z is A is ' ' or '\t' (whitespace), or ',' (arg sep)
|
; Whether A is a separator or end-of-string (null or ':')
|
||||||
|
isSepOrEnd:
|
||||||
|
or a
|
||||||
|
ret z
|
||||||
|
cp ':'
|
||||||
|
ret z
|
||||||
|
; continue to isSep
|
||||||
|
|
||||||
|
; Sets Z is A is ' ' or '\t' (whitespace)
|
||||||
isSep:
|
isSep:
|
||||||
cp ' '
|
cp ' '
|
||||||
ret z
|
ret z
|
||||||
cp 0x09
|
cp 0x09
|
||||||
ret z
|
|
||||||
cp ','
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; Expect at least one whitespace (0x20, 0x09) at (HL), and then advance HL
|
; Expect at least one whitespace (0x20, 0x09) at (HL), and then advance HL
|
||||||
@ -23,8 +29,8 @@ rdSep:
|
|||||||
ld a, (hl)
|
ld a, (hl)
|
||||||
call isSep
|
call isSep
|
||||||
jr z, .loop
|
jr z, .loop
|
||||||
or a ; cp 0
|
call isSepOrEnd
|
||||||
jp z, .fail
|
jp z, .fail ; unexpected EOL. fail
|
||||||
cp a ; ensure Z
|
cp a ; ensure Z
|
||||||
ret
|
ret
|
||||||
.fail:
|
.fail:
|
||||||
@ -33,12 +39,27 @@ rdSep:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
; Advance HL to the next separator or to the end of string.
|
; Advance HL to the next separator or to the end of string.
|
||||||
toSep:
|
toSepOrEnd:
|
||||||
ld a, (hl)
|
ld a, (hl)
|
||||||
call isSep
|
call isSepOrEnd
|
||||||
ret z
|
ret z
|
||||||
inc hl
|
inc hl
|
||||||
jr toSep
|
jr toSepOrEnd
|
||||||
|
|
||||||
|
; Advance HL to the end of the line, that is, either a null terminating char
|
||||||
|
; or the ':'.
|
||||||
|
; Sets Z if we met a null char, unset if we met a ':'
|
||||||
|
toEnd:
|
||||||
|
ld a, (hl)
|
||||||
|
or a
|
||||||
|
ret z
|
||||||
|
cp ':'
|
||||||
|
jr z, .havesep
|
||||||
|
inc hl
|
||||||
|
jr toEnd
|
||||||
|
.havesep:
|
||||||
|
inc a ; unset Z
|
||||||
|
ret
|
||||||
|
|
||||||
; Read (HL) until the next separator and copy it in (DE)
|
; Read (HL) until the next separator and copy it in (DE)
|
||||||
; DE is preserved, but HL is advanced to the end of the read word.
|
; DE is preserved, but HL is advanced to the end of the read word.
|
||||||
@ -47,9 +68,7 @@ rdWord:
|
|||||||
push de
|
push de
|
||||||
.loop:
|
.loop:
|
||||||
ld a, (hl)
|
ld a, (hl)
|
||||||
call isSep
|
call isSepOrEnd
|
||||||
jr z, .stop
|
|
||||||
or a
|
|
||||||
jr z, .stop
|
jr z, .stop
|
||||||
ld (de), a
|
ld (de), a
|
||||||
inc hl
|
inc hl
|
||||||
|
Loading…
Reference in New Issue
Block a user