about summary refs log tree commit diff stats
path: root/apps/tile
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2020-10-26 09:27:32 -0700
committerKartik Agaram <vc@akkartik.com>2020-10-26 09:27:32 -0700
commit7c9b650d27358a47ef7bcfd9a293f21e0dcb8a5f (patch)
tree77ff81ad2ceafe23c7cc92892db203d3e3c75ca9 /apps/tile
parent475da72c614ddee250c9542f23e81b6112b0efb8 (diff)
downloadmu-7c9b650d27358a47ef7bcfd9a293f21e0dcb8a5f.tar.gz
7110
Some more helpers that I want to avoid using, but they help me gain confidence
in the current implementation of file handles. Manual test:

  "x" open dup read swap read

Assumes there's a file called `x` in the current directory that contains
at least two (short!) lines.
Diffstat (limited to 'apps/tile')
-rw-r--r--apps/tile/rpn.mu54
1 files changed, 54 insertions, 0 deletions
diff --git a/apps/tile/rpn.mu b/apps/tile/rpn.mu
index d4e19a85..4f180b38 100644
--- a/apps/tile/rpn.mu
+++ b/apps/tile/rpn.mu
@@ -215,6 +215,60 @@ fn evaluate functions: (addr handle function), bindings: (addr table), scratch:
         perform-call callee, out, functions
         break $evaluate:process-word
       }
+      # HACKS: we're trying to avoid turning this into Forth
+      {
+        var is-dup?/eax: boolean <- stream-data-equal? curr-stream, "dup"
+        compare is-dup?, 0
+        break-if-=
+        # read src-val from out
+        var out2/esi: (addr value-stack) <- copy out
+        var top-addr/ecx: (addr int) <- get out2, top
+        compare *top-addr, 0
+        break-if-<=
+        var data-ah/eax: (addr handle array value) <- get out2, data
+        var data/eax: (addr array value) <- lookup *data-ah
+        var top/ecx: int <- copy *top-addr
+        top <- decrement
+        var offset/edx: (offset value) <- compute-offset data, top
+        var src-val/edx: (addr value) <- index data, offset
+        # push a copy of it
+        top <- increment
+        var offset/ebx: (offset value) <- compute-offset data, top
+        var target-val/ebx: (addr value) <- index data, offset
+        copy-object src-val, target-val
+        # commit
+        var top-addr/ecx: (addr int) <- get out2, top
+        increment *top-addr
+        break $evaluate:process-word
+      }
+      {
+        var is-swap?/eax: boolean <- stream-data-equal? curr-stream, "swap"
+        compare is-swap?, 0
+        break-if-=
+        # read top-val from out
+        var out2/esi: (addr value-stack) <- copy out
+        var top-addr/ecx: (addr int) <- get out2, top
+        compare *top-addr, 0
+        break-if-<=
+        var data-ah/eax: (addr handle array value) <- get out2, data
+        var data/eax: (addr array value) <- lookup *data-ah
+        var top/ecx: int <- copy *top-addr
+        top <- decrement
+        var offset/edx: (offset value) <- compute-offset data, top
+        var top-val/edx: (addr value) <- index data, offset
+        # read next val from out
+        top <- decrement
+        var offset/ebx: (offset value) <- compute-offset data, top
+        var pen-top-val/ebx: (addr value) <- index data, offset
+        # swap
+        var tmp: value
+        var tmp-a/eax: (addr value) <- address tmp
+        copy-object top-val, tmp-a
+        copy-object pen-top-val, top-val
+        copy-object tmp-a, pen-top-val
+        break $evaluate:process-word
+      }
+      # END HACKS
       # if it's a name, push its value
       {
         compare bindings, 0