about summary refs log tree commit diff stats
path: root/apps/tile/rpn.mu
diff options
context:
space:
mode:
Diffstat (limited to 'apps/tile/rpn.mu')
-rw-r--r--apps/tile/rpn.mu94
1 files changed, 94 insertions, 0 deletions
diff --git a/apps/tile/rpn.mu b/apps/tile/rpn.mu
new file mode 100644
index 00000000..a70d9fd5
--- /dev/null
+++ b/apps/tile/rpn.mu
@@ -0,0 +1,94 @@
+fn simplify in: (addr stream byte), out: (addr int-stack) {
+  var word-storage: slice
+  var word/ecx: (addr slice) <- address word-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
+    }
+    # otherwise it's an int
+    var n/eax: int <- parse-decimal-int-from-slice word
+    push-int-stack out, n
+    loop
+  }
+}
+
+# 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 {
+  var a/eax: int <- copy first-word
+  print-string-to-real-screen "inside max-stack-depth: "
+  print-int32-hex-to-real-screen a
+  print-string-to-real-screen "\n"
+  var curr-word/esi: (addr word) <- copy first-word
+  var curr-depth/ecx: int <- copy 0
+  result <- copy 0
+  $max-stack-depth:word-loop: {
+    # handle operators
+    {
+      var is-add?/eax: boolean <- word-equal? curr-word, "+"
+      compare is-add?, 0
+      break-if-=
+      curr-depth <- decrement
+      loop $max-stack-depth:word-loop
+    }
+    {
+      var is-sub?/eax: boolean <- word-equal? curr-word, "-"
+      compare is-sub?, 0
+      break-if-=
+      curr-depth <- decrement
+      loop $max-stack-depth:word-loop
+    }
+    {
+      var is-mul?/eax: boolean <- word-equal? curr-word, "*"
+      compare is-mul?, 0
+      break-if-=
+      curr-depth <- decrement
+      loop $max-stack-depth:word-loop
+    }
+    # otherwise it's an int (do we need error-checking?)
+    curr-depth <- increment
+    # update max depth if necessary
+    {
+      compare curr-depth, result
+      break-if-<=
+      result <- copy curr-depth
+    }
+    loop
+  }
+}