diff options
-rw-r--r-- | shell/parse.mu | 48 | ||||
-rw-r--r-- | shell/print.mu | 30 | ||||
-rw-r--r-- | shell/tokenize.mu | 203 |
3 files changed, 255 insertions, 26 deletions
diff --git a/shell/parse.mu b/shell/parse.mu index 03e0488e..283e1d49 100644 --- a/shell/parse.mu +++ b/shell/parse.mu @@ -57,6 +57,54 @@ 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? } + # backquote quote -> parse as list with a special car + var backquote-token?/eax: boolean <- backquote-token? curr-token + compare backquote-token?, 0/false + { + break-if-= + var out/edi: (addr handle cell) <- copy _out + allocate-pair out + var out-addr/eax: (addr cell) <- lookup *out + var left-ah/edx: (addr handle cell) <- get out-addr, left + new-symbol left-ah, "`" + var right-ah/edx: (addr handle cell) <- get out-addr, right + var close-paren?/eax: boolean <- copy 0/false + var dot?/ecx: boolean <- copy 0/false + close-paren?, dot? <- parse-sexpression tokens, right-ah, trace + return close-paren?, dot? + } + # unquote -> parse as list with a special car + var unquote-token?/eax: boolean <- unquote-token? curr-token + compare unquote-token?, 0/false + { + break-if-= + var out/edi: (addr handle cell) <- copy _out + allocate-pair out + var out-addr/eax: (addr cell) <- lookup *out + var left-ah/edx: (addr handle cell) <- get out-addr, left + new-symbol left-ah, "," + var right-ah/edx: (addr handle cell) <- get out-addr, right + var close-paren?/eax: boolean <- copy 0/false + var dot?/ecx: boolean <- copy 0/false + close-paren?, dot? <- parse-sexpression tokens, right-ah, trace + return close-paren?, dot? + } + # unquote-splice -> parse as list with a special car + var unquote-splice-token?/eax: boolean <- unquote-splice-token? curr-token + compare unquote-splice-token?, 0/false + { + break-if-= + var out/edi: (addr handle cell) <- copy _out + allocate-pair out + var out-addr/eax: (addr cell) <- lookup *out + var left-ah/edx: (addr handle cell) <- get out-addr, left + new-symbol left-ah, ",@" + var right-ah/edx: (addr handle cell) <- get out-addr, right + var close-paren?/eax: boolean <- copy 0/false + var dot?/ecx: boolean <- copy 0/false + 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 diff --git a/shell/print.mu b/shell/print.mu index b1d0e158..f294449d 100644 --- a/shell/print.mu +++ b/shell/print.mu @@ -156,7 +156,8 @@ fn print-pair _in: (addr cell), out: (addr stream byte), trace: (addr trace) { # if in starts with a quote, print the quote outside the expression var in/esi: (addr cell) <- copy _in var left-ah/eax: (addr handle cell) <- get in, left - var left/eax: (addr cell) <- lookup *left-ah + var _left/eax: (addr cell) <- lookup *left-ah + var left/ecx: (addr cell) <- copy _left var is-quote?/eax: boolean <- symbol-equal? left, "'" compare is-quote?, 0/false { @@ -166,6 +167,33 @@ fn print-pair _in: (addr cell), out: (addr stream byte), trace: (addr trace) { print-cell right-ah, out, trace return } + var is-backquote?/eax: boolean <- symbol-equal? left, "`" + compare is-backquote?, 0/false + { + break-if-= + write out, "`" + var right-ah/eax: (addr handle cell) <- get in, right + print-cell right-ah, out, trace + return + } + var is-unquote?/eax: boolean <- symbol-equal? left, "," + compare is-unquote?, 0/false + { + break-if-= + write out, "," + var right-ah/eax: (addr handle cell) <- get in, right + print-cell right-ah, out, trace + return + } + var is-unquote-splice?/eax: boolean <- symbol-equal? left, ",@" + compare is-unquote-splice?, 0/false + { + break-if-= + write out, ",@" + var right-ah/eax: (addr handle cell) <- get in, right + print-cell right-ah, out, trace + return + } # var curr/esi: (addr cell) <- copy _in write out, "(" diff --git a/shell/tokenize.mu b/shell/tokenize.mu index d0e278f1..0d6fdd6e 100644 --- a/shell/tokenize.mu +++ b/shell/tokenize.mu @@ -33,6 +33,95 @@ fn tokenize in: (addr gap-buffer), out: (addr stream cell), trace: (addr trace) trace-higher trace } +fn test-tokenize-quote { + var in-storage: gap-buffer + var in/esi: (addr gap-buffer) <- address in-storage + initialize-gap-buffer-with in, "'(a)" + # + var stream-storage: (stream cell 0x10) + var stream/edi: (addr stream cell) <- address stream-storage + # + tokenize in, stream, 0/no-trace + # + var curr-token-storage: cell + var curr-token/ebx: (addr cell) <- address curr-token-storage + read-from-stream stream, curr-token + var quote?/eax: boolean <- quote-token? curr-token + check quote?, "F - test-tokenize-quote: quote" + read-from-stream stream, curr-token + var open-paren?/eax: boolean <- open-paren-token? curr-token + check open-paren?, "F - test-tokenize-quote: open paren" + read-from-stream stream, curr-token # skip a + read-from-stream stream, curr-token + var close-paren?/eax: boolean <- close-paren-token? curr-token + check close-paren?, "F - test-tokenize-quote: close paren" +} + +fn test-tokenize-backquote { + var in-storage: gap-buffer + var in/esi: (addr gap-buffer) <- address in-storage + initialize-gap-buffer-with in, "`(a)" + # + var stream-storage: (stream cell 0x10) + var stream/edi: (addr stream cell) <- address stream-storage + # + tokenize in, stream, 0/no-trace + # + var curr-token-storage: cell + var curr-token/ebx: (addr cell) <- address curr-token-storage + read-from-stream stream, curr-token + var backquote?/eax: boolean <- backquote-token? curr-token + check backquote?, "F - test-tokenize-backquote: backquote" + read-from-stream stream, curr-token + var open-paren?/eax: boolean <- open-paren-token? curr-token + check open-paren?, "F - test-tokenize-backquote: open paren" + read-from-stream stream, curr-token # skip a + read-from-stream stream, curr-token + var close-paren?/eax: boolean <- close-paren-token? curr-token + check close-paren?, "F - test-tokenize-backquote: close paren" +} + +fn test-tokenize-unquote { + var in-storage: gap-buffer + var in/esi: (addr gap-buffer) <- address in-storage + initialize-gap-buffer-with in, ",(a)" + # + var stream-storage: (stream cell 0x10) + var stream/edi: (addr stream cell) <- address stream-storage + # + tokenize in, stream, 0/no-trace + # + var curr-token-storage: cell + var curr-token/ebx: (addr cell) <- address curr-token-storage + read-from-stream stream, curr-token + var unquote?/eax: boolean <- unquote-token? curr-token + check unquote?, "F - test-tokenize-unquote: unquote" + read-from-stream stream, curr-token + var open-paren?/eax: boolean <- open-paren-token? curr-token + check open-paren?, "F - test-tokenize-unquote: open paren" + read-from-stream stream, curr-token # skip a + read-from-stream stream, curr-token + var close-paren?/eax: boolean <- close-paren-token? curr-token + check close-paren?, "F - test-tokenize-unquote: close paren" +} + +fn test-tokenize-unquote-splice { + var in-storage: gap-buffer + var in/esi: (addr gap-buffer) <- address in-storage + initialize-gap-buffer-with in, ",@a" + # + var stream-storage: (stream cell 0x10) + var stream/edi: (addr stream cell) <- address stream-storage + # + tokenize in, stream, 0/no-trace + # + var curr-token-storage: cell + var curr-token/ebx: (addr cell) <- address curr-token-storage + read-from-stream stream, curr-token + var unquote-splice?/eax: boolean <- unquote-splice-token? curr-token + check unquote-splice?, "F - test-tokenize-unquote-splice: unquote-splice" +} + fn test-tokenize-dotted-list { var in-storage: gap-buffer var in/esi: (addr gap-buffer) <- address in-storage @@ -190,6 +279,38 @@ fn next-token in: (addr gap-buffer), _out-cell: (addr cell), trace: (addr trace) next-operator-token in, out, trace break $next-token:body } + # quote + { + compare g, 0x27/single-quote + break-if-!= + g <- read-from-gap-buffer in # consume + write-grapheme out, g + break $next-token:body + } + # backquote + { + compare g, 0x60/single-quote + break-if-!= + g <- read-from-gap-buffer in # consume + write-grapheme out, g + break $next-token:body + } + # unquote + { + compare g, 0x2c/comma + break-if-!= + g <- read-from-gap-buffer in # consume + write-grapheme out, g + # check for unquote-splice + { + var g2/eax: grapheme <- peek-from-gap-buffer in + compare g2, 0x40/at-sign + break-if-!= + g2 <- read-from-gap-buffer in + write-grapheme out, g2 + } + break $next-token:body + } } trace-higher trace var stream-storage: (stream byte 0x40) @@ -454,17 +575,27 @@ fn symbol-grapheme? g: grapheme -> _/eax: boolean { break-if-!= return 0/false } - compare g, 0x2a/asterisk + compare g, 0x60/backquote { break-if-!= return 0/false } - compare g, 0x2b/plus + compare g, 0x2c/comma { break-if-!= return 0/false } - compare g, 0x2c/comma + compare g, 0x40/at-sign + { + break-if-!= + return 0/false + } + compare g, 0x2a/asterisk + { + break-if-!= + return 0/false + } + compare g, 0x2b/plus { break-if-!= return 0/false @@ -510,11 +641,6 @@ fn symbol-grapheme? g: grapheme -> _/eax: boolean { return 0/false } # '?' is a symbol char - compare g, 0x40/at-sign - { - break-if-!= - return 0/false - } compare g, 0x5c/backslash { break-if-!= @@ -588,19 +714,29 @@ fn operator-grapheme? g: grapheme -> _/eax: boolean { compare g, 0x27/single-quote { break-if-!= - return 1/true + return 0/true } - compare g, 0x2a/asterisk + compare g, 0x60/backquote { break-if-!= - return 1/true + return 0/false } - compare g, 0x2b/plus + compare g, 0x2c/comma + { + break-if-!= + return 0/false + } + compare g, 0x40/at-sign + { + break-if-!= + return 0/false + } + compare g, 0x2a/asterisk { break-if-!= return 1/true } - compare g, 0x2c/comma + compare g, 0x2b/plus { break-if-!= return 1/true @@ -646,11 +782,6 @@ fn operator-grapheme? g: grapheme -> _/eax: boolean { return 1/true } # '?' is a symbol char - compare g, 0x40/at-sign - { - break-if-!= - return 1/true - } compare g, 0x5c/backslash { break-if-!= @@ -707,13 +838,35 @@ fn quote-token? _in: (addr cell) -> _/eax: boolean { var in-data-ah/eax: (addr handle stream byte) <- get in, text-data var in-data/eax: (addr stream byte) <- lookup *in-data-ah rewind-stream in-data - var g/eax: grapheme <- read-grapheme in-data - compare g, 0x27/single-quote - { - break-if-!= - return 1/true - } - return 0/false + var result/eax: boolean <- stream-data-equal? in-data, "'" + return result +} + +fn backquote-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 + rewind-stream in-data + var result/eax: boolean <- stream-data-equal? in-data, "`" + return result +} + +fn unquote-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 + rewind-stream in-data + var result/eax: boolean <- stream-data-equal? in-data, "," + return result +} + +fn unquote-splice-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 + rewind-stream in-data + var result/eax: boolean <- stream-data-equal? in-data, ",@" + return result } fn open-paren-token? _in: (addr cell) -> _/eax: boolean { |