about summary refs log tree commit diff stats
path: root/baremetal/shell
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2021-02-14 13:20:37 -0800
committerKartik K. Agaram <vc@akkartik.com>2021-02-14 13:20:37 -0800
commit1a9d3cb7efa84c0399fc852b93021eff89195d9d (patch)
treec502e0f7380006a880635ea5c298f27c37c8eb10 /baremetal/shell
parent90a8d404afcad67dd2ad87ed6241285149d3ca6e (diff)
downloadmu-1a9d3cb7efa84c0399fc852b93021eff89195d9d.tar.gz
7740 - baremetal/shell: eval and render line
Diffstat (limited to 'baremetal/shell')
-rw-r--r--baremetal/shell/line.mu81
-rw-r--r--baremetal/shell/value-stack.mu27
2 files changed, 108 insertions, 0 deletions
diff --git a/baremetal/shell/line.mu b/baremetal/shell/line.mu
index f3d8d261..f0831c36 100644
--- a/baremetal/shell/line.mu
+++ b/baremetal/shell/line.mu
@@ -83,3 +83,84 @@ fn parse-line in: (addr array byte), _out: (addr line) {
 #?   var line-addr/eax: (addr line) <- address line-storage
 #?   var dummy/eax: int <- render-line 0/screen, line-addr, 0/x, 0/y, 1/render-cursor
 #? }
+
+fn render-line-with-stack screen: (addr screen), _line: (addr line), x: int, y: int, render-cursor?: boolean -> _/eax: int, _/ecx: int {
+  var line/esi: (addr line) <- copy _line
+  # cursor-word
+  var cursor-word/edi: int <- copy 0
+  compare render-cursor?, 0/false
+  {
+    break-if-=
+    var cursor-word-ah/eax: (addr handle word) <- get line, cursor
+    var _cursor-word/eax: (addr word) <- lookup *cursor-word-ah
+    cursor-word <- copy _cursor-word
+  }
+  #
+  var curr-word-ah/eax: (addr handle word) <- get line, data
+  var _curr-word/eax: (addr word) <- lookup *curr-word-ah
+  var curr-word/edx: (addr word) <- copy _curr-word
+  var new-x/eax: int <- copy x  # increases each iteration
+  var new-y/ebx: int <- copy y  # compute max across all iterations
+  {
+    compare curr-word, 0
+    break-if-=
+    var curr-y/ecx: int <- copy 0
+    new-x, curr-y <- render-word-with-stack-and-cursor screen, line, curr-word, new-x, y, cursor-word
+    compare curr-y, new-y
+    {
+      break-if-<=
+      new-y <- copy curr-y
+    }
+    # update
+    var next-word-ah/eax: (addr handle word) <- get curr-word, next
+    var next-word/eax: (addr word) <- lookup *next-word-ah
+    curr-word <- copy next-word
+    loop
+  }
+  return new-x, new-y
+}
+
+fn render-word-with-stack-and-cursor screen: (addr screen), line: (addr line), curr-word: (addr word), x: int, y: int, _cursor-word-addr: int -> _/eax: int, _/ecx: int {
+  # print curr-word, with cursor if necessary
+  var render-cursor?/eax: boolean <- copy 0/false
+  var cursor-word-addr/ecx: int <- copy _cursor-word-addr
+  {
+    compare cursor-word-addr, curr-word
+    break-if-!=
+    render-cursor? <- copy 1/true
+  }
+  var new-x/eax: int <- render-word screen, curr-word, x, y, render-cursor?
+  var new-x-saved/edx: int <- copy new-x
+  add-to y, 1/word-stack-spacing
+  # compute stack until word
+  var stack-storage: value-stack
+  var stack/edi: (addr value-stack) <- address stack-storage
+  evaluate line, curr-word, stack
+  # render stack
+  var new-y/ecx: int <- copy 0
+  new-x, new-y <- render-value-stack screen, stack, x, y
+  compare new-x, new-x-saved
+  {
+    break-if-<=
+    new-x <- copy new-x-saved
+  }
+  return new-x, new-y
+}
+
+fn test-render-line-with-stack-singleton {
+  # line = [1]
+  var line-storage: line
+  var line/esi: (addr line) <- address line-storage
+  parse-line "1", line
+  # setup: screen
+  var screen-on-stack: screen
+  var screen/edi: (addr screen) <- address screen-on-stack
+  initialize-screen screen, 0x20, 4
+  #
+  var new-x/eax: int <- copy 0
+  var new-y/ecx: int <- copy 0
+  new-x, new-y <- render-line-with-stack screen, line, 0/x, 0/y, 0/no-cursor
+  check-screen-row screen, 0/y, "1  ", "F - test-render-line-with-stack-singleton/0"
+  check-screen-row screen, 1/y, " 1 ", "F - test-render-line-with-stack-singleton/1"
+  # not bothering to test hash colors for numbers
+}
diff --git a/baremetal/shell/value-stack.mu b/baremetal/shell/value-stack.mu
index e58d91d2..a422e9ff 100644
--- a/baremetal/shell/value-stack.mu
+++ b/baremetal/shell/value-stack.mu
@@ -180,3 +180,30 @@ fn dump-stack _self: (addr value-stack) {
     loop
   }
 }
+
+fn render-value-stack screen: (addr screen), _self: (addr value-stack), x: int, y: int -> _/eax: int, _/ecx: int {
+  var self/ecx: (addr value-stack) <- copy _self
+  var data-ah/eax: (addr handle array value) <- get self, data
+  var _data/eax: (addr array value) <- lookup *data-ah
+  var data/edi: (addr array value) <- copy _data
+  var top-addr/eax: (addr int) <- get self, top
+  var curr-idx/ecx: int <- copy *top-addr
+  curr-idx <- decrement
+  var new-x/edx: int <- copy 0
+  {
+    compare curr-idx, 0
+    break-if-<
+    var dest-offset/eax: (offset value) <- compute-offset data, curr-idx
+    var curr/eax: (addr value) <- index data, dest-offset
+    var curr-x/eax: int <- render-value screen, curr, x, y, 1/top-level
+    {
+      compare curr-x, new-x
+      break-if-<=
+      new-x <- copy curr-x
+    }
+    curr-idx <- decrement
+    increment y
+    loop
+  }
+  return new-x, y
+}