about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2020-09-26 21:58:47 -0700
committerKartik Agaram <vc@akkartik.com>2020-09-26 21:59:50 -0700
commitebb93c6d58ab087c581948acfc054e91a02047f9 (patch)
treec856a4a1e4ca7565983b2f5caf2a709bd1a3e31b
parent65e6633b79e97fdbaab37a47b8246d2726ae5907 (diff)
downloadmu-ebb93c6d58ab087c581948acfc054e91a02047f9.tar.gz
6870
Emit a stack of not ints but more complex objects containing the int payload.

Function calls again segfaulting.
-rw-r--r--apps/tile/data.mu2
-rw-r--r--apps/tile/environment.mu14
-rw-r--r--apps/tile/main.mu12
-rw-r--r--apps/tile/rpn.mu58
-rw-r--r--apps/tile/table.mu18
-rw-r--r--apps/tile/value-stack.mu64
6 files changed, 103 insertions, 65 deletions
diff --git a/apps/tile/data.mu b/apps/tile/data.mu
index 31c9aa16..9b852a82 100644
--- a/apps/tile/data.mu
+++ b/apps/tile/data.mu
@@ -48,7 +48,7 @@ type table {
 
 type bind {
   key: (handle array byte)
-  value: value
+  value: (handle value)  # I'd inline this but we sometimes want to return a specific value from a table
 }
 
 type result {
diff --git a/apps/tile/environment.mu b/apps/tile/environment.mu
index 906905d0..f85e7dd6 100644
--- a/apps/tile/environment.mu
+++ b/apps/tile/environment.mu
@@ -157,7 +157,7 @@ $process:body: {
 }
 }
 
-fn evaluate-environment _env: (addr environment), stack: (addr int-stack) {
+fn evaluate-environment _env: (addr environment), stack: (addr value-stack) {
   var env/esi: (addr environment) <- copy _env
   # program
   var program-ah/eax: (addr handle program) <- get env, program
@@ -242,22 +242,22 @@ fn render-column screen: (addr screen), defs: (addr handle function), bindings:
     var indented-col/ebx: int <- copy left-col
     indented-col <- add 1  # margin-right - 2 for padding spaces
     # compute stack
-    var stack: int-stack
-    var stack-addr/edi: (addr int-stack) <- address stack
-    initialize-int-stack stack-addr, 0x10  # max-words
+    var stack: value-stack
+    var stack-addr/edi: (addr value-stack) <- address stack
+    initialize-value-stack stack-addr, 0x10  # max-words
     evaluate defs, bindings, scratch, final-word, stack-addr
     # render stack
     var curr-row/edx: int <- copy top-row
     curr-row <- add 3  # stack-margin-top
-    var _max-width/eax: int <- int-stack-max-width stack-addr
+    var _max-width/eax: int <- value-stack-max-width stack-addr
     var max-width/esi: int <- copy _max-width
-    var i/eax: int <- int-stack-length stack-addr
+    var i/eax: int <- value-stack-length stack-addr
     {
       compare i, 0
       break-if-<=
       move-cursor screen, curr-row, indented-col
       {
-        var val/eax: int <- pop-int-stack stack-addr
+        var val/eax: int <- pop-int-from-value-stack stack-addr
         render-integer screen, val, max-width
         var size/eax: int <- decimal-size val
         compare size, max-width
diff --git a/apps/tile/main.mu b/apps/tile/main.mu
index afefc4b5..8d44ba80 100644
--- a/apps/tile/main.mu
+++ b/apps/tile/main.mu
@@ -67,24 +67,24 @@ fn repl {
   var env-storage: environment
   var env/esi: (addr environment) <- address env-storage
   initialize-environment env
-  var stack-storage: int-stack
-  var stack/edi: (addr int-stack) <- address stack-storage
-  initialize-int-stack stack, 0x10
+  var stack-storage: value-stack
+  var stack/edi: (addr value-stack) <- address stack-storage
+  initialize-value-stack stack, 0x10
   print-string-to-real-screen "> "
   $repl:loop: {
     var key/eax: grapheme <- read-key-from-real-keyboard
     print-grapheme-to-real-screen key
     compare key, 4  # ctrl-d
     break-if-=
-    compare key, 0xa  # 'q'
+    compare key, 0xa  # newline
     {
       break-if-!=
       evaluate-environment env, stack
-      var empty?/eax: boolean <- int-stack-empty? stack
+      var empty?/eax: boolean <- value-stack-empty? stack
       {
         compare empty?, 0  # false
         break-if-!=
-        var result/eax: int <- pop-int-stack stack
+        var result/eax: int <- pop-int-from-value-stack stack
         print-int32-decimal-to-real-screen result
         print-string-to-real-screen "\n"
       }
diff --git a/apps/tile/rpn.mu b/apps/tile/rpn.mu
index 1d94d69f..ab3a623c 100644
--- a/apps/tile/rpn.mu
+++ b/apps/tile/rpn.mu
@@ -1,10 +1,10 @@
-fn evaluate defs: (addr handle function), bindings: (addr table), scratch: (addr line), end: (addr word), out: (addr int-stack) {
+fn evaluate defs: (addr handle function), bindings: (addr table), scratch: (addr line), end: (addr word), out: (addr value-stack) {
   var line/eax: (addr line) <- copy scratch
   var word-ah/eax: (addr handle word) <- get line, data
   var curr/eax: (addr word) <- lookup *word-ah
   var curr-stream-storage: (stream byte 0x10)
   var curr-stream/edi: (addr stream byte) <- address curr-stream-storage
-  clear-int-stack out
+  clear-value-stack out
   $evaluate:loop: {
     # precondition (should never hit)
     compare curr, 0
@@ -19,33 +19,33 @@ fn evaluate defs: (addr handle function), bindings: (addr table), scratch: (addr
         var is-add?/eax: boolean <- stream-data-equal? curr-stream, "+"
         compare is-add?, 0
         break-if-=
-        var _b/eax: int <- pop-int-stack out
+        var _b/eax: int <- pop-int-from-value-stack out
         var b/edx: int <- copy _b
-        var a/eax: int <- pop-int-stack out
+        var a/eax: int <- pop-int-from-value-stack out
         a <- add b
-        push-int-stack out, a
+        push-int-to-value-stack out, a
         break $evaluate:process-word
       }
       {
         var is-sub?/eax: boolean <- stream-data-equal? curr-stream, "-"
         compare is-sub?, 0
         break-if-=
-        var _b/eax: int <- pop-int-stack out
+        var _b/eax: int <- pop-int-from-value-stack out
         var b/edx: int <- copy _b
-        var a/eax: int <- pop-int-stack out
+        var a/eax: int <- pop-int-from-value-stack out
         a <- subtract b
-        push-int-stack out, a
+        push-int-to-value-stack out, a
         break $evaluate:process-word
       }
       {
         var is-mul?/eax: boolean <- stream-data-equal? curr-stream, "*"
         compare is-mul?, 0
         break-if-=
-        var _b/eax: int <- pop-int-stack out
+        var _b/eax: int <- pop-int-from-value-stack out
         var b/edx: int <- copy _b
-        var a/eax: int <- pop-int-stack out
+        var a/eax: int <- pop-int-from-value-stack out
         a <- multiply b
-        push-int-stack out, a
+        push-int-to-value-stack out, a
         break $evaluate:process-word
       }
       # if curr-stream is a known function name, call it appropriately
@@ -65,26 +65,26 @@ fn evaluate defs: (addr handle function), bindings: (addr table), scratch: (addr
         break-if-=
         var tmp: (handle array byte)
         var curr-string-ah/edx: (addr handle array byte) <- address tmp
-        stream-to-string curr-stream, curr-string-ah
-        var _curr-string/eax: (addr array byte) <- lookup *curr-string-ah
-        var curr-string/edx: (addr array byte) <- copy _curr-string
-        var result/eax: int <- copy 0
-        var found?/ecx: boolean <- copy 0  # false
-        result, found? <- lookup-binding bindings, curr-string
-        compare found?, 0  # false
+        stream-to-string curr-stream, curr-string-ah  # unfortunate leak
+        var curr-string/eax: (addr array byte) <- lookup *curr-string-ah
+        var val-storage: (handle value)
+        var val-ah/edi: (addr handle value) <- address val-storage
+        lookup-binding bindings, curr-string, val-ah
+        var val/eax: (addr value) <- lookup *val-ah
+        compare val, 0
         break-if-=
 #?         print-string-to-real-screen "value of "
 #?         print-string-to-real-screen curr-string
 #?         print-string-to-real-screen " is "
 #?         print-int32-hex-to-real-screen result
 #?         print-string-to-real-screen "\n"
-        push-int-stack out, result
+        push-value-stack out, val
         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
-        push-int-stack out, n
+        push-int-to-value-stack out, n
       }
     }
     # termination check
@@ -119,7 +119,7 @@ fn find-function first: (addr handle function), name: (addr stream byte), out: (
   }
 }
 
-fn perform-call _callee: (addr function), caller-stack: (addr int-stack), defs: (addr handle function) {
+fn perform-call _callee: (addr function), caller-stack: (addr value-stack), defs: (addr handle function) {
   var callee/ecx: (addr function) <- copy _callee
   # create bindings for args
   var table-storage: table
@@ -141,7 +141,7 @@ fn perform-call _callee: (addr function), caller-stack: (addr int-stack), defs:
 #?       print-string-to-real-screen "binding "
 #?       print-string-to-real-screen tmp
 #?       print-string-to-real-screen " to "
-      var curr-val/eax: int <- pop-int-stack caller-stack
+      var curr-val/eax: int <- pop-int-from-value-stack caller-stack
 #?       print-int32-decimal-to-real-screen curr-val
 #?       print-string-to-real-screen "\n"
       bind-int-in-table table, curr-key, curr-val
@@ -155,15 +155,15 @@ fn perform-call _callee: (addr function), caller-stack: (addr int-stack), defs:
   var body-ah/eax: (addr handle line) <- get callee, body
   var body/eax: (addr line) <- lookup *body-ah
   # perform call
-  var stack-storage: int-stack
-  var stack/edi: (addr int-stack) <- address stack-storage
-  initialize-int-stack stack, 0x10
-#?   print-string-to-real-screen "about to enter recursive eval\n"
+  var stack-storage: value-stack
+  var stack/edi: (addr value-stack) <- address stack-storage
+  initialize-value-stack stack, 0x10
+  print-string-to-real-screen "about to enter recursive eval\n"
   evaluate defs, table, body, 0, stack
-#?   print-string-to-real-screen "exited recursive eval\n"
+  print-string-to-real-screen "exited recursive eval\n"
   # stitch result from stack into caller
-  var result/eax: int <- pop-int-stack stack
-  push-int-stack caller-stack, result
+  var result/eax: int <- pop-int-from-value-stack stack
+  push-int-to-value-stack caller-stack, result
 }
 
 # Copy of 'simplify' that just tracks the maximum stack depth needed
diff --git a/apps/tile/table.mu b/apps/tile/table.mu
index 53fb5ce7..fc3a5399 100644
--- a/apps/tile/table.mu
+++ b/apps/tile/table.mu
@@ -40,22 +40,20 @@ fn make-binding _self: (addr bind), key: (addr handle array byte), _val: int {
   var self/esi: (addr bind) <- copy _self
   var dest/eax: (addr handle array byte) <- get self, key
   copy-object key, dest
-  var dest2/eax: (addr value) <- get self, value
-  var dest3/eax: (addr int) <- get dest2, scalar-data
+  var dest2/eax: (addr handle value) <- get self, value
+  var dest3/eax: (addr value) <- lookup *dest2
+  var dest4/eax: (addr int) <- get dest3, scalar-data
   var val/ecx: int <- copy _val
-  copy-to *dest3, val
+  copy-to *dest4, val
 }
 
-# TODO: supporting non-integers
-# That'll require radical surgery.
-fn lookup-binding _self: (addr table), key: (addr array byte) -> result/eax: int, found?/ecx: boolean {
+fn lookup-binding _self: (addr table), key: (addr array byte), out: (addr handle value) {
   var self/esi: (addr table) <- copy _self
   var data-ah/esi: (addr handle array bind) <- get self, data
   var _data/eax: (addr array bind) <- lookup *data-ah
   var data/esi: (addr array bind) <- copy _data
   var len/edx: int <- length data
   var i/ebx: int <- copy 0
-  found? <- copy 0  # false
   $lookup-binding:loop: {
     compare i, len
     break-if->=
@@ -70,10 +68,8 @@ fn lookup-binding _self: (addr table), key: (addr array byte) -> result/eax: int
       compare is-match?, 0  # false
       break-if-=
       # found
-      found? <- copy 1  # true
-      var dest2/eax: (addr value) <- get target-bind, value
-      var dest3/eax: (addr int) <- get dest2, scalar-data
-      result <- copy *dest3
+      var target/eax: (addr handle value) <- get target-bind, value
+      copy-object target, out
       break $lookup-binding:loop
     }
     i <- increment
diff --git a/apps/tile/value-stack.mu b/apps/tile/value-stack.mu
index f43cd25d..126ed036 100644
--- a/apps/tile/value-stack.mu
+++ b/apps/tile/value-stack.mu
@@ -1,3 +1,5 @@
+# support for non-int values is untested
+
 type value-stack {
   data: (handle array value)
   top: int
@@ -17,7 +19,22 @@ fn clear-value-stack _self: (addr value-stack) {
   copy-to *top, 0
 }
 
-fn push-value-stack _self: (addr value-stack), _val: value {
+fn push-int-to-value-stack _self: (addr value-stack), _val: 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 int) <- get dest-addr, scalar-data
+  var val/esi: int <- copy _val
+#?   print-int32-hex-to-real-screen val
+  copy-to *dest-addr2, val
+  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
   var data-ah/edx: (addr handle array value) <- get self, data
@@ -25,28 +42,28 @@ fn push-value-stack _self: (addr value-stack), _val: value {
   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 val/eax: value <- copy _val
-  copy-to *dest-addr, val
-  add-to *top-addr, 1
+  copy-object val, dest-addr
+  increment *top-addr
 }
 
-fn pop-value-stack _self: (addr value-stack) -> val/eax: value {
-$pop-value-stack:body: {
+fn pop-int-from-value-stack _self: (addr value-stack) -> val/eax: int {
+$pop-int-from-value-stack:body: {
   var self/esi: (addr value-stack) <- copy _self
   var top-addr/ecx: (addr int) <- get self, top
   {
     compare *top-addr, 0
     break-if->
     val <- copy -1
-    break $pop-value-stack:body
+    break $pop-int-from-value-stack:body
   }
-  subtract-from *top-addr, 1
+  decrement *top-addr
   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 result-addr/eax: (addr value) <- index data, dest-offset
-  val <- copy *result-addr
+  var result-addr2/eax: (addr int) <- get result-addr, scalar-data
+  val <- copy *result-addr2
 }
 }
 
@@ -56,8 +73,8 @@ $value-stack-empty?:body: {
   var top/eax: (addr int) <- get self, top
   compare *top, 0
   {
-    break-if-=
-    result <- copy 1  # false
+    break-if-!=
+    result <- copy 1  # true
     break $value-stack-empty?:body
   }
   result <- copy 0  # false
@@ -69,3 +86,28 @@ fn value-stack-length _self: (addr value-stack) -> result/eax: int {
   var top-addr/eax: (addr int) <- get self, top
   result <- copy *top-addr
 }
+
+fn value-stack-max-width _self: (addr value-stack) -> result/eax: int {
+  var self/esi: (addr value-stack) <- copy _self
+  var data-ah/edi: (addr handle array value) <- get self, data
+  var _data/eax: (addr array value) <- lookup *data-ah
+  var data/edi: (addr array value) <- copy _data
+  var top-addr/ecx: (addr int) <- get self, top
+  var i/ebx: int <- copy 0
+  result <- copy 0
+  {
+    compare i, *top-addr
+    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, scalar-data
+    var w/ecx: int <- int-width-decimal *g2
+    compare w, result
+    {
+      break-if-<=
+      result <- copy w
+    }
+    i <- increment
+    loop
+  }
+}