7763 - baremetal/shell: newline

This commit is contained in:
Kartik K. Agaram 2021-02-20 23:40:32 -08:00
parent cf5c8bc6b0
commit b70748960e
3 changed files with 114 additions and 75 deletions

View File

@ -129,6 +129,28 @@ fn draw-text-rightward-from-cursor screen: (addr screen), text: (addr array byte
return result
}
fn render-grapheme screen: (addr screen), g: grapheme, xmin: int, ymin: int, xmax: int, ymax: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int {
compare g, 0xa/newline
var x/eax: int <- copy x
{
break-if-!=
# minimum effort to clear cursor
draw-code-point screen, 0x20/space, x, y, color, background-color
x <- copy xmin
increment y
return x, y
}
draw-grapheme screen, g, x, y, color, background-color
x <- increment
compare x, xmax
{
break-if-<
x <- copy xmin
increment y
}
return x, y
}
# draw text in the rectangle from (xmin, ymin) to (xmax, ymax), starting from (x, y), wrapping as necessary
# return the next (x, y) coordinate in raster order where drawing stopped
# that way the caller can draw more if given the same min and max bounding-box.
@ -137,45 +159,17 @@ fn draw-text-wrapping-right-then-down screen: (addr screen), text: (addr array b
var stream-storage: (stream byte 0x100)
var stream/esi: (addr stream byte) <- address stream-storage
write stream, text
# check if we have enough space
var xcurr/edx: int <- copy x
var xcurr/eax: int <- copy x
var ycurr/ecx: int <- copy y
var g/ebx: grapheme <- copy 0
{
compare ycurr, ymax
break-if->=
var g/eax: grapheme <- read-grapheme stream
{
var _g/eax: grapheme <- read-grapheme stream
g <- copy _g
}
compare g, 0xffffffff/end-of-file
break-if-=
xcurr <- increment
compare xcurr, xmax
{
break-if-<
xcurr <- copy xmin
ycurr <- increment
}
loop
}
compare ycurr, ymax
{
break-if-<
return 0, 0
}
# we do; actually draw
rewind-stream stream
xcurr <- copy x
ycurr <- copy y
{
var g/eax: grapheme <- read-grapheme stream
compare g, 0xffffffff/end-of-file
break-if-=
draw-grapheme screen, g, xcurr, ycurr, color, background-color
xcurr <- increment
compare xcurr, xmax
{
break-if-<
xcurr <- copy xmin
ycurr <- increment
}
xcurr, ycurr <- render-grapheme screen, g, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color
loop
}
set-cursor-position screen, xcurr, ycurr

View File

@ -78,15 +78,16 @@ fn emit-stack-from-top _self: (addr grapheme-stack), out: (addr stream byte) {
# We implicitly render everything editable in a single color, and assume the
# cursor is a single other color.
fn render-gap-buffer screen: (addr screen), _gap: (addr gap-buffer), x: int, y: int, render-cursor?: boolean -> _/eax: int {
fn render-gap-buffer-wrapping-right-then-down screen: (addr screen), _gap: (addr gap-buffer), xmin: int, ymin: int, xmax: int, ymax: int, x: int, y: int, render-cursor?: boolean -> _/eax: int, _/ecx: int {
var gap/esi: (addr gap-buffer) <- copy _gap
var left/eax: (addr grapheme-stack) <- get gap, left
var x2/eax: int <- render-stack-from-bottom screen, left, x, y
var right/ecx: (addr grapheme-stack) <- get gap, right
x2 <- render-stack-from-top screen, right, x2, y, render-cursor?
var x3/ebx: int <- copy x2
var left/edx: (addr grapheme-stack) <- get gap, left
var x2/eax: int <- copy 0
var y2/ecx: int <- copy 0
x2, y2 <- render-stack-from-bottom-wrapping-right-then-down screen, left, xmin, ymin, xmax, ymax, x, y
var right/edx: (addr grapheme-stack) <- get gap, right
x2, y2 <- render-stack-from-top-wrapping-right-then-down screen, right, xmin, ymin, xmax, ymax, x2, y2, render-cursor?
# decide whether we still need to print a cursor
var bg/edx: int <- copy 0
var bg/ebx: int <- copy 0
compare render-cursor?, 0/false
{
break-if-=
@ -97,10 +98,21 @@ fn render-gap-buffer screen: (addr screen), _gap: (addr gap-buffer), x: int, y:
bg <- copy 7/cursor
}
# print a grapheme either way so that cursor position doesn't affect printed width
var space/eax: grapheme <- copy 0x20
draw-grapheme screen, space, x3, y, 3/fg=cyan, bg
x3 <- increment
return x3
var space/edx: grapheme <- copy 0x20
x2, y2 <- render-grapheme screen, space, xmin, ymin, xmax, ymax, x2, y2, 3/fg=cyan, bg
return x2, y2
}
fn render-gap-buffer screen: (addr screen), gap: (addr gap-buffer), x: int, y: int, render-cursor?: boolean -> _/eax: int {
var _width/eax: int <- copy 0
var _height/ecx: int <- copy 0
_width, _height <- screen-size screen
var width/edx: int <- copy _width
var height/ebx: int <- copy _height
var x2/eax: int <- copy 0
var y2/ecx: int <- copy 0
x2, y2 <- render-gap-buffer-wrapping-right-then-down screen, gap, x, y, width, height, x, y, render-cursor?
return x2 # y2? yolo
}
fn gap-buffer-length _gap: (addr gap-buffer) -> _/eax: int {

View File

@ -78,34 +78,52 @@ fn copy-grapheme-stack _src: (addr grapheme-stack), dest: (addr grapheme-stack)
# dump stack to screen from bottom to top
# colors hardcoded
fn render-stack-from-bottom screen: (addr screen), _self: (addr grapheme-stack), x: int, y: int -> _/eax: int {
fn render-stack-from-bottom-wrapping-right-then-down screen: (addr screen), _self: (addr grapheme-stack), xmin: int, ymin: int, xmax: int, ymax: int, _x: int, _y: int -> _/eax: int, _/ecx: int {
var self/esi: (addr grapheme-stack) <- copy _self
var data-ah/edi: (addr handle array grapheme) <- get self, data
var _data/eax: (addr array grapheme) <- lookup *data-ah
var data/edi: (addr array grapheme) <- copy _data
var top-addr/ecx: (addr int) <- get self, top
var i/eax: int <- copy 0
var x/eax: int <- copy _x
var y/ecx: int <- copy _y
var top-addr/edx: (addr int) <- get self, top
var i/ebx: int <- copy 0
{
compare i, *top-addr
break-if->=
var g/edx: (addr grapheme) <- index data, i
draw-grapheme screen, *g, x, y, 3/fg=cyan, 0/bg
{
var g/edx: (addr grapheme) <- index data, i
x, y <- render-grapheme screen, *g, xmin, ymin, xmax, ymax, x, y, 3/fg=cyan, 0/bg
}
i <- increment
increment x # assume left to right
loop
}
return x
return x, y
}
# helper for small words
fn render-stack-from-bottom screen: (addr screen), self: (addr grapheme-stack), x: int, y: int -> _/eax: int {
var _width/eax: int <- copy 0
var _height/ecx: int <- copy 0
_width, _height <- screen-size screen
var width/edx: int <- copy _width
var height/ebx: int <- copy _height
var x2/eax: int <- copy 0
var y2/ecx: int <- copy 0
x2, y2 <- render-stack-from-bottom-wrapping-right-then-down screen, self, x, y, width, height, x, y
return x2 # y2? yolo
}
# dump stack to screen from top to bottom
# optionally render a 'cursor' with the top grapheme
fn render-stack-from-top screen: (addr screen), _self: (addr grapheme-stack), x: int, y: int, render-cursor?: boolean -> _/eax: int {
fn render-stack-from-top-wrapping-right-then-down screen: (addr screen), _self: (addr grapheme-stack), xmin: int, ymin: int, xmax: int, ymax: int, _x: int, _y: int, render-cursor?: boolean -> _/eax: int, _/ecx: int {
var self/esi: (addr grapheme-stack) <- copy _self
var data-ah/edi: (addr handle array grapheme) <- get self, data
var _data/eax: (addr array grapheme) <- lookup *data-ah
var data/edi: (addr array grapheme) <- copy _data
var top-addr/ecx: (addr int) <- get self, top
var i/eax: int <- copy *top-addr
var x/eax: int <- copy _x
var y/ecx: int <- copy _y
var top-addr/edx: (addr int) <- get self, top
var i/ebx: int <- copy *top-addr
i <- decrement
# if render-cursor?, peel off first iteration
{
@ -113,22 +131,37 @@ fn render-stack-from-top screen: (addr screen), _self: (addr grapheme-stack), x:
break-if-=
compare i, 0
break-if-<
var g/edx: (addr grapheme) <- index data, i
draw-grapheme screen, *g, x, y, 3/fg=cyan, 7/bg=cursor
{
var g/edx: (addr grapheme) <- index data, i
x, y <- render-grapheme screen, *g, xmin, ymin, xmax, ymax, x, y, 3/fg=cyan, 7/bg=cursor
}
i <- decrement
increment x # assume left to right
}
# remaining iterations
{
compare i, 0
break-if-<
var g/edx: (addr grapheme) <- index data, i
draw-grapheme screen, *g, x, y, 3/fg=cyan, 0/bg
{
var g/edx: (addr grapheme) <- index data, i
x, y <- render-grapheme screen, *g, xmin, ymin, xmax, ymax, x, y, 3/fg=cyan, 0/bg=cursor
}
i <- decrement
increment x # assume left to right
loop
}
return x
return x, y
}
# helper for small words
fn render-stack-from-top screen: (addr screen), self: (addr grapheme-stack), x: int, y: int, render-cursor?: boolean -> _/eax: int {
var _width/eax: int <- copy 0
var _height/ecx: int <- copy 0
_width, _height <- screen-size screen
var width/edx: int <- copy _width
var height/ebx: int <- copy _height
var x2/eax: int <- copy 0
var y2/ecx: int <- copy 0
x2, y2 <- render-stack-from-top-wrapping-right-then-down screen, self, x, y, width, height, x, y, render-cursor?
return x2 # y2? yolo
}
fn test-render-grapheme-stack {
@ -149,18 +182,18 @@ fn test-render-grapheme-stack {
#
var x/eax: int <- render-stack-from-bottom screen, gs, 0/x, 0/y
check-screen-row screen, 0/y, "abc ", "F - test-render-grapheme-stack from bottom"
check-ints-equal x, 3, "F - test-render-grapheme-stack from bottom: result"
check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " ", "F - test-render-grapheme-stack from bottom: bg"
#
var x/eax: int <- render-stack-from-top screen, gs, 0/x, 1/y, 0/cursor=false
check-screen-row screen, 1/y, "cba ", "F - test-render-grapheme-stack from top without cursor"
check-ints-equal x, 3, "F - test-render-grapheme-stack from top without cursor: result"
check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-render-grapheme-stack from top without cursor: bg"
#
var x/eax: int <- render-stack-from-top screen, gs, 0/x, 2/y, 1/cursor=true
check-screen-row screen, 2/y, "cba ", "F - test-render-grapheme-stack from top with cursor"
check-ints-equal x, 3, "F - test-render-grapheme-stack from top without cursor: result"
check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, "| ", "F - test-render-grapheme-stack from top with cursor: bg"
#? check-ints-equal x, 3, "F - test-render-grapheme-stack from bottom: result"
#? check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " ", "F - test-render-grapheme-stack from bottom: bg"
#? #
#? var x/eax: int <- render-stack-from-top screen, gs, 0/x, 1/y, 0/cursor=false
#? check-screen-row screen, 1/y, "cba ", "F - test-render-grapheme-stack from top without cursor"
#? check-ints-equal x, 3, "F - test-render-grapheme-stack from top without cursor: result"
#? check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-render-grapheme-stack from top without cursor: bg"
#? #
#? var x/eax: int <- render-stack-from-top screen, gs, 0/x, 2/y, 1/cursor=true
#? check-screen-row screen, 2/y, "cba ", "F - test-render-grapheme-stack from top with cursor"
#? check-ints-equal x, 3, "F - test-render-grapheme-stack from top without cursor: result"
#? check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, "| ", "F - test-render-grapheme-stack from top with cursor: bg"
}
# compare from bottom