From 588d6df6511cc489191d5f63ce15bd40532b96c0 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Sun, 21 Feb 2021 22:45:45 -0800 Subject: 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. --- baremetal/shell/read.mu | 93 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) (limited to 'baremetal/shell') 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 -- cgit 1.4.1-2-gfad0