about summary refs log tree commit diff stats
path: root/baremetal/shell
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2021-02-27 07:21:29 -0800
committerKartik K. Agaram <vc@akkartik.com>2021-02-27 07:21:29 -0800
commit03178cde6fd47f4eebb49852199681355bff5a14 (patch)
treeb72acc9b3258b4641e60d5b932d6c861ca975512 /baremetal/shell
parenta9e0cb7cc9da462c6e7886edfb554d7266e84c18 (diff)
downloadmu-03178cde6fd47f4eebb49852199681355bff5a14.tar.gz
7818 - baremetal/shell: parse numbers
Diffstat (limited to 'baremetal/shell')
-rw-r--r--baremetal/shell/cell.mu8
-rw-r--r--baremetal/shell/parse.mu44
-rw-r--r--baremetal/shell/print.mu12
-rw-r--r--baremetal/shell/tokenize.mu14
4 files changed, 71 insertions, 7 deletions
diff --git a/baremetal/shell/cell.mu b/baremetal/shell/cell.mu
index fe1dd6b6..2e1beb0e 100644
--- a/baremetal/shell/cell.mu
+++ b/baremetal/shell/cell.mu
@@ -20,3 +20,11 @@ fn new-symbol _out: (addr handle cell) {
   var dest-ah/eax: (addr handle stream byte) <- get out-addr, text-data
   populate-stream dest-ah, 0x40/max-symbol-size
 }
+
+fn new-number _out: (addr handle cell) {
+  var out/eax: (addr handle cell) <- copy _out
+  allocate out
+  var out-addr/eax: (addr cell) <- lookup *out
+  var type/ecx: (addr int) <- get out-addr, type
+  copy-to *type, 1/number
+}
diff --git a/baremetal/shell/parse.mu b/baremetal/shell/parse.mu
index 918fb108..f55adf6d 100644
--- a/baremetal/shell/parse.mu
+++ b/baremetal/shell/parse.mu
@@ -1,9 +1,39 @@
 fn parse-sexpression tokens: (addr stream cell), _out: (addr handle cell), trace: (addr trace) {
-  # For now we just convert first token into a symbol and return it. TODO
-  var out/eax: (addr handle cell) <- copy _out
-  allocate out
-  var out-addr/eax: (addr cell) <- lookup *out
-  read-from-stream tokens, out-addr
-  var type/ecx: (addr int) <- get out-addr, type
-  copy-to *type, 2/symbol
+  rewind-stream tokens
+  var curr-token-storage: cell
+  var curr-token/ecx: (addr cell) <- address curr-token-storage
+  {
+    var done?/eax: boolean <- stream-empty? tokens
+    compare done?, 0/false
+    break-if-!=
+    read-from-stream tokens, 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
+    # 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
+      new-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
+      return
+    }
+    # Temporary default: just convert first token to symbol and return it.
+    var out/eax: (addr handle cell) <- copy _out
+    allocate out
+    var out-addr/eax: (addr cell) <- lookup *out
+    copy-object curr-token, out-addr
+    var type/ecx: (addr int) <- get out-addr, type
+    copy-to *type, 2/symbol
+    return
+  }
+  abort "unexpected tokens at end; only type in a single expression at a time"
 }
diff --git a/baremetal/shell/print.mu b/baremetal/shell/print.mu
index f8e9de31..13605fef 100644
--- a/baremetal/shell/print.mu
+++ b/baremetal/shell/print.mu
@@ -3,6 +3,12 @@ fn print-cell _in: (addr handle cell), out: (addr stream byte) {
   var in/eax: (addr handle cell) <- copy _in
   var in-addr/eax: (addr cell) <- lookup *in
   var in-type/ecx: (addr int) <- get in-addr, type
+  compare *in-type, 1/number
+  {
+    break-if-!=
+    print-number in-addr, out
+    return
+  }
   compare *in-type, 2/symbol
   {
     break-if-!=
@@ -26,3 +32,9 @@ fn print-symbol _in: (addr cell), out: (addr stream byte) {
     loop
   }
 }
+
+fn print-number _in: (addr cell), out: (addr stream byte) {
+  var in/esi: (addr cell) <- copy _in
+  var val/eax: (addr float) <- get in, number-data
+  write-float-decimal-approximate out, *val, 3/precision
+}
diff --git a/baremetal/shell/tokenize.mu b/baremetal/shell/tokenize.mu
index 2f1c4e62..07ba9f8a 100644
--- a/baremetal/shell/tokenize.mu
+++ b/baremetal/shell/tokenize.mu
@@ -1,3 +1,7 @@
+# We reuse the cell data structure for tokenization
+# Token cells are special, though. They have no type, they're always atoms,
+# they always have text-data.
+
 fn tokenize in: (addr gap-buffer), out: (addr stream cell), trace: (addr trace) {
   trace-text trace, "read", "tokenize"
   trace-lower trace
@@ -368,3 +372,13 @@ fn is-bracket-grapheme? g: grapheme -> _/eax: boolean {
   }
   return 0/false
 }
+
+fn is-number-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 g/eax: grapheme <- read-grapheme in-data
+  var result/eax: boolean <- is-decimal-digit? g
+  return result
+}