shell: support negative integer literals

We still don't support _any_ fractional literals, positive or negative.
This commit is contained in:
Kartik K. Agaram 2021-06-06 12:39:03 -07:00
parent 3bdf3b1a7f
commit 8014210316
3 changed files with 133 additions and 1 deletions

View File

@ -1115,6 +1115,25 @@ fn read-from-gap-buffer _self: (addr gap-buffer) -> _/eax: grapheme {
return 0/nul
}
fn put-back-from-gap-buffer _self: (addr gap-buffer) {
var self/esi: (addr gap-buffer) <- copy _self
# more in right?
var right/eax: (addr grapheme-stack) <- get self, right
var right-size/eax: int <- grapheme-stack-length right
var right-read-index-a/eax: (addr int) <- get self, right-read-index
compare *right-read-index-a, 0
{
break-if-<=
decrement *right-read-index-a
return
}
# more in left?
var left/eax: (addr grapheme-stack) <- get self, left
var left-size/eax: int <- grapheme-stack-length left
var left-read-index-a/eax: (addr int) <- get self, left-read-index
decrement *left-read-index-a
}
fn test-read-from-gap-buffer {
var gap-storage: gap-buffer
var gap/esi: (addr gap-buffer) <- address gap-storage

View File

@ -740,6 +740,24 @@ fn test-run-integer {
check-screen-row screen, 3/y, " => 1 ", "F - test-run-integer/2"
}
fn test-run-negative-integer {
var sandbox-storage: sandbox
var sandbox/esi: (addr sandbox) <- address sandbox-storage
initialize-sandbox-with sandbox, "-1"
# eval
edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk, 0/no-tweak-screen
# setup: screen
var screen-on-stack: screen
var screen/edi: (addr screen) <- address screen-on-stack
initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics
#
render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor
# skip one line of padding
check-screen-row screen, 1/y, " -1 ", "F - test-run-negative-integer/0"
check-screen-row screen, 2/y, " ... ", "F - test-run-negative-integer/1"
check-screen-row screen, 3/y, " => -1 ", "F - test-run-negative-integer/2"
}
fn test-run-error-invalid-integer {
var sandbox-storage: sandbox
var sandbox/esi: (addr sandbox) <- address sandbox-storage

View File

@ -30,6 +30,75 @@ fn tokenize in: (addr gap-buffer), out: (addr stream cell), trace: (addr trace)
trace-higher trace
}
fn test-tokenize-number {
var in-storage: gap-buffer
var in/esi: (addr gap-buffer) <- address in-storage
initialize-gap-buffer-with in, "123 a"
#
var stream-storage: (stream cell 0x10)
var stream/edi: (addr stream cell) <- address stream-storage
#
var trace-storage: trace
var trace/edx: (addr trace) <- address trace-storage
initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible
tokenize in, stream, trace
#
var curr-token-storage: cell
var curr-token/ebx: (addr cell) <- address curr-token-storage
read-from-stream stream, curr-token
var number?/eax: boolean <- number-token? curr-token
check number?, "F - test-tokenize-number"
var curr-token-data-ah/eax: (addr handle stream byte) <- get curr-token, text-data
var curr-token-data/eax: (addr stream byte) <- lookup *curr-token-data-ah
check-stream-equal curr-token-data, "123", "F - test-tokenize-number: value"
}
fn test-tokenize-negative-number {
var in-storage: gap-buffer
var in/esi: (addr gap-buffer) <- address in-storage
initialize-gap-buffer-with in, "-123 a"
#
var stream-storage: (stream cell 0x10)
var stream/edi: (addr stream cell) <- address stream-storage
#
var trace-storage: trace
var trace/edx: (addr trace) <- address trace-storage
initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible
tokenize in, stream, trace
#
var curr-token-storage: cell
var curr-token/ebx: (addr cell) <- address curr-token-storage
read-from-stream stream, curr-token
var number?/eax: boolean <- number-token? curr-token
check number?, "F - test-tokenize-negative-number"
var curr-token-data-ah/eax: (addr handle stream byte) <- get curr-token, text-data
var curr-token-data/eax: (addr stream byte) <- lookup *curr-token-data-ah
check-stream-equal curr-token-data, "-123", "F - test-tokenize-negative-number: value"
}
fn test-tokenize-number-followed-by-hyphen {
var in-storage: gap-buffer
var in/esi: (addr gap-buffer) <- address in-storage
initialize-gap-buffer-with in, "123-4 a"
#
var stream-storage: (stream cell 0x10)
var stream/edi: (addr stream cell) <- address stream-storage
#
var trace-storage: trace
var trace/edx: (addr trace) <- address trace-storage
initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible
tokenize in, stream, trace
#
var curr-token-storage: cell
var curr-token/ebx: (addr cell) <- address curr-token-storage
read-from-stream stream, curr-token
var number?/eax: boolean <- number-token? curr-token
check number?, "F - test-tokenize-number-followed-by-hyphen"
var curr-token-data-ah/eax: (addr handle stream byte) <- get curr-token, text-data
var curr-token-data/eax: (addr stream byte) <- lookup *curr-token-data-ah
check-stream-equal curr-token-data, "123", "F - test-tokenize-number-followed-by-hyphen: value"
}
fn test-tokenize-quote {
var in-storage: gap-buffer
var in/esi: (addr gap-buffer) <- address in-storage
@ -273,6 +342,19 @@ fn next-token in: (addr gap-buffer), _out-cell: (addr cell), trace: (addr trace)
rest-of-line in, out, trace
break $next-token:case
}
# special-case: '-'
{
compare g, 0x2d/minus
break-if-!=
var dummy/eax: grapheme <- read-from-gap-buffer in # skip '-'
var g2/eax: grapheme <- peek-from-gap-buffer in
put-back-from-gap-buffer in
var digit?/eax: boolean <- decimal-digit? g2
compare digit?, 0/false
break-if-=
next-number-token in, out, trace
break $next-token:case
}
# digit
{
var digit?/eax: boolean <- decimal-digit? g
@ -458,6 +540,12 @@ fn next-operator-token in: (addr gap-buffer), out: (addr stream byte), trace: (a
fn next-number-token in: (addr gap-buffer), out: (addr stream byte), trace: (addr trace) {
trace-text trace, "tokenize", "looking for a number"
trace-lower trace
$next-number-token:check-minus: {
var g/eax: grapheme <- peek-from-gap-buffer in
compare g, 0x2d/minus
g <- read-from-gap-buffer in # consume
write-grapheme out, g
}
$next-number-token:loop: {
var done?/eax: boolean <- gap-buffer-scan-done? in
compare done?, 0/false
@ -889,9 +977,16 @@ fn operator-grapheme? g: grapheme -> _/eax: boolean {
fn number-token? _in: (addr cell) -> _/eax: boolean {
var in/eax: (addr cell) <- copy _in
var in-data-ah/eax: (addr handle stream byte) <- get in, text-data
var in-data/eax: (addr stream byte) <- lookup *in-data-ah
var _in-data/eax: (addr stream byte) <- lookup *in-data-ah
var in-data/ecx: (addr stream byte) <- copy _in-data
rewind-stream in-data
var g/eax: grapheme <- read-grapheme in-data
# if '-', read another
{
compare g, 0x2d/minus
break-if-!=
g <- read-grapheme in-data
}
var result/eax: boolean <- decimal-digit? g
return result
}