about summary refs log tree commit diff stats
path: root/apps
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2020-09-26 21:23:04 -0700
committerKartik Agaram <vc@akkartik.com>2020-09-26 21:26:20 -0700
commit5babe16f2d4a8e51f6ffc8acd02bafe47d510ad0 (patch)
tree729cd28a695dd2ce52547c879a8570bfe8138ff9 /apps
parente46cfc2e0c053c3dc2ca17e52126a97f29ce618b (diff)
downloadmu-5babe16f2d4a8e51f6ffc8acd02bafe47d510ad0.tar.gz
6868
First function call working in apps/tile!
Diffstat (limited to 'apps')
-rw-r--r--apps/README.md3
-rw-r--r--apps/tile/rpn.mu56
-rw-r--r--apps/tile/table.mu39
3 files changed, 81 insertions, 17 deletions
diff --git a/apps/README.md b/apps/README.md
index 3cffc3fc..d17c0be9 100644
--- a/apps/README.md
+++ b/apps/README.md
@@ -1,7 +1,8 @@
 Some apps written in SubX and Mu. Check out:
 
 * `tile`: [A text-mode postfix calculator](https://mastodon.social/@akkartik/104896128141863951)
-  that updates as you type.
+  that updates as you type. Prototype. Look at this to see what is currently
+  possible, not how I recommend building software.
 
   <img alt='tile app' src='../html/rpn5.png' width='500px'>
 
diff --git a/apps/tile/rpn.mu b/apps/tile/rpn.mu
index 47383642..1d94d69f 100644
--- a/apps/tile/rpn.mu
+++ b/apps/tile/rpn.mu
@@ -2,21 +2,21 @@ fn evaluate defs: (addr handle function), bindings: (addr table), scratch: (addr
   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-text-storage: (stream byte 0x10)
-  var curr-text/edi: (addr stream byte) <- address curr-text-storage
+  var curr-stream-storage: (stream byte 0x10)
+  var curr-stream/edi: (addr stream byte) <- address curr-stream-storage
   clear-int-stack out
   $evaluate:loop: {
     # precondition (should never hit)
     compare curr, 0
     break-if-=
-    # update curr-text
-    emit-word curr, curr-text
-#?     print-stream-to-real-screen curr-text
+    # update curr-stream
+    emit-word curr, curr-stream
+#?     print-stream-to-real-screen curr-stream
 #?     print-string-to-real-screen "\n"
     $evaluate:process-word: {
-      # if curr-text is an operator, perform it
+      # if curr-stream is an operator, perform it
       {
-        var is-add?/eax: boolean <- stream-data-equal? curr-text, "+"
+        var is-add?/eax: boolean <- stream-data-equal? curr-stream, "+"
         compare is-add?, 0
         break-if-=
         var _b/eax: int <- pop-int-stack out
@@ -27,7 +27,7 @@ fn evaluate defs: (addr handle function), bindings: (addr table), scratch: (addr
         break $evaluate:process-word
       }
       {
-        var is-sub?/eax: boolean <- stream-data-equal? curr-text, "-"
+        var is-sub?/eax: boolean <- stream-data-equal? curr-stream, "-"
         compare is-sub?, 0
         break-if-=
         var _b/eax: int <- pop-int-stack out
@@ -38,7 +38,7 @@ fn evaluate defs: (addr handle function), bindings: (addr table), scratch: (addr
         break $evaluate:process-word
       }
       {
-        var is-mul?/eax: boolean <- stream-data-equal? curr-text, "*"
+        var is-mul?/eax: boolean <- stream-data-equal? curr-stream, "*"
         compare is-mul?, 0
         break-if-=
         var _b/eax: int <- pop-int-stack out
@@ -48,20 +48,42 @@ fn evaluate defs: (addr handle function), bindings: (addr table), scratch: (addr
         push-int-stack out, a
         break $evaluate:process-word
       }
-      # if curr-text is a known function name, call it appropriately
+      # if curr-stream is a known function name, call it appropriately
       {
         var callee-h: (handle function)
         var callee-ah/eax: (addr handle function) <- address callee-h
-        find-function defs, curr-text, callee-ah
+        find-function defs, curr-stream, callee-ah
         var callee/eax: (addr function) <- lookup *callee-ah
         compare callee, 0
         break-if-=
         perform-call callee, out, defs
         break $evaluate:process-word
       }
-      # otherwise it's an int
+      # if it's a name, push its value
       {
-        var n/eax: int <- parse-decimal-int-from-stream curr-text
+        compare bindings, 0
+        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
+        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
+        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
       }
     }
@@ -102,7 +124,7 @@ fn perform-call _callee: (addr function), caller-stack: (addr int-stack), defs:
   # create bindings for args
   var table-storage: table
   var table/esi: (addr table) <- address table-storage
-  initialize-table table
+  initialize-table table, 0x10
   #
   var curr-arg-ah/eax: (addr handle word) <- get callee, args
   var curr-arg/eax: (addr word) <- lookup *curr-arg-ah
@@ -115,7 +137,13 @@ fn perform-call _callee: (addr function), caller-stack: (addr int-stack), defs:
     # create binding
     word-to-string curr-arg, curr-key
     {
+#?       var tmp/eax: (addr array byte) <- lookup *curr-key
+#?       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
+#?       print-int32-decimal-to-real-screen curr-val
+#?       print-string-to-real-screen "\n"
       bind-int-in-table table, curr-key, curr-val
     }
     #
diff --git a/apps/tile/table.mu b/apps/tile/table.mu
index 851f891c..53fb5ce7 100644
--- a/apps/tile/table.mu
+++ b/apps/tile/table.mu
@@ -1,7 +1,7 @@
-fn initialize-table _self: (addr table) {
+fn initialize-table _self: (addr table), n: int {
   var self/esi: (addr table) <- copy _self
   var data-ah/eax: (addr handle array bind) <- get self, data
-  populate data-ah, 0x10
+  populate data-ah, n
 }
 
 fn bind-int-in-table _self: (addr table), key: (addr handle array byte), val: int {
@@ -45,3 +45,38 @@ fn make-binding _self: (addr bind), key: (addr handle array byte), _val: int {
   var val/ecx: int <- copy _val
   copy-to *dest3, 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 {
+  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->=
+    {
+      var offset/edx: (offset bind) <- compute-offset data, i
+      var target-bind/esi: (addr bind) <- index data, offset
+      var target2/edx: (addr handle array byte) <- get target-bind, key
+      var target3/eax: (addr array byte) <- lookup *target2
+      compare target3, 0
+      break-if-= $lookup-binding:loop
+      var is-match?/eax: boolean <- string-equal? target3, key
+      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
+      break $lookup-binding:loop
+    }
+    i <- increment
+    loop
+  }
+}