about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2020-10-26 21:56:00 -0700
committerKartik Agaram <vc@akkartik.com>2020-10-26 21:56:47 -0700
commitf3d1929033856ac12db84435c317c5a288f898b3 (patch)
tree2f612a537a55d9a2d234354f0d98f7562ee357c7
parent2ddfdf191c8c1f8be1bab5f5aad76b610922b444 (diff)
downloadmu-f3d1929033856ac12db84435c317c5a288f898b3.tar.gz
7119 - tile: new primitive to slurp file contents
Stack display is messed up when file contents contain newlines. Ignoring
that for now.
-rw-r--r--apps/tile/environment.mu6
-rw-r--r--apps/tile/rpn.mu36
2 files changed, 41 insertions, 1 deletions
diff --git a/apps/tile/environment.mu b/apps/tile/environment.mu
index cb36a4ca..230fc1be 100644
--- a/apps/tile/environment.mu
+++ b/apps/tile/environment.mu
@@ -786,6 +786,10 @@ fn bound-function? w: (addr word), functions-ah: (addr handle function) -> resul
   subresult <- word-equal? w, "read"
   compare subresult, 0  # false
   break-if-!=
+  # if w == "slurp" return true
+  subresult <- word-equal? w, "slurp"
+  compare subresult, 0  # false
+  break-if-!=
   # if w == "dup" return true
   subresult <- word-equal? w, "dup"
   compare subresult, 0  # false
@@ -1554,7 +1558,7 @@ fn clear-canvas _env: (addr environment) {
   move-cursor screen, 2, start-col
   print-string screen, "+ - * len"
   move-cursor screen, 3, start-col
-  print-string screen, "open read"
+  print-string screen, "open read slurp"
   move-cursor screen, 4, start-col
   print-string screen, "dup swap"
   # currently defined functions
diff --git a/apps/tile/rpn.mu b/apps/tile/rpn.mu
index 641350a6..7b65b71c 100644
--- a/apps/tile/rpn.mu
+++ b/apps/tile/rpn.mu
@@ -170,6 +170,42 @@ fn evaluate functions: (addr handle function), bindings: (addr table), scratch:
         copy-handle empty, target-file-ah
         break $evaluate:process-word
       }
+      {
+        var is-slurp?/eax: boolean <- stream-data-equal? curr-stream, "slurp"
+        compare is-slurp?, 0
+        break-if-=
+        # pop target-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/edx: int <- copy *top-addr
+        top <- decrement
+        var dest-offset/edx: (offset value) <- compute-offset data, top
+        var target-val/edx: (addr value) <- index data, dest-offset
+        # check target-val is a file
+        var target-type-addr/eax: (addr int) <- get target-val, type
+        compare *target-type-addr, 3  # file
+        break-if-!=
+        # slurp all contents from file and save in target-val
+        # read target-val as a filename and save the handle in target-val
+        var file-ah/eax: (addr handle buffered-file) <- get target-val, file-data
+        var file/eax: (addr buffered-file) <- lookup *file-ah
+        var s: (stream byte 0x100)
+        var s-addr/ecx: (addr stream byte) <- address s
+        slurp file, s-addr
+        var target/eax: (addr handle array byte) <- get target-val, text-data
+        stream-to-array s-addr, target
+        # save result into target-val
+        var type-addr/eax: (addr int) <- get target-val, type
+        copy-to *type-addr, 1  # string
+        var target-file-ah/eax: (addr handle buffered-file) <- get target-val, file-data
+        var empty: (handle buffered-file)
+        copy-handle empty, target-file-ah
+        break $evaluate:process-word
+      }
       # if curr-stream defines a binding, save top of stack to bindings
       {
         var done?/eax: boolean <- stream-empty? curr-stream