diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2021-02-21 22:45:45 -0800 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2021-02-21 22:49:39 -0800 |
commit | 588d6df6511cc489191d5f63ce15bd40532b96c0 (patch) | |
tree | 4b1eb86949e8dfe82182d023faa3730f366a70ea /baremetal/shell/read.mu | |
parent | e3f7765cb791c45513c67aadc0abc4865831b1c5 (diff) | |
download | mu-588d6df6511cc489191d5f63ce15bd40532b96c0.tar.gz |
7781 - baremetal/shell: tokenize numbers
We've now reached a point where we need to start thinking of error handling, and tests for error handling. The top-level has `stop`, but that's really just for working with Unix's exit(). Here we have the opportunity to bake errors into the trace. Which might also be a good opportunity for fleshing out the UX for the trace.
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 |