diff options
Diffstat (limited to 'shell/sandbox.mu')
-rw-r--r-- | shell/sandbox.mu | 263 |
1 files changed, 263 insertions, 0 deletions
diff --git a/shell/sandbox.mu b/shell/sandbox.mu new file mode 100644 index 00000000..49c2a5f9 --- /dev/null +++ b/shell/sandbox.mu @@ -0,0 +1,263 @@ +type sandbox { + data: (handle gap-buffer) + value: (handle stream byte) + trace: (handle trace) + cursor-in-trace?: boolean +} + +fn initialize-sandbox _self: (addr sandbox) { + var self/esi: (addr sandbox) <- copy _self + var data-ah/eax: (addr handle gap-buffer) <- get self, data + allocate data-ah + var data/eax: (addr gap-buffer) <- lookup *data-ah + initialize-gap-buffer data, 0x1000/4KB + var value-ah/eax: (addr handle stream byte) <- get self, value + populate-stream value-ah, 0x1000/4KB + var trace-ah/eax: (addr handle trace) <- get self, trace + allocate trace-ah + var trace/eax: (addr trace) <- lookup *trace-ah + initialize-trace trace, 0x1000/lines, 0x80/visible-lines +} + +## some helpers for tests + +fn initialize-sandbox-with _self: (addr sandbox), s: (addr array byte) { + var self/esi: (addr sandbox) <- copy _self + var data-ah/eax: (addr handle gap-buffer) <- get self, data + allocate data-ah + var data/eax: (addr gap-buffer) <- lookup *data-ah + initialize-gap-buffer-with data, s +} + +fn allocate-sandbox-with _out: (addr handle sandbox), s: (addr array byte) { + var out/eax: (addr handle sandbox) <- copy _out + allocate out + var out-addr/eax: (addr sandbox) <- lookup *out + initialize-sandbox-with out-addr, s +} + +## + +fn render-sandbox screen: (addr screen), _self: (addr sandbox), xmin: int, ymin: int, xmax: int, ymax: int { + clear-screen screen + var self/esi: (addr sandbox) <- copy _self + # data + var data-ah/eax: (addr handle gap-buffer) <- get self, data + var _data/eax: (addr gap-buffer) <- lookup *data-ah + var data/edx: (addr gap-buffer) <- copy _data + var x/eax: int <- copy xmin + var y/ecx: int <- copy ymin + var cursor-in-sandbox?/ebx: boolean <- copy 0/false + { + var cursor-in-trace?/eax: (addr boolean) <- get self, cursor-in-trace? + compare *cursor-in-trace?, 0/false + break-if-!= + cursor-in-sandbox? <- copy 1/true + } + x, y <- render-gap-buffer-wrapping-right-then-down screen, data, x, y, xmax, ymax, cursor-in-sandbox? + 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 + var cursor-in-trace?/eax: (addr boolean) <- get self, cursor-in-trace? + y <- render-trace screen, trace, xmin, y, xmax, ymax, *cursor-in-trace? + # value + $render-sandbox: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 + rewind-stream value + var done?/eax: boolean <- stream-empty? value + compare done?, 0/false + break-if-!= + var x/eax: int <- copy 0 + x, y <- draw-text-wrapping-right-then-down screen, "=> ", xmin, y, xmax, ymax, xmin, y, 7/fg, 0/bg + var x2/edx: int <- copy x + var dummy/eax: int <- draw-stream-rightward screen, value, x2, xmax, y, 7/fg=grey, 0/bg + } + # render menu + var cursor-in-trace?/eax: (addr boolean) <- get self, cursor-in-trace? + compare *cursor-in-trace?, 0/false + { + break-if-= + render-trace-menu screen + return + } + render-sandbox-menu screen +} + +fn render-sandbox-menu screen: (addr screen) { + var width/eax: int <- copy 0 + var height/ecx: int <- copy 0 + width, height <- screen-size screen + var y/ecx: int <- copy height + y <- decrement + set-cursor-position screen, 0/x, y + draw-text-rightward-from-cursor screen, " ctrl-s ", width, 0/fg, 7/bg=grey + draw-text-rightward-from-cursor screen, " run sandbox ", width, 7/fg, 0/bg + draw-text-rightward-from-cursor screen, " ctrl-d ", width, 0/fg, 7/bg=grey + draw-text-rightward-from-cursor screen, " cursor down ", width, 7/fg, 0/bg + draw-text-rightward-from-cursor screen, " ctrl-u ", width, 0/fg, 7/bg=grey + draw-text-rightward-from-cursor screen, " cursor up ", width, 7/fg, 0/bg + draw-text-rightward-from-cursor screen, " tab ", width, 0/fg, 9/bg=blue + draw-text-rightward-from-cursor screen, " move to trace ", width, 7/fg, 0/bg +} + +fn edit-sandbox _self: (addr sandbox), key: byte { + var self/esi: (addr sandbox) <- copy _self + var g/edx: grapheme <- copy key + # running code + { + compare g, 0x12/ctrl-r + break-if-!= + # ctrl-r: run function outside sandbox + # required: fn (addr screen), (addr keyboard) + # Mu will pass in the real screen and keyboard. + return + } + { + compare g, 0x13/ctrl-s + break-if-!= + # ctrl-s: run sandbox(es) + var data-ah/eax: (addr handle gap-buffer) <- get self, data + var _data/eax: (addr gap-buffer) <- lookup *data-ah + var data/ecx: (addr gap-buffer) <- copy _data + var value-ah/eax: (addr handle stream byte) <- get self, value + var _value/eax: (addr stream byte) <- lookup *value-ah + var value/edx: (addr stream byte) <- copy _value + var trace-ah/eax: (addr handle trace) <- get self, trace + var trace/eax: (addr trace) <- lookup *trace-ah + clear-trace trace + run data, value, trace + return + } + # tab + var cursor-in-trace?/eax: (addr boolean) <- get self, cursor-in-trace? + { + compare g, 9/tab + break-if-!= + # if cursor in input, switch to trace + { + compare *cursor-in-trace?, 0/false + break-if-!= + copy-to *cursor-in-trace?, 1/true + return + } + # if cursor in trace, switch to input + copy-to *cursor-in-trace?, 0/false + return + } + # if cursor in trace, send cursor to trace + { + compare *cursor-in-trace?, 0/false + break-if-= + var trace-ah/eax: (addr handle trace) <- get self, trace + var trace/eax: (addr trace) <- lookup *trace-ah + edit-trace trace, g + return + } + # otherwise send cursor to input + var data-ah/eax: (addr handle gap-buffer) <- get self, data + var data/eax: (addr gap-buffer) <- lookup *data-ah + edit-gap-buffer data, g + return +} + +fn run in: (addr gap-buffer), out: (addr stream byte), trace: (addr trace) { + var read-result-storage: (handle cell) + var read-result/esi: (addr handle cell) <- address read-result-storage + read-cell in, read-result, trace + var error?/eax: boolean <- has-errors? trace + { + compare error?, 0/false + break-if-= + return + } + # TODO: eval + clear-stream out + print-cell read-result, out, trace + mark-lines-dirty trace +} + +fn test-run-integer { + var sandbox-storage: sandbox + var sandbox/esi: (addr sandbox) <- address sandbox-storage + initialize-sandbox sandbox + # type "1" + edit-sandbox sandbox, 0x31/1 + # eval + edit-sandbox sandbox, 0x13/ctrl-s + # setup: screen + var screen-on-stack: screen + var screen/edi: (addr screen) <- address screen-on-stack + initialize-screen screen, 0x80/width, 0x10/height + # + render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height + check-screen-row screen, 0/y, "1 ", "F - test-run-integer/0" + check-screen-row screen, 1/y, "... ", "F - test-run-integer/1" + check-screen-row screen, 2/y, "=> 1 ", "F - test-run-integer/2" +} + +fn test-run-error-invalid-integer { + var sandbox-storage: sandbox + var sandbox/esi: (addr sandbox) <- address sandbox-storage + initialize-sandbox sandbox + # type "1a" + edit-sandbox sandbox, 0x31/1 + edit-sandbox sandbox, 0x61/a + # eval + edit-sandbox sandbox, 0x13/ctrl-s + # setup: screen + var screen-on-stack: screen + var screen/edi: (addr screen) <- address screen-on-stack + initialize-screen screen, 0x80/width, 0x10/height + # + render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height + check-screen-row screen, 0/y, "1a ", "F - test-run-error-invalid-integer/0" + check-screen-row screen, 1/y, "... ", "F - test-run-error-invalid-integer/0" + check-screen-row screen, 2/y, "invalid number ", "F - test-run-error-invalid-integer/2" +} + +fn test-run-move-cursor-into-trace { + var sandbox-storage: sandbox + var sandbox/esi: (addr sandbox) <- address sandbox-storage + initialize-sandbox sandbox + # type "12" + edit-sandbox sandbox, 0x31/1 + edit-sandbox sandbox, 0x32/2 + # eval + edit-sandbox sandbox, 0x13/ctrl-s + # setup: screen + var screen-on-stack: screen + var screen/edi: (addr screen) <- address screen-on-stack + initialize-screen screen, 0x80/width, 0x10/height + # + render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height + check-screen-row screen, 0/y, "12 ", "F - test-run-move-cursor-into-trace/pre-0" + check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " | ", "F - test-run-move-cursor-into-trace/pre-0/cursor" + check-screen-row screen, 1/y, "... ", "F - test-run-move-cursor-into-trace/pre-1" + check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-run-move-cursor-into-trace/pre-1/cursor" + check-screen-row screen, 2/y, "=> 12 ", "F - test-run-move-cursor-into-trace/pre-2" + check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-run-move-cursor-into-trace/pre-2/cursor" + # move cursor into trace + edit-sandbox sandbox, 9/tab + # + render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height + check-screen-row screen, 0/y, "12 ", "F - test-run-move-cursor-into-trace/trace-0" + check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " ", "F - test-run-move-cursor-into-trace/trace-0/cursor" + check-screen-row screen, 1/y, "... ", "F - test-run-move-cursor-into-trace/trace-1" + check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, "||| ", "F - test-run-move-cursor-into-trace/trace-1/cursor" + check-screen-row screen, 2/y, "=> 12 ", "F - test-run-move-cursor-into-trace/trace-2" + check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-run-move-cursor-into-trace/trace-2/cursor" + # move cursor into input + edit-sandbox sandbox, 9/tab + # + render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height + check-screen-row screen, 0/y, "12 ", "F - test-run-move-cursor-into-trace/input-0" + check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " | ", "F - test-run-move-cursor-into-trace/input-0/cursor" + check-screen-row screen, 1/y, "... ", "F - test-run-move-cursor-into-trace/input-1" + check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-run-move-cursor-into-trace/input-1/cursor" + check-screen-row screen, 2/y, "=> 12 ", "F - test-run-move-cursor-into-trace/input-2" + check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-run-move-cursor-into-trace/input-2/cursor" +} |