parse dotted lists
This commit is contained in:
parent
2e06991834
commit
613b1d5734
|
@ -57,6 +57,14 @@ fn parse-sexpression tokens: (addr stream cell), _out: (addr handle cell), trace
|
|||
close-paren?, dot? <- parse-sexpression tokens, right-ah, trace
|
||||
return close-paren?, dot?
|
||||
}
|
||||
# dot -> return
|
||||
var dot?/eax: boolean <- dot-token? curr-token
|
||||
compare dot?, 0/false
|
||||
{
|
||||
break-if-=
|
||||
trace-higher trace
|
||||
return 0/false, 1/true
|
||||
}
|
||||
# not bracket -> parse atom
|
||||
var bracket-token?/eax: boolean <- bracket-token? curr-token
|
||||
compare bracket-token?, 0/false
|
||||
|
@ -78,6 +86,12 @@ fn parse-sexpression tokens: (addr stream cell), _out: (addr handle cell), trace
|
|||
var close-paren?/eax: boolean <- copy 0/false
|
||||
var dot?/ecx: boolean <- copy 0/false
|
||||
close-paren?, dot? <- parse-sexpression tokens, left, trace
|
||||
{
|
||||
compare dot?, 0/false
|
||||
break-if-=
|
||||
error trace, "'.' cannot be at the start of a list"
|
||||
return 1/true, dot?
|
||||
}
|
||||
compare close-paren?, 0/false
|
||||
break-if-!=
|
||||
var curr-addr/eax: (addr cell) <- lookup *curr
|
||||
|
@ -88,6 +102,13 @@ fn parse-sexpression tokens: (addr stream cell), _out: (addr handle cell), trace
|
|||
var close-paren?/eax: boolean <- copy 0/false
|
||||
var dot?/ecx: boolean <- copy 0/false
|
||||
close-paren?, dot? <- parse-sexpression tokens, tmp, trace
|
||||
# '.' -> clean up right here and return
|
||||
compare dot?, 0/false
|
||||
{
|
||||
break-if-=
|
||||
parse-dot-tail tokens, curr, trace
|
||||
return 0/false, 0/false
|
||||
}
|
||||
allocate-pair curr
|
||||
# ')' -> return
|
||||
compare close-paren?, 0/false
|
||||
|
@ -170,3 +191,38 @@ fn parse-atom _curr-token: (addr cell), _out: (addr handle cell), trace: (addr t
|
|||
trace trace, "read", stream
|
||||
}
|
||||
}
|
||||
|
||||
fn parse-dot-tail tokens: (addr stream cell), _out: (addr handle cell), trace: (addr trace) {
|
||||
var out/edi: (addr handle cell) <- copy _out
|
||||
var close-paren?/eax: boolean <- copy 0/false
|
||||
var dot?/ecx: boolean <- copy 0/false
|
||||
close-paren?, dot? <- parse-sexpression tokens, out, trace
|
||||
compare close-paren?, 0/false
|
||||
{
|
||||
break-if-=
|
||||
error trace, "'. )' makes no sense"
|
||||
return
|
||||
}
|
||||
compare dot?, 0/false
|
||||
{
|
||||
break-if-=
|
||||
error trace, "'. .' makes no sense"
|
||||
return
|
||||
}
|
||||
#
|
||||
var dummy: (handle cell)
|
||||
var dummy-ah/edi: (addr handle cell) <- address dummy
|
||||
close-paren?, dot? <- parse-sexpression tokens, dummy-ah, trace
|
||||
compare close-paren?, 0/false
|
||||
{
|
||||
break-if-!=
|
||||
error trace, "cannot have multiple expressions between '.' and ')'"
|
||||
return
|
||||
}
|
||||
compare dot?, 0/false
|
||||
{
|
||||
break-if-=
|
||||
error trace, "cannot have two dots in a single list"
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
135
shell/sandbox.mu
135
shell/sandbox.mu
|
@ -719,6 +719,141 @@ fn test-run-quote {
|
|||
check-screen-row screen, 2/y, "=> a ", "F - test-run-quote/2"
|
||||
}
|
||||
|
||||
fn test-run-dotted-list {
|
||||
var sandbox-storage: sandbox
|
||||
var sandbox/esi: (addr sandbox) <- address sandbox-storage
|
||||
initialize-sandbox sandbox, 0/no-screen-or-keyboard
|
||||
# type "'(a . b)"
|
||||
edit-sandbox sandbox, 0x27/quote, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x28/open-paren, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x61/a, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x20/space, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x2e/dot, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x20/space, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x62/b, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x29/close-paren, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
# eval
|
||||
edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
# setup: screen
|
||||
var screen-on-stack: screen
|
||||
var screen/edi: (addr screen) <- address screen-on-stack
|
||||
initialize-screen screen, 0x80/width, 0x10/height
|
||||
#
|
||||
render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 0/no-globals
|
||||
check-screen-row screen, 0/y, "'(a . b) ", "F - test-run-dotted-list/0"
|
||||
check-screen-row screen, 1/y, "... ", "F - test-run-dotted-list/1"
|
||||
check-screen-row screen, 2/y, "=> (a . b) ", "F - test-run-dotted-list/2"
|
||||
}
|
||||
|
||||
fn test-run-dot-and-list {
|
||||
var sandbox-storage: sandbox
|
||||
var sandbox/esi: (addr sandbox) <- address sandbox-storage
|
||||
initialize-sandbox sandbox, 0/no-screen-or-keyboard
|
||||
# type "'(a . (b))"
|
||||
edit-sandbox sandbox, 0x27/quote, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x28/open-paren, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x61/a, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x20/space, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x2e/dot, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x20/space, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x28/open-paren, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x62/b, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x29/close-paren, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x29/close-paren, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
# eval
|
||||
edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
# setup: screen
|
||||
var screen-on-stack: screen
|
||||
var screen/edi: (addr screen) <- address screen-on-stack
|
||||
initialize-screen screen, 0x80/width, 0x10/height
|
||||
#
|
||||
render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 0/no-globals
|
||||
check-screen-row screen, 0/y, "'(a . (b)) ", "F - test-run-dot-and-list/0"
|
||||
check-screen-row screen, 1/y, "... ", "F - test-run-dot-and-list/1"
|
||||
check-screen-row screen, 2/y, "=> (a b) ", "F - test-run-dot-and-list/2"
|
||||
}
|
||||
|
||||
fn test-run-final-dot {
|
||||
var sandbox-storage: sandbox
|
||||
var sandbox/esi: (addr sandbox) <- address sandbox-storage
|
||||
initialize-sandbox sandbox, 0/no-screen-or-keyboard
|
||||
# type "'(a .)"
|
||||
edit-sandbox sandbox, 0x27/quote, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x28/open-paren, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x61/a, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x20/space, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x2e/dot, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x29/close-paren, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
# eval
|
||||
edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
# setup: screen
|
||||
var screen-on-stack: screen
|
||||
var screen/edi: (addr screen) <- address screen-on-stack
|
||||
initialize-screen screen, 0x80/width, 0x10/height
|
||||
#
|
||||
render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 0/no-globals
|
||||
check-screen-row screen, 0/y, "'(a .) ", "F - test-run-final-dot/0"
|
||||
check-screen-row screen, 1/y, "... ", "F - test-run-final-dot/1"
|
||||
check-screen-row screen, 2/y, "'. )' makes no sense ", "F - test-run-final-dot/2"
|
||||
# further errors may occur
|
||||
}
|
||||
|
||||
fn test-run-double-dot {
|
||||
var sandbox-storage: sandbox
|
||||
var sandbox/esi: (addr sandbox) <- address sandbox-storage
|
||||
initialize-sandbox sandbox, 0/no-screen-or-keyboard
|
||||
# type "'(a . .)"
|
||||
edit-sandbox sandbox, 0x27/quote, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x28/open-paren, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x61/a, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x20/space, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x2e/dot, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x20/space, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x2e/dot, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x29/close-paren, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
# eval
|
||||
edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
# setup: screen
|
||||
var screen-on-stack: screen
|
||||
var screen/edi: (addr screen) <- address screen-on-stack
|
||||
initialize-screen screen, 0x80/width, 0x10/height
|
||||
#
|
||||
render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 0/no-globals
|
||||
check-screen-row screen, 0/y, "'(a . .) ", "F - test-run-double-dot/0"
|
||||
check-screen-row screen, 1/y, "... ", "F - test-run-double-dot/1"
|
||||
check-screen-row screen, 2/y, "'. .' makes no sense ", "F - test-run-double-dot/2"
|
||||
# further errors may occur
|
||||
}
|
||||
|
||||
fn test-run-multiple-expressions-after-dot {
|
||||
var sandbox-storage: sandbox
|
||||
var sandbox/esi: (addr sandbox) <- address sandbox-storage
|
||||
initialize-sandbox sandbox, 0/no-screen-or-keyboard
|
||||
# type "'(a . b c)"
|
||||
edit-sandbox sandbox, 0x27/quote, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x28/open-paren, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x61/a, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x20/space, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x2e/dot, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x20/space, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x62/b, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x20/space, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x63/c, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
edit-sandbox sandbox, 0x29/close-paren, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
# eval
|
||||
edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
|
||||
# setup: screen
|
||||
var screen-on-stack: screen
|
||||
var screen/edi: (addr screen) <- address screen-on-stack
|
||||
initialize-screen screen, 0x80/width, 0x10/height
|
||||
#
|
||||
render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 0/no-globals
|
||||
check-screen-row screen, 0/y, "'(a . b c) ", "F - test-run-multiple-expressions-after-dot/0"
|
||||
check-screen-row screen, 1/y, "... ", "F - test-run-multiple-expressions-after-dot/1"
|
||||
check-screen-row screen, 2/y, "cannot have multiple expressions between '.' and ')' ", "F - test-run-multiple-expressions-after-dot/2"
|
||||
# further errors may occur
|
||||
}
|
||||
|
||||
fn test-run-error-invalid-integer {
|
||||
var sandbox-storage: sandbox
|
||||
var sandbox/esi: (addr sandbox) <- address sandbox-storage
|
||||
|
|
Loading…
Reference in New Issue