diff --git a/baremetal/shell/read.mu b/baremetal/shell/read.mu index e619affd..24d5df13 100644 --- a/baremetal/shell/read.mu +++ b/baremetal/shell/read.mu @@ -122,6 +122,7 @@ fn next-number-token in: (addr gap-buffer), out: (addr stream byte), trace: (add compare digit?, 0/false break-if-!= error trace, "invalid number" + return } var g/eax: grapheme <- read-from-gap-buffer in write-grapheme out, g diff --git a/baremetal/shell/sandbox.mu b/baremetal/shell/sandbox.mu index a766bc4d..08b76c3a 100644 --- a/baremetal/shell/sandbox.mu +++ b/baremetal/shell/sandbox.mu @@ -59,27 +59,25 @@ fn render-sandbox screen: (addr screen), _self: (addr sandbox), _x: int, _y: int var x/eax: int <- copy _x var y/ecx: int <- copy _y x, y <- render-gap-buffer-wrapping-right-then-down screen, data, x, y, 0x20/xmax, 0x20/ymax, x, y, 1/show-cursor - { - var value-ah/eax: (addr handle stream byte) <- get self, value - var value/eax: (addr stream byte) <- lookup *value-ah - var done?/eax: boolean <- stream-empty? value - compare done?, 0/false - break-if-= - return - } y <- increment # trace var trace-ah/eax: (addr handle trace) <- get self, trace var _trace/eax: (addr trace) <- lookup *trace-ah var trace/edx: (addr trace) <- copy _trace y <- render-trace screen, trace, _x, y, 0x20/xmax, 0x20/ymax - y <- increment # value + var value-ah/eax: (addr handle stream byte) <- get self, value + var _value/eax: (addr stream byte) <- lookup *value-ah + var value/esi: (addr stream byte) <- copy _value + var done?/eax: boolean <- stream-empty? value + compare done?, 0/false + { + break-if-= + return + } var x/eax: int <- copy 0 x, y <- draw-text-wrapping-right-then-down screen, "=> ", _x, y, 0x20/xmax, 0x20/ymax, _x, y, 7/fg, 0/bg var x2/edx: int <- copy x - var value-ah/eax: (addr handle stream byte) <- get self, value - var value/eax: (addr stream byte) <- lookup *value-ah var dummy/eax: int <- draw-stream-rightward screen, value, x2, 0x30/xmax, y, 7/fg=grey, 0/bg } diff --git a/baremetal/shell/trace.mu b/baremetal/shell/trace.mu index 90a2a844..4c699a08 100644 --- a/baremetal/shell/trace.mu +++ b/baremetal/shell/trace.mu @@ -30,6 +30,7 @@ fn has-errors? _self: (addr trace) -> _/eax: boolean { var trace-ah/eax: (addr handle stream trace-line) <- get self, data var _trace/eax: (addr stream trace-line) <- lookup *trace-ah var trace/esi: (addr stream trace-line) <- copy _trace + rewind-stream trace { var done?/eax: boolean <- stream-empty? trace compare done?, 0/false @@ -92,8 +93,167 @@ fn trace-higher _self: (addr trace) { } fn render-trace screen: (addr screen), _self: (addr trace), xmin: int, ymin: int, xmax: int, ymax: int -> _/ecx: int { - var x/eax: int <- copy xmin + var already-hiding-lines?/ebx: boolean <- copy 0/false var y/ecx: int <- copy ymin - x, y <- draw-text-wrapping-right-then-down screen, "...", xmin, ymin, xmax, ymax, x, y, 9/fg=trace, 0/bg + var self/eax: (addr trace) <- copy _self + var trace-ah/eax: (addr handle stream trace-line) <- get self, data + var _trace/eax: (addr stream trace-line) <- lookup *trace-ah + var trace/esi: (addr stream trace-line) <- copy _trace + rewind-stream trace + $render-trace:loop: { + var done?/eax: boolean <- stream-empty? trace + compare done?, 0/false + break-if-!= + var curr-storage: trace-line + var curr/edx: (addr trace-line) <- address curr-storage + read-from-stream trace, curr + var curr-label-ah/eax: (addr handle array byte) <- get curr, label + var curr-label/eax: (addr array byte) <- lookup *curr-label-ah + # always display errors + var is-error?/eax: boolean <- string-equal? curr-label, "error" + { + compare is-error?, 0/false + break-if-= + var curr-data-ah/eax: (addr handle array byte) <- get curr, data + var _curr-data/eax: (addr array byte) <- lookup *curr-data-ah + var curr-data/edx: (addr array byte) <- copy _curr-data + var x/eax: int <- copy xmin + x, y <- draw-text-wrapping-right-then-down screen, curr-data, xmin, ymin, xmax, ymax, x, y, 0xc/fg=trace-error, 0/bg + y <- increment + already-hiding-lines? <- copy 0/false + loop $render-trace:loop + } + # otherwise ignore the rest + compare already-hiding-lines?, 0/false + { + break-if-!= + var x/eax: int <- copy xmin + x, y <- draw-text-wrapping-right-then-down screen, "...", xmin, ymin, xmax, ymax, x, y, 9/fg=trace, 0/bg + y <- increment + } + loop + } return y } + +fn test-render-trace-empty { + var t-storage: trace + var t/esi: (addr trace) <- address t-storage + initialize-trace t, 0x10 + # setup: screen + var screen-on-stack: screen + var screen/edi: (addr screen) <- address screen-on-stack + initialize-screen screen, 5, 4 + # + var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 5/xmax, 4/ymax + # + check-ints-equal y, 0, "F - test-render-trace-empty/cursor" + check-screen-row screen, 0/y, " ", "F - test-render-trace-empty" +} + +fn test-render-trace-collapsed-by-default { + var t-storage: trace + var t/esi: (addr trace) <- address t-storage + initialize-trace t, 0x10 + var contents-storage: (stream byte 0x10) + var contents/ecx: (addr stream byte) <- address contents-storage + write contents, "data" + trace t, "l", contents + # setup: screen + var screen-on-stack: screen + var screen/edi: (addr screen) <- address screen-on-stack + initialize-screen screen, 5, 4 + # + var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 5/xmax, 4/ymax + # + check-ints-equal y, 1, "F - test-render-trace-collapsed-by-default/cursor" + check-screen-row screen, 0/y, "... ", "F - test-render-trace-collapsed-by-default" +} + +fn test-render-trace-error { + var t-storage: trace + var t/esi: (addr trace) <- address t-storage + initialize-trace t, 0x10 + error t, "error" + # setup: screen + var screen-on-stack: screen + var screen/edi: (addr screen) <- address screen-on-stack + initialize-screen screen, 0xa, 4 + # + var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0xa/xmax, 4/ymax + # + check-ints-equal y, 1, "F - test-render-trace-error/cursor" + check-screen-row screen, 0/y, "error", "F - test-render-trace-error" +} + +fn test-render-trace-error-at-start { + var t-storage: trace + var t/esi: (addr trace) <- address t-storage + initialize-trace t, 0x10 + # line 1 + error t, "error" + # line 2 + var contents-storage: (stream byte 0x10) + var contents/ecx: (addr stream byte) <- address contents-storage + write contents, "data" + trace t, "l", contents + # setup: screen + var screen-on-stack: screen + var screen/edi: (addr screen) <- address screen-on-stack + initialize-screen screen, 0xa, 4 + # + var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0xa/xmax, 4/ymax + # + check-ints-equal y, 2, "F - test-render-trace-error-at-start/cursor" + check-screen-row screen, 0/y, "error", "F - test-render-trace-error-at-start/0" + check-screen-row screen, 1/y, "... ", "F - test-render-trace-error-at-start/1" +} + +fn test-render-trace-error-at-end { + var t-storage: trace + var t/esi: (addr trace) <- address t-storage + initialize-trace t, 0x10 + # line 1 + var contents-storage: (stream byte 0x10) + var contents/ecx: (addr stream byte) <- address contents-storage + write contents, "data" + trace t, "l", contents + # line 2 + error t, "error" + # setup: screen + var screen-on-stack: screen + var screen/edi: (addr screen) <- address screen-on-stack + initialize-screen screen, 0xa, 4 + # + var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0xa/xmax, 4/ymax + # + check-ints-equal y, 2, "F - test-render-trace-error-at-end/cursor" + check-screen-row screen, 0/y, "... ", "F - test-render-trace-error-at-end/0" + check-screen-row screen, 1/y, "error", "F - test-render-trace-error-at-end/1" +} + +fn test-render-trace-error-in-the-middle { + var t-storage: trace + var t/esi: (addr trace) <- address t-storage + initialize-trace t, 0x10 + # line 1 + var contents-storage: (stream byte 0x10) + var contents/ecx: (addr stream byte) <- address contents-storage + write contents, "data" + trace t, "l", contents + # line 2 + error t, "error" + # line 3 + trace t, "l", contents + # setup: screen + var screen-on-stack: screen + var screen/edi: (addr screen) <- address screen-on-stack + initialize-screen screen, 0xa, 4 + # + var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0xa/xmax, 4/ymax + # + check-ints-equal y, 3, "F - test-render-trace-error-in-the-middle/cursor" + check-screen-row screen, 0/y, "... ", "F - test-render-trace-error-in-the-middle/0" + check-screen-row screen, 1/y, "error", "F - test-render-trace-error-in-the-middle/1" + check-screen-row screen, 2/y, "... ", "F - test-render-trace-error-in-the-middle/2" +}