about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2020-10-25 17:41:06 -0700
committerKartik Agaram <vc@akkartik.com>2020-10-25 18:14:12 -0700
commit8a6ad45d8d26c60b62a2a7ac8d594b3c4d1dbc45 (patch)
treef021f4413da5f0b2e532fb7fd59f874355c366b1
parent517ef9f64f32ea6592c7b802fd94391254daf86c (diff)
downloadmu-8a6ad45d8d26c60b62a2a7ac8d594b3c4d1dbc45.tar.gz
7100 - tile: render string literals
-rw-r--r--309stream.subx56
-rw-r--r--400.mu2
-rwxr-xr-xapps/mubin421929 -> 422010 bytes
-rw-r--r--apps/tile/data.mu1
-rw-r--r--apps/tile/environment.mu32
-rw-r--r--apps/tile/rpn.mu14
-rw-r--r--apps/tile/value-stack.mu34
7 files changed, 129 insertions, 10 deletions
diff --git a/309stream.subx b/309stream.subx
index 84642def..adc92cfd 100644
--- a/309stream.subx
+++ b/309stream.subx
@@ -156,3 +156,59 @@ $read-from-stream:abort:
     bb/copy-to-ebx 1/imm32
     (syscall_exit)
     # never gets here
+
+stream-first:  # s: (addr stream byte) -> result/eax: byte
+    # . prologue
+    55/push-ebp
+    89/<- %ebp 4/r32/esp
+    # . save registers
+    51/push-ecx
+    56/push-esi
+    # result = false
+    b8/copy-to-eax 0/imm32
+    # esi = s
+    8b/-> *(ebp+8) 6/r32/esi
+    # var idx/ecx: int = s->read
+    8b/-> *(esi+4) 1/r32/ecx
+    # if idx >= s->write return 0
+    3b/compare-with 1/r32/ecx *esi
+    7d/jump-if->= $stream-first:end/disp8
+    # result = s->data[idx]
+    8a/byte-> *(esi+ecx+0xc) 0/r32/AL
+$stream-first:end:
+    # . restore registers
+    5e/pop-to-esi
+    59/pop-to-ecx
+    # . epilogue
+    89/<- %esp 5/r32/ebp
+    5d/pop-to-ebp
+    c3/return
+
+stream-final:  # s: (addr stream byte) -> result/eax: byte
+    # . prologue
+    55/push-ebp
+    89/<- %ebp 4/r32/esp
+    # . save registers
+    51/push-ecx
+    56/push-esi
+    # result = false
+    b8/copy-to-eax 0/imm32
+    # esi = s
+    8b/-> *(ebp+8) 6/r32/esi
+    # var max/ecx: int = s->write
+    8b/-> *esi 1/r32/ecx
+    # if s->read >= max return 0
+    39/compare-with *(esi+4) 1/r32/ecx
+    7d/jump-if->= $stream-final:end/disp8
+    # var idx/ecx: int = max - 1
+    49/decrement-ecx
+    # result = s->data[idx]
+    8a/byte-> *(esi+ecx+0xc) 0/r32/AL
+$stream-final:end:
+    # . restore registers
+    5e/pop-to-esi
+    59/pop-to-ecx
+    # . epilogue
+    89/<- %esp 5/r32/ebp
+    5d/pop-to-ebp
+    c3/return
diff --git a/400.mu b/400.mu
index 93e6f03a..fb686e17 100644
--- a/400.mu
+++ b/400.mu
@@ -177,5 +177,7 @@ sig new-buffered-file out: (addr handle buffered-file)
 sig stream-empty? s: (addr stream _) -> result/eax: boolean
 sig stream-full? s: (addr stream _) -> result/eax: boolean
 sig stream-to-string in: (addr stream _), out: (addr handle array _)
+sig stream-first s: (addr stream byte) -> result/eax: byte
+sig stream-final s: (addr stream byte) -> result/eax: byte
 
 #sig copy-bytes src: (addr byte), dest: (addr byte), n: int
diff --git a/apps/mu b/apps/mu
index 6c1e8057..d713a6eb 100755
--- a/apps/mu
+++ b/apps/mu
Binary files differdiff --git a/apps/tile/data.mu b/apps/tile/data.mu
index 18b7e7ce..f69ed645 100644
--- a/apps/tile/data.mu
+++ b/apps/tile/data.mu
@@ -36,6 +36,7 @@ type word {
 type value {
   type: int
   int-data: int  # if type = 0
+  text-data: (handle array byte)  # if type = 1
 }
 
 type table {
diff --git a/apps/tile/environment.mu b/apps/tile/environment.mu
index 2cc552c0..2b768c0a 100644
--- a/apps/tile/environment.mu
+++ b/apps/tile/environment.mu
@@ -1323,19 +1323,37 @@ fn render-column screen: (addr screen), functions: (addr handle function), bindi
     curr-row <- add 2  # stack-margin-top
     var _max-width/eax: int <- value-stack-max-width stack-addr
     max-width <- copy _max-width
-    var i/eax: int <- value-stack-length stack-addr
     {
-      compare i, 0
+      var top-addr/ecx: (addr int) <- get stack-addr, top
+      compare *top-addr, 0
       break-if-<=
+      decrement *top-addr
       move-cursor screen, curr-row, indented-col
       {
-        var val/eax: int <- pop-int-from-value-stack stack-addr
-#?         print-int32-decimal 0, val
-#?         print-string 0, "\n"
-        render-integer screen, val, max-width
+        var data-ah/eax: (addr handle array value) <- get stack-addr, 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 val-addr/eax: (addr value) <- index data, dest-offset
+        $render-column:render-value: {
+          var val-type/ecx: (addr int) <- get val-addr, type
+          # per-type rendering logic goes here
+          {
+            compare *val-type, 1  # string
+            break-if-!=
+            var val-ah/eax: (addr handle array byte) <- get val-addr, text-data
+            var val/eax: (addr array byte) <- lookup *val-ah
+            start-color screen, 0, 7
+            print-grapheme screen, 0x20  # space
+            print-string 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
+        }
       }
       curr-row <- increment
-      i <- decrement
       loop
     }
   }
diff --git a/apps/tile/rpn.mu b/apps/tile/rpn.mu
index 44108580..80ab47ae 100644
--- a/apps/tile/rpn.mu
+++ b/apps/tile/rpn.mu
@@ -99,6 +99,20 @@ 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
+      {
+        var start/eax: byte <- stream-first curr-stream
+        compare start, 0x22  # double-quote
+        break-if-!=
+        var end/eax: byte <- stream-final curr-stream
+        compare end, 0x22  # double-quote
+        break-if-!=
+        var h: (handle array byte)
+        var s/eax: (addr handle array byte) <- address h
+        stream-to-string curr-stream, s  # leak
+        push-string-to-value-stack out, *s
+        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 ba1a824d..aae87c3d 100644
--- a/apps/tile/value-stack.mu
+++ b/apps/tile/value-stack.mu
@@ -34,6 +34,21 @@ fn push-int-to-value-stack _self: (addr value-stack), _val: int {
   increment *top-addr
 }
 
+fn push-string-to-value-stack _self: (addr value-stack), val: (handle array byte) {
+  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 byte) <- get dest-addr, text-data
+  copy-handle val, dest-addr2
+  var dest-addr3/eax: (addr int) <- get dest-addr, type
+  copy-to *dest-addr3, 1  # type string
+  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
@@ -100,10 +115,23 @@ fn value-stack-max-width _self: (addr value-stack) -> result/eax: int {
     break-if->=
     var o/edx: (offset value) <- compute-offset data, i
     var g/edx: (addr value) <- index data, o
-    var g2/edx: (addr int) <- get g, int-data
-    var w/eax: int <- decimal-size *g2
-    compare w, out
+    var type/eax: (addr int) <- get g, type
+    {
+      compare *type, 0
+      break-if-!=
+      var g2/edx: (addr int) <- get g, int-data
+      var w/eax: int <- decimal-size *g2
+      compare w, out
+      break-if-<=
+      copy-to out, w
+    }
     {
+      compare *type, 1
+      break-if-!=
+      var s-ah/eax: (addr handle array byte) <- get g, text-data
+      var s/eax: (addr array byte) <- lookup *s-ah
+      var w/eax: int <- length s
+      compare w, out
       break-if-<=
       copy-to out, w
     }