about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--310copy-bytes.subx58
-rw-r--r--400.mu1
-rw-r--r--apps/tile/environment.mu8
-rw-r--r--apps/tile/gap-buffer.mu7
-rw-r--r--apps/tile/rpn.mu73
-rw-r--r--apps/tile/table.mu10
-rw-r--r--apps/tile/word.mu7
7 files changed, 152 insertions, 12 deletions
diff --git a/310copy-bytes.subx b/310copy-bytes.subx
index f33388a9..7a90495b 100644
--- a/310copy-bytes.subx
+++ b/310copy-bytes.subx
@@ -55,3 +55,61 @@ $copy-bytes:end:
     89/<- %esp 5/r32/ebp
     5d/pop-to-ebp
     c3/return
+
+stream-to-string:  # in: (addr stream _), out: (addr handle array _)
+    # . prologue
+    55/push-ebp
+    89/<- %ebp 4/r32/esp
+    # . save registers
+    50/push-eax
+    51/push-ecx
+    52/push-edx
+    56/push-esi
+    # esi = s
+    8b/-> *(ebp+8) 6/r32/esi
+    # var len/ecx: int = s->write - s->read
+    8b/-> *esi 1/r32/ecx
+    2b/subtract *(esi+4) 1/r32/ecx
+    # allocate
+    (allocate-array Heap %ecx *(ebp+0xc))
+    # var in/edx: (addr byte) = s->data + s->read
+    8b/-> *(esi+4) 2/r32/edx
+    8d/copy-address *(esi+edx+0xc) 2/r32/edx
+    # var dest/eax: (addr byte) = data for out
+    8b/-> *(ebp+0xc) 0/r32/eax
+    (lookup *eax *(eax+4))  # => eax
+    8d/copy-address *(eax+4) 0/r32/eax
+    #
+    (copy-bytes %edx %eax %ecx)
+$stream-to-string:end:
+    # . restore registers
+    5e/pop-to-esi
+    5a/pop-to-edx
+    59/pop-to-ecx
+    58/pop-to-eax
+    # . epilogue
+    89/<- %esp 5/r32/ebp
+    5d/pop-to-ebp
+    c3/return
+
+test-stream-to-string:
+    # . prologue
+    55/push-ebp
+    89/<- %ebp 4/r32/esp
+    # setup
+    (clear-stream _test-input-stream)
+    (write _test-input-stream "abc")
+    # skip something
+    (read-byte _test-input-stream)  # => eax
+    # var out/ecx: (handle array byte)
+    68/push 0/imm32
+    68/push 0/imm32
+    89/<- %ecx 4/r32/esp
+    #
+    (stream-to-string _test-input-stream %ecx)
+    (lookup *ecx *(ecx+4))  # => eax
+    (check-strings-equal %eax "bc")
+    # . epilogue
+    89/<- %esp 5/r32/ebp
+    5d/pop-to-ebp
+    c3/return
diff --git a/400.mu b/400.mu
index b51d111f..9676f283 100644
--- a/400.mu
+++ b/400.mu
@@ -173,5 +173,6 @@ sig new-buffered-file out: (addr handle buffered-file)
 
 sig stream-empty? s: (addr stream _) -> result/eax: boolean
 sig stream-full? s: (addr stream _) -> result/eax: boolean
+sig stream-to-string in: (addr stream _), out: (addr handle array _)
 
 sig copy-bytes src: (addr byte), dest: (addr byte), n: int
diff --git a/apps/tile/environment.mu b/apps/tile/environment.mu
index 200aed98..4caa37f1 100644
--- a/apps/tile/environment.mu
+++ b/apps/tile/environment.mu
@@ -177,9 +177,7 @@ fn render _env: (addr environment) {
   var _program/eax: (addr program) <- lookup *program-ah
   var program/esi: (addr program) <- copy _program
   # defs
-  var defs-ah/edx: (addr handle function) <- get program, defs
-  var _defs/eax: (addr function) <- lookup *defs-ah
-  var defs/edx: (addr function) <- copy _defs
+  var defs/edx: (addr handle function) <- get program, defs
   # line
   var sandbox-ah/esi: (addr handle sandbox) <- get program, sandboxes
   var sandbox/eax: (addr sandbox) <- lookup *sandbox-ah
@@ -194,7 +192,7 @@ fn render _env: (addr environment) {
   move-cursor screen, 3, cursor-col  # input-row
 }
 
-fn render-line screen: (addr screen), defs: (addr function), bindings: (addr table), _line: (addr line), top-row: int, left-col: int, cursor-word: (addr word), cursor-col-a: (addr int) {
+fn render-line screen: (addr screen), defs: (addr handle function), bindings: (addr table), _line: (addr line), top-row: int, left-col: int, cursor-word: (addr word), cursor-col-a: (addr int) {
   # curr-word
   var line/esi: (addr line) <- copy _line
   var first-word-ah/eax: (addr handle word) <- get line, data
@@ -222,7 +220,7 @@ fn render-line screen: (addr screen), defs: (addr function), bindings: (addr tab
 # - Return the farthest column written.
 # - If final-word is same as cursor-word, do some additional computation to set
 #   cursor-col-a.
-fn render-column screen: (addr screen), defs: (addr function), bindings: (addr table), scratch: (addr line), final-word: (addr word), top-row: int, left-col: int, cursor-word: (addr word), cursor-col-a: (addr int) -> right-col/ecx: int {
+fn render-column screen: (addr screen), defs: (addr handle function), bindings: (addr table), scratch: (addr line), final-word: (addr word), top-row: int, left-col: int, cursor-word: (addr word), cursor-col-a: (addr int) -> right-col/ecx: int {
   var max-width/ecx: int <- copy 0
   {
     # render stack for all but final column
diff --git a/apps/tile/gap-buffer.mu b/apps/tile/gap-buffer.mu
index f4f866a4..47417b96 100644
--- a/apps/tile/gap-buffer.mu
+++ b/apps/tile/gap-buffer.mu
@@ -27,6 +27,13 @@ fn initialize-gap-buffer-with self: (addr gap-buffer), s: (addr array byte) {
   }
 }
 
+fn gap-buffer-to-string self: (addr gap-buffer), out: (addr handle array byte) {
+  var s-storage: (stream byte 0x100)
+  var s/ecx: (addr stream byte) <- address s-storage
+  emit-gap-buffer self, s
+  stream-to-string s, out
+}
+
 fn emit-gap-buffer _self: (addr gap-buffer), out: (addr stream byte) {
   var self/esi: (addr gap-buffer) <- copy _self
   clear-stream out
diff --git a/apps/tile/rpn.mu b/apps/tile/rpn.mu
index 83f6e909..417bc9a0 100644
--- a/apps/tile/rpn.mu
+++ b/apps/tile/rpn.mu
@@ -1,4 +1,4 @@
-fn evaluate defs: (addr function), bindings: (addr table), scratch: (addr line), end: (addr word), out: (addr int-stack) {
+fn evaluate defs: (addr handle function), bindings: (addr table), scratch: (addr line), end: (addr word), out: (addr int-stack) {
   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
@@ -46,8 +46,16 @@ fn evaluate defs: (addr function), bindings: (addr table), scratch: (addr line),
         push-int-stack out, a
         break $evaluate:process-word
       }
-      # HERE: if curr-text is a known function name, call it appropriately
+      # if curr-text 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
+        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
       {
@@ -66,6 +74,67 @@ fn evaluate defs: (addr function), bindings: (addr table), scratch: (addr line),
   }
 }
 
+fn find-function first: (addr handle function), name: (addr stream byte), out: (addr handle function) {
+  var curr/esi: (addr handle function) <- copy first
+  $find-function:loop: {
+    var _f/eax: (addr function) <- lookup *curr
+    var f/ecx: (addr function) <- copy _f
+    compare f, 0
+    break-if-=
+    var curr-name-ah/eax: (addr handle array byte) <- get f, name
+    var curr-name/eax: (addr array byte) <- lookup *curr-name-ah
+    var done?/eax: boolean <- stream-data-equal? name, curr-name
+    compare done?, 0  # false
+    {
+      break-if-=
+      copy-handle *curr, out
+      break $find-function:loop
+    }
+    curr <- get f, next
+    loop
+  }
+}
+
+fn perform-call _callee: (addr function), caller-stack: (addr int-stack), defs: (addr handle function) {
+  var callee/ecx: (addr function) <- copy _callee
+  # create bindings for args
+  var table-storage: table
+  var table/esi: (addr table) <- address table-storage
+  initialize-table table
+  #
+  var curr-arg-ah/eax: (addr handle word) <- get callee, args
+  var curr-arg/eax: (addr word) <- lookup *curr-arg-ah
+  #
+  var curr-key-storage: (handle array byte)
+  var curr-key/edx: (addr handle array byte) <- address curr-key-storage
+  {
+    compare curr-arg, 0
+    break-if-=
+    # create binding
+    word-to-string curr-arg, curr-key
+    {
+      var curr-val/eax: int <- pop-int-stack caller-stack
+      bind-int-in-table table, curr-key, curr-val
+    }
+    #
+    var next-arg-ah/edx: (addr handle word) <- get curr-arg, next
+    curr-arg <- lookup *next-arg-ah
+    loop
+  }
+  # obtain body
+  var body-ah/eax: (addr handle line) <- get callee, body
+  var body/eax: (addr line) <- lookup *body-ah
+  # perform call
+  var stack-storage: int-stack
+  var stack/edi: (addr int-stack) <- address stack-storage
+      print-string-to-real-screen "about to enter recursive eval\n"
+  evaluate defs, table, body, 0, stack
+      print-string-to-real-screen "exited recursive eval\n"
+  # stitch result from stack into caller
+  var result/eax: int <- pop-int-stack stack
+  push-int-stack caller-stack, result
+}
+
 # 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 {
diff --git a/apps/tile/table.mu b/apps/tile/table.mu
index 94f3299a..851f891c 100644
--- a/apps/tile/table.mu
+++ b/apps/tile/table.mu
@@ -1,10 +1,10 @@
-fn initialize-table _self: (address table) {
+fn initialize-table _self: (addr table) {
   var self/esi: (addr table) <- copy _self
   var data-ah/eax: (addr handle array bind) <- get self, data
   populate data-ah, 0x10
 }
 
-fn bind-int-in-table _self: (addr table), key: (addr array byte), val: int {
+fn bind-int-in-table _self: (addr table), key: (addr handle array byte), val: int {
   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
@@ -15,7 +15,7 @@ fn bind-int-in-table _self: (addr table), key: (addr array byte), val: int {
 }
 
 # manual test: full array of binds
-fn next-empty-slot _data: (addr array bind), key: (addr array byte) -> result/eax: (offset bind) {
+fn next-empty-slot _data: (addr array bind), key: (addr handle array byte) -> result/eax: (offset bind) {
   var data/esi: (addr array bind) <- copy _data
   var len/ecx: int <- length data
   var i/edx: int <- copy 0
@@ -36,10 +36,10 @@ fn next-empty-slot _data: (addr array bind), key: (addr array byte) -> result/ea
   }
 }
 
-fn make-binding _self: (addr bind), key: (addr array byte), _val: int {
+fn make-binding _self: (addr bind), key: (addr handle array byte), _val: int {
   var self/esi: (addr bind) <- copy _self
   var dest/eax: (addr handle array byte) <- get self, key
-  populate-text-with dest, key
+  copy-object key, dest
   var dest2/eax: (addr value) <- get self, value
   var dest3/eax: (addr int) <- get dest2, scalar-data
   var val/ecx: int <- copy _val
diff --git a/apps/tile/word.mu b/apps/tile/word.mu
index 8016a496..b425868e 100644
--- a/apps/tile/word.mu
+++ b/apps/tile/word.mu
@@ -225,3 +225,10 @@ fn emit-word _self: (addr word), out: (addr stream byte) {
   var data/eax: (addr gap-buffer) <- lookup *data-ah
   emit-gap-buffer data, out
 }
+
+fn word-to-string _self: (addr word), out: (addr handle array byte) {
+  var self/esi: (addr word) <- copy _self
+  var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
+  var data/eax: (addr gap-buffer) <- lookup *data-ah
+  gap-buffer-to-string data, out
+}