about summary refs log tree commit diff stats
path: root/apps/tile
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2020-10-25 21:15:43 -0700
committerKartik Agaram <vc@akkartik.com>2020-10-25 21:15:43 -0700
commit2d7960d493c11ba6286193ec01b7f6771cd0b695 (patch)
tree023f318219fa5fe50faa891b37a4b7381cb70d91 /apps/tile
parent1787560a6d1c3de236a40c3be457925b82a01bfd (diff)
downloadmu-2d7960d493c11ba6286193ec01b7f6771cd0b695.tar.gz
7106 - tile: arrays of ints
Diffstat (limited to 'apps/tile')
-rw-r--r--apps/tile/data.mu1
-rw-r--r--apps/tile/environment.mu28
-rw-r--r--apps/tile/rpn.mu77
-rw-r--r--apps/tile/value-stack.mu64
4 files changed, 145 insertions, 25 deletions
diff --git a/apps/tile/data.mu b/apps/tile/data.mu
index f69ed645..7575461c 100644
--- a/apps/tile/data.mu
+++ b/apps/tile/data.mu
@@ -37,6 +37,7 @@ type value {
   type: int
   int-data: int  # if type = 0
   text-data: (handle array byte)  # if type = 1
+  array-data: (handle array int)  # if type = 2
 }
 
 type table {
diff --git a/apps/tile/environment.mu b/apps/tile/environment.mu
index bdf9574c..e37b32ba 100644
--- a/apps/tile/environment.mu
+++ b/apps/tile/environment.mu
@@ -424,6 +424,7 @@ $process-sandbox:body: {
       break $process-sandbox:body
     }
     # if start of word is quote and grapheme before cursor is not, just insert it as usual
+    # TODO: support string escaping
     {
       var first-grapheme/eax: grapheme <- first-grapheme cursor-word
       compare first-grapheme, 0x22  # double quote
@@ -433,6 +434,17 @@ $process-sandbox:body: {
       break-if-=
       break $process-sandbox:space
     }
+    # if start of word is '[' and grapheme before cursor is not ']', just insert it as usual
+    # TODO: support nested arrays
+    {
+      var first-grapheme/eax: grapheme <- first-grapheme cursor-word
+      compare first-grapheme, 0x5b  # '['
+      break-if-!=
+      var final-grapheme/eax: grapheme <- grapheme-before-cursor cursor-word
+      compare final-grapheme, 0x5d  # ']'
+      break-if-=
+      break $process-sandbox:space
+    }
     # otherwise insert word after and move cursor to it for the next key
     # (but we'll continue to track the current cursor-word for the rest of this function)
     append-word cursor-word-ah
@@ -1352,6 +1364,14 @@ fn render-column screen: (addr screen), functions: (addr handle function), bindi
             print-string screen, val
             break $render-column:render-value
           }
+          {
+            compare *val-type, 2  # array
+            break-if-!=
+            var val-ah/eax: (addr handle array int) <- get val-addr, array-data
+            var val/eax: (addr array int) <- lookup *val-ah
+            render-array screen, val
+            break $render-column:render-value
+          }
           # render ints by default for now
           var val-addr2/eax: (addr int) <- get val-addr, int-data
           render-integer screen, *val-addr2, max-width
@@ -1410,6 +1430,14 @@ fn render-integer screen: (addr screen), val: int, max-width: int {
   print-grapheme screen, 0x20  # space
 }
 
+fn render-array screen: (addr screen), val: (addr array int) {
+  start-color screen, 0, 7
+  # don't surround in spaces
+  print-grapheme screen, 0x5b  # '['
+  print-array-of-ints-in-decimal screen, val
+  print-grapheme screen, 0x5d  # ']'
+}
+
 fn hash-color val: int -> result/eax: int {
   result <- try-modulo val, 7  # assumes that 7 is always the background color
 }
diff --git a/apps/tile/rpn.mu b/apps/tile/rpn.mu
index 847a3a8c..ef53bb7e 100644
--- a/apps/tile/rpn.mu
+++ b/apps/tile/rpn.mu
@@ -65,30 +65,42 @@ fn evaluate functions: (addr handle function), bindings: (addr table), scratch:
         top <- decrement
         var dest-offset/edx: (offset value) <- compute-offset data, top
         var target-val/edx: (addr value) <- index data, dest-offset
-        # check target-val is a string
+        # check target-val is a string or array
         var target-type-addr/eax: (addr int) <- get target-val, type
-#?         print-string 0, "checking type: "
-#?         {
-#?           var foo/eax: int <- copy target-type-addr
-#?           print-int32-hex 0, foo
-#?         }
-#?         print-string 0, "\n"
         compare *target-type-addr, 1  # string
-        break-if-!=
-#?         print-string 0, "is string\n"
-        # compute length
-        var src-ah/eax: (addr handle array byte) <- get target-val, text-data
-        var src/eax: (addr array byte) <- lookup *src-ah
-        var result/ebx: int <- length src
-        # save result into target-val
-        var type-addr/eax: (addr int) <- get target-val, type
-        copy-to *type-addr, 0  # int
-        var target-string-ah/eax: (addr handle array byte) <- get target-val, text-data
-        var empty: (handle array byte)
-        copy-handle empty, target-string-ah
-        var target/eax: (addr int) <- get target-val, int-data
-        copy-to *target, result
-        break $evaluate:process-word
+        {
+          break-if-!=
+          # compute length
+          var src-ah/eax: (addr handle array byte) <- get target-val, text-data
+          var src/eax: (addr array byte) <- lookup *src-ah
+          var result/ebx: int <- length src
+          # save result into target-val
+          var type-addr/eax: (addr int) <- get target-val, type
+          copy-to *type-addr, 0  # int
+          var target-string-ah/eax: (addr handle array byte) <- get target-val, text-data
+          var empty: (handle array byte)
+          copy-handle empty, target-string-ah
+          var target/eax: (addr int) <- get target-val, int-data
+          copy-to *target, result
+          break $evaluate:process-word
+        }
+        compare *target-type-addr, 2  # array of ints
+        {
+          break-if-!=
+          # compute length
+          var src-ah/eax: (addr handle array int) <- get target-val, array-data
+          var src/eax: (addr array int) <- lookup *src-ah
+          var result/ebx: int <- length src
+          # save result into target-val
+          var type-addr/eax: (addr int) <- get target-val, type
+          copy-to *type-addr, 0  # int
+          var target-array-ah/eax: (addr handle array int) <- get target-val, array-data
+          var empty: (handle array int)
+          copy-handle empty, target-array-ah
+          var target/eax: (addr int) <- get target-val, int-data
+          copy-to *target, result
+          break $evaluate:process-word
+        }
       }
       # if curr-stream defines a binding, save top of stack to bindings
       {
@@ -152,7 +164,7 @@ fn evaluate functions: (addr handle function), bindings: (addr table), scratch:
         push-value-stack out, val
         break $evaluate:process-word
       }
-      # if the word starts with a quote and ends with a quote, return it directly
+      # if the word starts with a quote and ends with a quote, turn it into a string
       {
         var start/eax: byte <- stream-first curr-stream
         compare start, 0x22  # double-quote
@@ -166,6 +178,25 @@ fn evaluate functions: (addr handle function), bindings: (addr table), scratch:
         push-string-to-value-stack out, *s
         break $evaluate:process-word
       }
+      # if the word starts with a '[' and ends with a ']', turn it into an array
+      {
+        var start/eax: byte <- stream-first curr-stream
+        compare start, 0x5b  # '['
+        break-if-!=
+        var end/eax: byte <- stream-final curr-stream
+        compare end, 0x5d  # ']'
+        break-if-!=
+        # wastefully create a new string to strip quotes
+        var h: (handle array int)
+        var tmp-ah/eax: (addr handle array byte) <- address h
+        unquote-stream-to-string curr-stream, tmp-ah  # leak
+        var tmp/eax: (addr array byte) <- lookup *tmp-ah
+        var h2: (handle array int)
+        var array-ah/ecx: (addr handle array int) <- address h2
+        parse-array-of-ints tmp, array-ah  # leak
+        push-array-to-value-stack out, *array-ah
+        break $evaluate:process-word
+      }
       # otherwise assume it's a literal int and push it
       {
         var n/eax: int <- parse-decimal-int-from-stream curr-stream
diff --git a/apps/tile/value-stack.mu b/apps/tile/value-stack.mu
index 093e8846..dbe25b74 100644
--- a/apps/tile/value-stack.mu
+++ b/apps/tile/value-stack.mu
@@ -55,6 +55,27 @@ fn push-string-to-value-stack _self: (addr value-stack), val: (handle array byte
   increment *top-addr
 }
 
+fn push-array-to-value-stack _self: (addr value-stack), val: (handle array int) {
+  var self/esi: (addr value-stack) <- copy _self
+  var top-addr/ecx: (addr int) <- get self, top
+  var data-ah/edx: (addr handle array value) <- get self, data
+  var data/eax: (addr array value) <- lookup *data-ah
+  var top/edx: int <- copy *top-addr
+  var dest-offset/edx: (offset value) <- compute-offset data, top
+  var dest-addr/edx: (addr value) <- index data, dest-offset
+  var dest-addr2/eax: (addr handle array int) <- get dest-addr, array-data
+  copy-handle val, dest-addr2
+  var dest-addr3/eax: (addr int) <- get dest-addr, type
+#?   print-string 0, "setting type to 1: "
+#?   {
+#?     var foo/eax: int <- copy dest-addr3
+#?     print-int32-hex 0, foo
+#?   }
+#?   print-string 0, "\n"
+  copy-to *dest-addr3, 2  # type array
+  increment *top-addr
+}
+
 fn push-value-stack _self: (addr value-stack), val: (addr value) {
   var self/esi: (addr value-stack) <- copy _self
   var top-addr/ecx: (addr int) <- get self, top
@@ -123,7 +144,7 @@ fn value-stack-max-width _self: (addr value-stack) -> result/eax: int {
     var g/edx: (addr value) <- index data, o
     var type/eax: (addr int) <- get g, type
     {
-      compare *type, 0
+      compare *type, 0  # int
       break-if-!=
       var g2/edx: (addr int) <- get g, int-data
       var w/eax: int <- decimal-size *g2
@@ -132,7 +153,7 @@ fn value-stack-max-width _self: (addr value-stack) -> result/eax: int {
       copy-to out, w
     }
     {
-      compare *type, 1
+      compare *type, 1  # string
       break-if-!=
       var s-ah/eax: (addr handle array byte) <- get g, text-data
       var s/eax: (addr array byte) <- lookup *s-ah
@@ -143,8 +164,47 @@ fn value-stack-max-width _self: (addr value-stack) -> result/eax: int {
       break-if-<=
       copy-to out, w
     }
+    {
+      compare *type, 2  # array
+      break-if-!=
+      var a-ah/eax: (addr handle array int) <- get g, array-data
+      var a/eax: (addr array int) <- lookup *a-ah
+      compare a, 0
+      break-if-=
+      var w/eax: int <- array-decimal-size a
+      compare w, out
+      break-if-<=
+      copy-to out, w
+    }
+    i <- increment
+    loop
+  }
+  result <- copy out
+}
+
+# keep sync'd with print-array-of-ints
+fn array-decimal-size _a: (addr array int) -> result/eax: int {
+  var a/esi: (addr array int) <- copy _a
+  var max/ecx: int <- length a
+  var i/eax: int <- copy 0
+  var out/edi: int <- copy 0
+  {
+    compare i, max
+    break-if->=
+    {
+      compare i, 0
+      break-if-=
+      out <- increment  # for space
+    }
+    var x/ecx: (addr int) <- index a, i
+    {
+      var w/eax: int <- decimal-size *x
+      out <- add w
+    }
     i <- increment
     loop
   }
   result <- copy out
+  # we won't add 2 for surrounding brackets since we don't surround arrays in
+  # spaces like other value types
 }