about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2020-10-05 22:21:27 -0700
committerKartik Agaram <vc@akkartik.com>2020-10-05 22:21:27 -0700
commite41bc160a0dfee0c38ecf20b20ddaf7e6f3da408 (patch)
tree84022ff933074dbc56027348990ed175f48c6565
parenta9e56c46c6e2d9a6c89e0b4ab16bd5c2ae9cb3da (diff)
downloadmu-e41bc160a0dfee0c38ecf20b20ddaf7e6f3da408.tar.gz
6967
Function expand/contract still works, but the implementation is totally
different under the hood.
-rw-r--r--apps/tile/data.mu72
-rw-r--r--apps/tile/environment.mu59
2 files changed, 116 insertions, 15 deletions
diff --git a/apps/tile/data.mu b/apps/tile/data.mu
index 52f2a8c4..5c54f6f5 100644
--- a/apps/tile/data.mu
+++ b/apps/tile/data.mu
@@ -1,7 +1,11 @@
 type sandbox {
   setup: (handle line)
   data: (handle line)
+  # display data
   cursor-word: (handle word)
+  cursor-word-index: int
+  expanded-words: (handle call-path)
+  #
   next: (handle sandbox)
   prev: (handle sandbox)
 }
@@ -27,8 +31,7 @@ type word {
   scalar-data: (handle gap-buffer)
   text-data: (handle array byte)
   box-data: (handle line)  # recurse
-  # other metadata attached to this word
-  display-subsidiary-stack?: boolean
+  #
   next: (handle word)
   prev: (handle word)
 }
@@ -49,6 +52,13 @@ type bind {
   value: (handle value)  # I'd inline this but we sometimes want to return a specific value from a table
 }
 
+# A call-path is a data structure that can unambiguously refer to any specific
+# call arbitrarily deep inside the call hierarchy of a program.
+type call-path {
+  data: int
+  next: (handle call-path)
+}
+
 type result {
   data: value-stack
   error: (handle array byte)  # single error message for now
@@ -184,3 +194,61 @@ fn populate-text-with _out: (addr handle array byte), _in: (addr array byte) {
     loop
   }
 }
+
+fn find-in-call-path in: (addr handle call-path), _needle: int -> result/eax: boolean {
+$find-in-call-path:body: {
+  var curr-ah/esi: (addr handle call-path) <- copy in
+  var needle/ebx: int <- copy _needle
+  {
+    var curr/eax: (addr call-path) <- lookup *curr-ah
+    compare curr, 0
+    break-if-=
+    var curr-n/ecx: (addr int) <- get curr, data
+    compare needle, *curr-n
+    {
+      break-if-!=
+      result <- copy 1  # true
+      break $find-in-call-path:body
+    }
+    curr-ah <- get curr, next
+    loop
+  }
+  result <- copy 0  # false
+}
+}
+
+# order is irrelevant
+fn insert-in-call-path list: (addr handle call-path), _n: int {
+  var new-path-storage: (handle call-path)
+  var new-path-ah/edi: (addr handle call-path) <- address new-path-storage
+  allocate new-path-ah
+  var new-path/eax: (addr call-path) <- lookup *new-path-ah
+  var next/ecx: (addr handle call-path) <- get new-path, next
+  copy-object list, next
+  var data/ecx: (addr int) <- get new-path, data
+  var n/edx: int <- copy _n
+  copy-to *data, n
+  copy-object new-path-ah, list
+}
+
+fn delete-in-call-path list: (addr handle call-path), _n: int {
+$delete-in-call-path:body: {
+  var curr-ah/esi: (addr handle call-path) <- copy list
+  var n/ebx: int <- copy _n
+  $delete-in-call-path:loop: {
+    var curr/eax: (addr call-path) <- lookup *curr-ah
+    compare curr, 0
+    break-if-=
+    var curr-n/ecx: (addr int) <- get curr, data
+    compare n, *curr-n
+    {
+      break-if-!=
+      var next-ah/ecx: (addr handle call-path) <- get curr, next
+      copy-object next-ah, curr-ah
+      loop $delete-in-call-path:loop
+    }
+    curr-ah <- get curr, next
+    loop
+  }
+}
+}
diff --git a/apps/tile/environment.mu b/apps/tile/environment.mu
index 2e7ae970..deb66a0d 100644
--- a/apps/tile/environment.mu
+++ b/apps/tile/environment.mu
@@ -59,7 +59,8 @@ fn process _self: (addr environment), key: grapheme {
 $process:body: {
     var self/esi: (addr environment) <- copy _self
     var sandbox-ah/eax: (addr handle sandbox) <- get self, sandboxes
-    var sandbox/eax: (addr sandbox) <- lookup *sandbox-ah
+    var _sandbox/eax: (addr sandbox) <- lookup *sandbox-ah
+    var sandbox/esi: (addr sandbox) <- copy _sandbox
     var cursor-word-ah/edi: (addr handle word) <- get sandbox, cursor-word
     var _cursor-word/eax: (addr word) <- lookup *cursor-word-ah
     var cursor-word/ecx: (addr word) <- copy _cursor-word
@@ -75,13 +76,15 @@ $process:body: {
         break $process:body
       }
       # otherwise, move to end of prev word
-      var prev-word-ah/esi: (addr handle word) <- get cursor-word, prev
+      var prev-word-ah/edx: (addr handle word) <- get cursor-word, prev
       var prev-word/eax: (addr word) <- lookup *prev-word-ah
       {
         compare prev-word, 0
         break-if-=
         copy-object prev-word-ah, cursor-word-ah
         cursor-to-end prev-word
+        var cursor-word-index/eax: (addr int) <- get sandbox, cursor-word-index
+        decrement *cursor-word-index
       }
       break $process:body
     }
@@ -97,13 +100,15 @@ $process:body: {
         break $process:body
       }
       # otherwise, move to start of next word
-      var next-word-ah/esi: (addr handle word) <- get cursor-word, next
+      var next-word-ah/edx: (addr handle word) <- get cursor-word, next
       var next-word/eax: (addr word) <- lookup *next-word-ah
       {
         compare next-word, 0
         break-if-=
         copy-object next-word-ah, cursor-word-ah
         cursor-to-start next-word
+        var cursor-word-index/eax: (addr int) <- get sandbox, cursor-word-index
+        increment *cursor-word-index
       }
       break $process:body
     }
@@ -119,7 +124,7 @@ $process:body: {
         break $process:body
       }
       # otherwise delete current word and move to end of prev word
-      var prev-word-ah/esi: (addr handle word) <- get cursor-word, prev
+      var prev-word-ah/edx: (addr handle word) <- get cursor-word, prev
       var prev-word/eax: (addr word) <- lookup *prev-word-ah
       {
         compare prev-word, 0
@@ -127,6 +132,8 @@ $process:body: {
         copy-object prev-word-ah, cursor-word-ah
         cursor-to-end prev-word
         delete-next prev-word
+        var cursor-word-index/eax: (addr int) <- get sandbox, cursor-word-index
+        decrement *cursor-word-index
       }
       break $process:body
     }
@@ -137,16 +144,15 @@ $process:body: {
       append-word cursor-word-ah
       var next-word-ah/ecx: (addr handle word) <- get cursor-word, next
       copy-object next-word-ah, cursor-word-ah
+      var cursor-word-index/eax: (addr int) <- get sandbox, cursor-word-index
+      increment *cursor-word-index
       break $process:body
     }
     compare key, 0xa  # enter
     {
       break-if-!=
       # toggle display of subsidiary stack
-      var display-subsidiary-stack?/eax: (addr boolean) <- get cursor-word, display-subsidiary-stack?
-      var tmp/ecx: int <- copy 1
-      tmp <- subtract *display-subsidiary-stack?
-      copy-to *display-subsidiary-stack?, tmp
+      toggle-cursor-word sandbox
       break $process:body
     }
     # otherwise insert key within current word
@@ -162,6 +168,27 @@ $process:body: {
 }
 }
 
+fn toggle-cursor-word _sandbox: (addr sandbox) {
+$toggle-cursor-word:body: {
+  var sandbox/esi: (addr sandbox) <- copy _sandbox
+  var expanded-words/edi: (addr handle call-path) <- get sandbox, expanded-words
+  var cursor-word-index/ecx: (addr int) <- get sandbox, cursor-word-index
+  var already-expanded?/eax: boolean <- find-in-call-path expanded-words, *cursor-word-index
+  compare already-expanded?, 0  # false
+  {
+    break-if-!=
+    # if not already-expanded, insert
+    insert-in-call-path expanded-words *cursor-word-index
+    break $toggle-cursor-word:body
+  }
+  {
+    break-if-=
+    # otherwise delete
+    delete-in-call-path expanded-words *cursor-word-index
+  }
+}
+}
+
 fn evaluate-environment _env: (addr environment), stack: (addr value-stack) {
   var env/esi: (addr environment) <- copy _env
   # functions
@@ -196,6 +223,8 @@ fn render _env: (addr environment) {
 
 fn render-sandbox screen: (addr screen), functions: (addr handle function), bindings: (addr table), _sandbox: (addr sandbox), top-row: int, left-col: int {
   var sandbox/esi: (addr sandbox) <- copy _sandbox
+  # expanded-words
+  var expanded-words/edi: (addr handle call-path) <- get sandbox, expanded-words
   # line
   var line-ah/eax: (addr handle line) <- get sandbox, data
   var _line/eax: (addr line) <- lookup *line-ah
@@ -208,11 +237,11 @@ fn render-sandbox screen: (addr screen), functions: (addr handle function), bind
   var cursor-col: int
   var cursor-col-a/eax: (addr int) <- address cursor-col
   #
-  var dummy/ecx: int <- render-line screen, functions, 0, line, 3, left-col, cursor-word, cursor-col-a  # input-row=3
+  var dummy/ecx: int <- render-line screen, functions, 0, line, expanded-words, 3, left-col, cursor-word, cursor-col-a  # input-row=3
   move-cursor screen, 3, cursor-col  # input-row
 }
 
-fn render-line screen: (addr screen), functions: (addr handle function), bindings: (addr table), _line: (addr line), top-row: int, left-col: int, cursor-word: (addr word), cursor-col-a: (addr int) -> right-col/ecx: int {
+fn render-line screen: (addr screen), functions: (addr handle function), bindings: (addr table), _line: (addr line), expanded-words: (addr handle call-path), top-row: int, left-col: int, cursor-word: (addr word), cursor-col-a: (addr int) -> right-col/ecx: int {
   # curr-word
   var line/esi: (addr line) <- copy _line
   var first-word-ah/eax: (addr handle word) <- get line, data
@@ -228,8 +257,12 @@ fn render-line screen: (addr screen), functions: (addr handle function), binding
     # if necessary, first render columns for subsidiary stack
     $render-line:subsidiary: {
       {
-        var display-subsidiary-stack?/eax: (addr boolean) <- get curr-word, display-subsidiary-stack?
-        compare *display-subsidiary-stack?, 0  # false
+        # can't expand subsidiary stacks for now
+        compare bindings, 0
+        break-if-!= $render-line:subsidiary
+        #
+        var display-subsidiary-stack?/eax: boolean <- find-in-call-path expanded-words, word-index
+        compare display-subsidiary-stack?, 0  # false
         break-if-= $render-line:subsidiary
       }
       # does function exist?
@@ -274,7 +307,7 @@ fn render-line screen: (addr screen), functions: (addr handle function), binding
       var callee-body-ah/eax: (addr handle line) <- get callee, body
       var callee-body/eax: (addr line) <- lookup *callee-body-ah
       # - render subsidiary stack
-      curr-col <- render-line screen, functions, callee-bindings, callee-body, top-row, curr-col, cursor-word, cursor-col-a
+      curr-col <- render-line screen, functions, callee-bindings, callee-body, 0, top-row, curr-col, cursor-word, cursor-col-a
       #
       move-cursor screen, top-row, curr-col
       print-code-point screen, 0x21d7  # ⇗