about summary refs log tree commit diff stats
path: root/baremetal
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2021-02-10 22:11:54 -0800
committerKartik K. Agaram <vc@akkartik.com>2021-02-10 22:11:54 -0800
commitd4afe371f513989a2ec6f6f6868d96300142654b (patch)
tree31e7baae182b02cdd8ebdf94f95bc454e5020db2 /baremetal
parent07852ae00f655ba74ee0f6916190192cf918dbc3 (diff)
downloadmu-d4afe371f513989a2ec6f6f6868d96300142654b.tar.gz
7711 - baremetal/shell: line data structure
Pretty thin; perhaps we should put cursor management in words. But we don't
need every node in the list of words to know which word in the list the
cursor is at.
Diffstat (limited to 'baremetal')
-rw-r--r--baremetal/shell/line.mu78
-rw-r--r--baremetal/shell/word.mu102
2 files changed, 176 insertions, 4 deletions
diff --git a/baremetal/shell/line.mu b/baremetal/shell/line.mu
new file mode 100644
index 00000000..70b0184c
--- /dev/null
+++ b/baremetal/shell/line.mu
@@ -0,0 +1,78 @@
+type line {
+  name: (handle array byte)
+  data: (handle word)
+  cursor: (handle word)
+  next: (handle line)
+  prev: (handle line)
+}
+
+# initialize line with a single empty word
+fn initialize-line _line: (addr line) {
+  var line/esi: (addr line) <- copy _line
+  var word-ah/eax: (addr handle word) <- get line, data
+  allocate word-ah
+  var word/eax: (addr word) <- lookup *word-ah
+  initialize-word word
+}
+
+fn num-words-in-line _in: (addr line) -> _/eax: int {
+  var in/esi: (addr line) <- copy _in
+  var curr-ah/ecx: (addr handle word) <- get in, data
+  var result/edi: int <- copy 0
+  {
+    var curr/eax: (addr word) <- lookup *curr-ah
+    compare curr, 0
+    break-if-=
+    curr-ah <- get curr, next
+    result <- increment
+    loop
+  }
+  return result
+}
+
+fn line-list-length lines: (addr handle line) -> _/eax: int {
+  var curr-ah/esi: (addr handle line) <- copy lines
+  var result/edi: int <- copy 0
+  {
+    var curr/eax: (addr line) <- lookup *curr-ah
+    compare curr, 0
+    break-if-=
+    curr-ah <- get curr, next
+    result <- increment
+    loop
+  }
+  return result
+}
+
+fn render-line screen: (addr screen), _line: (addr line), x: int, y: int, render-cursor?: boolean -> _/eax: int {
+  var line/eax: (addr line) <- copy _line
+  var first-word-ah/esi: (addr handle word) <- get line, data
+  # 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 result/eax: int <- render-words screen, first-word-ah, x, y, cursor-word
+  return result
+}
+
+#? fn main {
+#?   # line = [aaa, bbb, ccc, ddd]
+#?   var line-storage: line
+#?   var w-ah/eax: (addr handle word) <- get line-storage, data
+#?   allocate-word-with w-ah, "aaa"
+#?   append-word-at-end-with w-ah, "bbb"
+#?   append-word-at-end-with w-ah, "ccc"
+#?   append-word-at-end-with w-ah, "ddd"
+#?   var cursor-ah/ecx: (addr handle word) <- get line-storage, cursor
+#?   var w/eax: (addr word) <- lookup *w-ah
+#?   var next-ah/eax: (addr handle word) <- get w, next
+#?   copy-object next-ah, cursor-ah
+#?   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
+#? }
diff --git a/baremetal/shell/word.mu b/baremetal/shell/word.mu
index 44407b28..cb50b2fe 100644
--- a/baremetal/shell/word.mu
+++ b/baremetal/shell/word.mu
@@ -276,6 +276,101 @@ fn render-word screen: (addr screen), _self: (addr word), x: int, y: int, render
   return result
 }
 
+fn render-words screen: (addr screen), _words-ah: (addr handle word), x: int, y: int, cursor-word-addr: int -> _/eax: int {
+  var words-ah/eax: (addr handle word) <- copy _words-ah
+  var _words-a/eax: (addr word) <- lookup *words-ah
+  var words-a/ecx: (addr word) <- copy _words-a
+  compare words-a, 0
+  {
+    break-if-!=
+    return x
+  }
+  # print
+  var render-cursor?/edx: boolean <- copy 0/false
+  {
+    compare cursor-word-addr, words-a
+    break-if-!=
+    render-cursor? <- copy 1/true
+  }
+  var next-x/eax: int <- render-word screen, words-a, x, y, render-cursor?
+  var space/edx: grapheme <- copy 0x20/space
+  draw-grapheme screen, space, next-x, y, 3/fg=cyan, 0/bg
+  next-x <- increment
+  # recurse
+  var next-ah/ecx: (addr handle word) <- get words-a, next
+  next-x <- render-words screen, next-ah, next-x, y, cursor-word-addr
+  return next-x
+}
+
+fn test-render-words {
+  # words = [aaa, bbb, ccc, ddd]
+  var w-storage: (handle word)
+  var w-ah/esi: (addr handle word) <- address w-storage
+  allocate-word-with w-ah, "aaa"
+  append-word-at-end-with w-ah, "bbb"
+  append-word-at-end-with w-ah, "ccc"
+  append-word-at-end-with w-ah, "ddd"
+  # setup: screen
+  var screen-on-stack: screen
+  var screen/edi: (addr screen) <- address screen-on-stack
+  initialize-screen screen, 0x20, 4
+  #
+  var _w/eax: (addr word) <- lookup *w-ah
+  var w/ecx: (addr word) <- copy _w
+  var cursor-word/eax: int <- copy w
+  var new-x/eax: int <- render-words screen, w-ah, 0/x, 0/y, cursor-word
+  check-screen-row screen, 0/y,                                   "aaa  bbb  ccc  ddd  ", "F - test-render-words/0"
+  check-background-color-in-screen-row screen, 7/bg=cursor, 0/y,  "   |                ", "F - test-render-words/0 cursor"
+  # - start moving cursor left through final word
+  cursor-left w
+  var cursor-word/eax: int <- copy w
+  var new-x/eax: int <- render-words screen, w-ah, 0/x, 0/y, cursor-word
+  check-screen-row screen, 0/y,                                   "aaa  bbb  ccc  ddd  ", "F - test-render-words/0"
+  check-background-color-in-screen-row screen, 7/bg=cursor, 0/y,  "  |                 ", "F - test-render-words/1 cursor"
+  #
+  cursor-left w
+  var cursor-word/eax: int <- copy w
+  var new-x/eax: int <- render-words screen, w-ah, 0/x, 0/y, cursor-word
+  check-screen-row screen, 0/y,                                   "aaa  bbb  ccc  ddd  ", "F - test-render-words/0"
+  check-background-color-in-screen-row screen, 7/bg=cursor, 0/y,  " |                  ", "F - test-render-words/2 cursor"
+  #
+  cursor-left w
+  var cursor-word/eax: int <- copy w
+  var new-x/eax: int <- render-words screen, w-ah, 0/x, 0/y, cursor-word
+  check-screen-row screen, 0/y,                                   "aaa  bbb  ccc  ddd  ", "F - test-render-words/0"
+  check-background-color-in-screen-row screen, 7/bg=cursor, 0/y,  "|                   ", "F - test-render-words/3 cursor"
+  # further moves left within the word change nothing
+  cursor-left w
+  var cursor-word/eax: int <- copy w
+  var new-x/eax: int <- render-words screen, w-ah, 0/x, 0/y, cursor-word
+  check-screen-row screen, 0/y,                                   "aaa  bbb  ccc  ddd  ", "F - test-render-words/0"
+  check-background-color-in-screen-row screen, 7/bg=cursor, 0/y,  "|                   ", "F - test-render-words/4 cursor"
+  # - switch to next word
+  var w2-ah/eax: (addr handle word) <- get w, next
+  var _w/eax: (addr word) <- lookup *w2-ah
+  var w/ecx: (addr word) <- copy _w
+  var cursor-word/eax: int <- copy w
+  var new-x/eax: int <- render-words screen, w-ah, 0/x, 0/y, cursor-word
+  check-screen-row screen, 0/y,                                   "aaa  bbb  ccc  ddd  ", "F - test-render-words/0"
+  check-background-color-in-screen-row screen, 7/bg=cursor, 0/y,  "        |           ", "F - test-render-words/5 cursor"
+  # now speed up a little
+  cursor-left w
+  cursor-left w
+  var cursor-word/eax: int <- copy w
+  var new-x/eax: int <- render-words screen, w-ah, 0/x, 0/y, cursor-word
+  check-screen-row screen, 0/y,                                   "aaa  bbb  ccc  ddd  ", "F - test-render-words/0"
+  check-background-color-in-screen-row screen, 7/bg=cursor, 0/y,  "      |             ", "F - test-render-words/6 cursor"
+  #
+  var w2-ah/eax: (addr handle word) <- get w, next
+  var _w/eax: (addr word) <- lookup *w2-ah
+  var w/ecx: (addr word) <- copy _w
+  cursor-left w
+  var cursor-word/eax: int <- copy w
+  var new-x/eax: int <- render-words screen, w-ah, 0/x, 0/y, cursor-word
+  check-screen-row screen, 0/y,                                   "aaa  bbb  ccc  ddd  ", "F - test-render-words/0"
+  check-background-color-in-screen-row screen, 7/bg=cursor, 0/y,  "            |       ", "F - test-render-words/7 cursor"
+}
+
 fn render-words-in-reverse screen: (addr screen), _words-ah: (addr handle word), x: int, y: int, cursor-word-addr: int -> _/eax: int {
   var words-ah/eax: (addr handle word) <- copy _words-ah
   var _words-a/eax: (addr word) <- lookup *words-ah
@@ -306,10 +401,7 @@ fn test-render-words-in-reverse {
   # words = [aaa, bbb, ccc, ddd]
   var w-storage: (handle word)
   var w-ah/esi: (addr handle word) <- address w-storage
-  allocate w-ah
-  var _w/eax: (addr word) <- lookup *w-ah
-  var w/ecx: (addr word) <- copy _w
-  initialize-word-with w, "aaa"
+  allocate-word-with w-ah, "aaa"
   append-word-at-end-with w-ah, "bbb"
   append-word-at-end-with w-ah, "ccc"
   append-word-at-end-with w-ah, "ddd"
@@ -318,6 +410,8 @@ fn test-render-words-in-reverse {
   var screen/edi: (addr screen) <- address screen-on-stack
   initialize-screen screen, 0x20, 4
   #
+  var _w/eax: (addr word) <- lookup *w-ah
+  var w/ecx: (addr word) <- copy _w
   var cursor-word/eax: int <- copy w
   var new-x/eax: int <- render-words-in-reverse screen, w-ah, 0/x, 0/y, cursor-word
   check-screen-row screen, 0/y,                                   "ddd  ccc  bbb  aaa  ", "F - test-render-words-in-reverse/0"