diff options
Diffstat (limited to 'baremetal/shell/read.mu')
-rw-r--r-- | baremetal/shell/read.mu | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/baremetal/shell/read.mu b/baremetal/shell/read.mu index 81dd6f07..d6325c62 100644 --- a/baremetal/shell/read.mu +++ b/baremetal/shell/read.mu @@ -22,16 +22,109 @@ fn read-cell in: (addr gap-buffer), out: (addr handle cell) { fn next-token in: (addr gap-buffer), out: (addr stream byte) { clear-stream out skip-whitespace-from-gap-buffer in + var g/eax: grapheme <- peek-from-gap-buffer in + { + var digit?/eax: boolean <- is-decimal-digit? g + compare digit?, 0/false + break-if-= + next-number-token in, out + return + } + next-symbol-token in, out +} + +fn next-symbol-token in: (addr gap-buffer), out: (addr stream byte) { { var done?/eax: boolean <- gap-buffer-scan-done? in compare done?, 0/false break-if-!= + var g/eax: grapheme <- peek-from-gap-buffer in + # if non-symbol, return + var symbol-grapheme?/eax: boolean <- is-symbol-grapheme? g + { + compare symbol-grapheme?, 0/false + break-if-!= + return + } var g/eax: grapheme <- read-from-gap-buffer in write-grapheme out, g loop } } +fn is-symbol-grapheme? g: grapheme -> _/eax: boolean { + compare g, 0x20/space + { + break-if-!= + return 0/false + } + compare g, 0xa/newline + { + break-if-!= + return 0/false + } + compare g, 0x22/double-quote + { + break-if-!= + return 0/false + } + compare g, 0x28/open-paren + { + break-if-!= + return 0/false + } + compare g, 0x29/close-paren + { + break-if-!= + return 0/false + } + compare g, 0x5b/open-square-bracket + { + break-if-!= + return 0/false + } + compare g, 0x5d/close-square-bracket + { + break-if-!= + return 0/false + } + compare g, 0x7b/open-curly-bracket + { + break-if-!= + return 0/false + } + compare g, 0x7d/close-curly-bracket + { + break-if-!= + return 0/false + } + return 1/true +} + +fn next-number-token in: (addr gap-buffer), out: (addr stream byte) { + var done?/eax: boolean <- gap-buffer-scan-done? in + compare done?, 0/false + break-if-!= + var g/eax: grapheme <- peek-from-gap-buffer in + # if not symbol grapheme, return + { + var symbol-grapheme?/eax: boolean <- is-symbol-grapheme? g + compare symbol-grapheme?, 0/false + break-if-!= + return + } + # if not digit grapheme, abort + { + var digit?/eax: boolean <- is-decimal-digit? g + compare digit?, 0/false + break-if-!= + abort "invalid number" + } + var g/eax: grapheme <- read-from-gap-buffer in + write-grapheme out, g + loop +} + fn read-symbol in: (addr stream byte), _out: (addr handle cell) { var out/eax: (addr handle cell) <- copy _out new-symbol out |