shell: support negative integer literals
We still don't support _any_ fractional literals, positive or negative.
This commit is contained in:
parent
3bdf3b1a7f
commit
8014210316
|
@ -1115,6 +1115,25 @@ fn read-from-gap-buffer _self: (addr gap-buffer) -> _/eax: grapheme {
|
||||||
return 0/nul
|
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 {
|
fn test-read-from-gap-buffer {
|
||||||
var gap-storage: gap-buffer
|
var gap-storage: gap-buffer
|
||||||
var gap/esi: (addr gap-buffer) <- address gap-storage
|
var gap/esi: (addr gap-buffer) <- address gap-storage
|
||||||
|
|
|
@ -740,6 +740,24 @@ fn test-run-integer {
|
||||||
check-screen-row screen, 3/y, " => 1 ", "F - test-run-integer/2"
|
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 {
|
fn test-run-error-invalid-integer {
|
||||||
var sandbox-storage: sandbox
|
var sandbox-storage: sandbox
|
||||||
var sandbox/esi: (addr sandbox) <- address sandbox-storage
|
var sandbox/esi: (addr sandbox) <- address sandbox-storage
|
||||||
|
|
|
@ -30,6 +30,75 @@ fn tokenize in: (addr gap-buffer), out: (addr stream cell), trace: (addr trace)
|
||||||
trace-higher 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 {
|
fn test-tokenize-quote {
|
||||||
var in-storage: gap-buffer
|
var in-storage: gap-buffer
|
||||||
var in/esi: (addr gap-buffer) <- address in-storage
|
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
|
rest-of-line in, out, trace
|
||||||
break $next-token:case
|
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
|
# digit
|
||||||
{
|
{
|
||||||
var digit?/eax: boolean <- decimal-digit? g
|
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) {
|
fn next-number-token in: (addr gap-buffer), out: (addr stream byte), trace: (addr trace) {
|
||||||
trace-text trace, "tokenize", "looking for a number"
|
trace-text trace, "tokenize", "looking for a number"
|
||||||
trace-lower trace
|
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: {
|
$next-number-token:loop: {
|
||||||
var done?/eax: boolean <- gap-buffer-scan-done? in
|
var done?/eax: boolean <- gap-buffer-scan-done? in
|
||||||
compare done?, 0/false
|
compare done?, 0/false
|
||||||
|
@ -889,9 +977,16 @@ fn operator-grapheme? g: grapheme -> _/eax: boolean {
|
||||||
fn number-token? _in: (addr cell) -> _/eax: boolean {
|
fn number-token? _in: (addr cell) -> _/eax: boolean {
|
||||||
var in/eax: (addr cell) <- copy _in
|
var in/eax: (addr cell) <- copy _in
|
||||||
var in-data-ah/eax: (addr handle stream byte) <- get in, text-data
|
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
|
rewind-stream in-data
|
||||||
var g/eax: grapheme <- read-grapheme 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
|
var result/eax: boolean <- decimal-digit? g
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user