diff options
author | Kartik Agaram <vc@akkartik.com> | 2020-10-26 21:56:00 -0700 |
---|---|---|
committer | Kartik Agaram <vc@akkartik.com> | 2020-10-26 21:56:47 -0700 |
commit | f3d1929033856ac12db84435c317c5a288f898b3 (patch) | |
tree | 2f612a537a55d9a2d234354f0d98f7562ee357c7 | |
parent | 2ddfdf191c8c1f8be1bab5f5aad76b610922b444 (diff) | |
download | mu-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.mu | 6 | ||||
-rw-r--r-- | apps/tile/rpn.mu | 36 |
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 |