about summary refs log tree commit diff stats
path: root/apps/tile/rpn.mu
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2020-09-19 21:44:48 -0700
committerKartik Agaram <vc@akkartik.com>2020-09-19 21:44:48 -0700
commit8e4b4f2013b3f347e84398c70eabab60f6edd625 (patch)
treebf0e5f947ea43dbca51998bd4a27a05ffd8d161b /apps/tile/rpn.mu
parent72e8240a23da7b82893d6b4e7ed3337ca0827049 (diff)
downloadmu-8e4b4f2013b3f347e84398c70eabab60f6edd625.tar.gz
6807 - tile: render intermediate stack state
Diffstat (limited to 'apps/tile/rpn.mu')
-rw-r--r--apps/tile/rpn.mu122
1 files changed, 78 insertions, 44 deletions
diff --git a/apps/tile/rpn.mu b/apps/tile/rpn.mu
index 696912fd..3ca8a38f 100644
--- a/apps/tile/rpn.mu
+++ b/apps/tile/rpn.mu
@@ -1,53 +1,87 @@
-fn simplify in: (addr stream byte), out: (addr int-stack) {
-  var word-storage: slice
-  var word/ecx: (addr slice) <- address word-storage
+fn evaluate start: (addr word), end: (addr word), out: (addr int-stack) {
+  var curr/eax: (addr word) <- copy start
+  var curr-text-storage: (stream byte 0x10)
+  var curr-text/edi: (addr stream byte) <- address curr-text-storage
   clear-int-stack out
-  $simplify:word-loop: {
-    next-word in, word
-    var done?/eax: boolean <- slice-empty? word
-    compare done?, 0
-    break-if-!=
-    # if word is an operator, perform it
-    {
-      var is-add?/eax: boolean <- slice-equal? word, "+"
-      compare is-add?, 0
-      break-if-=
-      var _b/eax: int <- pop-int-stack out
-      var b/edx: int <- copy _b
-      var a/eax: int <- pop-int-stack out
-      a <- add b
-      push-int-stack out, a
-      loop $simplify:word-loop
-    }
-    {
-      var is-sub?/eax: boolean <- slice-equal? word, "-"
-      compare is-sub?, 0
-      break-if-=
-      var _b/eax: int <- pop-int-stack out
-      var b/edx: int <- copy _b
-      var a/eax: int <- pop-int-stack out
-      a <- subtract b
-      push-int-stack out, a
-      loop $simplify:word-loop
-    }
-    {
-      var is-mul?/eax: boolean <- slice-equal? word, "*"
-      compare is-mul?, 0
-      break-if-=
-      var _b/eax: int <- pop-int-stack out
-      var b/edx: int <- copy _b
-      var a/eax: int <- pop-int-stack out
-      a <- multiply b
-      push-int-stack out, a
-      loop $simplify:word-loop
+  $evaluate:loop: {
+    # precondition (should never hit)
+    compare curr, 0
+    break-if-=
+    # update curr-text
+    emit-word curr, curr-text
+    $evaluate:process-word: {
+      # if curr-text is an operator, perform it
+      {
+        var is-add?/eax: boolean <- stream-data-equal? curr-text, "+"
+        compare is-add?, 0
+        break-if-=
+        var _b/eax: int <- pop-int-stack out
+        var b/edx: int <- copy _b
+        var a/eax: int <- pop-int-stack out
+        a <- add b
+        push-int-stack out, a
+        break $evaluate:process-word
+      }
+      {
+        var is-sub?/eax: boolean <- stream-data-equal? curr-text, "-"
+        compare is-sub?, 0
+        break-if-=
+        var _b/eax: int <- pop-int-stack out
+        var b/edx: int <- copy _b
+        var a/eax: int <- pop-int-stack out
+        a <- subtract b
+        push-int-stack out, a
+        break $evaluate:process-word
+      }
+      {
+        var is-mul?/eax: boolean <- stream-data-equal? curr-text, "*"
+        compare is-mul?, 0
+        break-if-=
+        var _b/eax: int <- pop-int-stack out
+        var b/edx: int <- copy _b
+        var a/eax: int <- pop-int-stack out
+        a <- multiply b
+        push-int-stack out, a
+        break $evaluate:process-word
+      }
+      # otherwise it's an int
+      {
+        var n/eax: int <- parse-decimal-int-from-stream curr-text
+        push-int-stack out, n
+      }
     }
-    # otherwise it's an int
-    var n/eax: int <- parse-decimal-int-from-slice word
-    push-int-stack out, n
+    # termination check
+    compare curr, end
+    break-if-=
+    # update
+    var next-word-ah/edx: (addr handle word) <- get curr, next
+    curr <- lookup *next-word-ah
+    #
     loop
   }
 }
 
+fn test-evaluate {
+  # input = [1, 2, +]
+  var w: (handle word)
+  var wah/eax: (addr handle word) <- address w
+  allocate wah
+  var wa/eax: (addr word) <- lookup w
+  initialize-word-with wa, "1"
+  append-word-with w, "2"
+  var next/ecx: (addr handle word) <- get wa, next
+  append-word-with *next, "+"
+  # initialize output
+  var stack-storage: int-stack
+  var stack/edx: (addr int-stack) <- address stack-storage
+  initialize-int-stack stack, 0x10
+  #
+  evaluate wa, 0, stack
+  # check output
+  var x/eax: int <- pop-int-stack stack
+  check-ints-equal x, 3, "F - test-evaluate"
+}
+
 # Copy of 'simplify' that just tracks the maximum stack depth needed
 # Doesn't actually need to simulate the stack, since every word has a predictable effect.
 fn max-stack-depth first-word: (addr word), final-word: (addr word) -> result/edi: int {