diff options
Diffstat (limited to 'shell/parse.mu')
-rw-r--r-- | shell/parse.mu | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/shell/parse.mu b/shell/parse.mu new file mode 100644 index 00000000..a0045eb3 --- /dev/null +++ b/shell/parse.mu @@ -0,0 +1,136 @@ +fn parse-input tokens: (addr stream cell), out: (addr handle cell), trace: (addr trace) { + rewind-stream tokens + var empty?/eax: boolean <- stream-empty? tokens + compare empty?, 0/false + { + break-if-= + error trace, "nothing to parse" + return + } + var close-paren?/eax: boolean <- parse-sexpression tokens, out, trace + { + compare close-paren?, 0/false + break-if-= + error trace, "')' is not a valid expression" + return + } + { + var empty?/eax: boolean <- stream-empty? tokens + compare empty?, 0/false + break-if-!= + error trace, "unexpected tokens at end; only type in a single expression at a time" + } +} + +# return value: true if close-paren was encountered +fn parse-sexpression tokens: (addr stream cell), _out: (addr handle cell), trace: (addr trace) -> _/eax: boolean { + trace-text trace, "read", "parse" + trace-lower trace + var curr-token-storage: cell + var curr-token/ecx: (addr cell) <- address curr-token-storage + var empty?/eax: boolean <- stream-empty? tokens + compare empty?, 0/false + { + break-if-= + error trace, "end of stream; never found a balancing ')'" + return 1/true + } + read-from-stream tokens, curr-token + $parse-sexpression:type-check: { + # not bracket -> parse atom + var is-bracket-token?/eax: boolean <- is-bracket-token? curr-token + compare is-bracket-token?, 0/false + { + break-if-!= + parse-atom curr-token, _out, trace + break $parse-sexpression:type-check + } + # open paren -> parse list + var is-open-paren?/eax: boolean <- is-open-paren-token? curr-token + compare is-open-paren?, 0/false + { + break-if-= + var curr/esi: (addr handle cell) <- copy _out + $parse-sexpression:list-loop: { + allocate-pair curr + var curr-addr/eax: (addr cell) <- lookup *curr + var left/ecx: (addr handle cell) <- get curr-addr, left + { + var is-close-paren?/eax: boolean <- parse-sexpression tokens, left, trace + compare is-close-paren?, 0/false + break-if-!= $parse-sexpression:list-loop + } + # + curr <- get curr-addr, right + loop + } + break $parse-sexpression:type-check + } + # close paren -> parse list + var is-close-paren?/eax: boolean <- is-close-paren-token? curr-token + compare is-close-paren?, 0/false + { + break-if-= + trace-higher trace + return 1/true + } + # otherwise abort + var stream-storage: (stream byte 0x40) + var stream/edx: (addr stream byte) <- address stream-storage + write stream, "unexpected token " + 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 + rewind-stream curr-token-data + write-stream stream, curr-token-data + trace trace, "error", stream + } + trace-higher trace + return 0/false +} + +fn parse-atom _curr-token: (addr cell), _out: (addr handle cell), trace: (addr trace) { + trace-text trace, "read", "parse atom" + var curr-token/ecx: (addr cell) <- copy _curr-token + 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 + var curr-token-data/esi: (addr stream byte) <- copy _curr-token-data + trace trace, "read", curr-token-data + # number + var is-number-token?/eax: boolean <- is-number-token? curr-token + compare is-number-token?, 0/false + { + break-if-= + rewind-stream curr-token-data + var _val/eax: int <- parse-decimal-int-from-stream curr-token-data + var val/ecx: int <- copy _val + var val-float/xmm0: float <- convert val + allocate-number _out + var out/eax: (addr handle cell) <- copy _out + var out-addr/eax: (addr cell) <- lookup *out + var dest/edi: (addr float) <- get out-addr, number-data + copy-to *dest, val-float + { + var stream-storage: (stream byte 0x40) + var stream/ecx: (addr stream byte) <- address stream-storage + write stream, "=> number " + print-number out-addr, stream, 0/no-trace + trace trace, "read", stream + } + return + } + # default: symbol + # just copy token data + allocate-symbol _out + var out/eax: (addr handle cell) <- copy _out + var out-addr/eax: (addr cell) <- lookup *out + var curr-token-data-ah/ecx: (addr handle stream byte) <- get curr-token, text-data + var dest-ah/edx: (addr handle stream byte) <- get out-addr, text-data + copy-object curr-token-data-ah, dest-ah + { + var stream-storage: (stream byte 0x40) + var stream/ecx: (addr stream byte) <- address stream-storage + write stream, "=> symbol " + print-symbol out-addr, stream, 0/no-trace + trace trace, "read", stream + } +} |