https://github.com/akkartik/mu/blob/main/shell/sandbox.mu
1 type sandbox {
2 data: (handle gap-buffer)
3 value: (handle stream byte)
4 screen-var: (handle cell)
5 keyboard-var: (handle cell)
6 trace: (handle trace)
7 cursor-in-data?: boolean
8 cursor-in-keyboard?: boolean
9 cursor-in-trace?: boolean
10 }
11
12 fn initialize-sandbox _self: (addr sandbox), screen-and-keyboard?: boolean {
13 var self/esi: (addr sandbox) <- copy _self
14 var data-ah/eax: (addr handle gap-buffer) <- get self, data
15 allocate data-ah
16 var data/eax: (addr gap-buffer) <- lookup *data-ah
17 initialize-gap-buffer data, 0x1000/4KB
18
19 var value-ah/eax: (addr handle stream byte) <- get self, value
20 populate-stream value-ah, 0x1000/4KB
21
22 {
23 compare screen-and-keyboard?, 0/false
24 break-if-=
25 var screen-ah/eax: (addr handle cell) <- get self, screen-var
26 new-screen screen-ah, 5/width, 4/height
27 var keyboard-ah/eax: (addr handle cell) <- get self, keyboard-var
28 new-keyboard keyboard-ah, 0x10/keyboard-capacity
29 }
30
31 var trace-ah/eax: (addr handle trace) <- get self, trace
32 allocate trace-ah
33 var trace/eax: (addr trace) <- lookup *trace-ah
34 initialize-trace trace, 0x1000/lines, 0x80/visible-lines
35 var cursor-in-data?/eax: (addr boolean) <- get self, cursor-in-data?
36 copy-to *cursor-in-data?, 1/true
37 }
38
39
40
41 fn initialize-sandbox-with _self: (addr sandbox), s: (addr array byte) {
42 var self/esi: (addr sandbox) <- copy _self
43 var data-ah/eax: (addr handle gap-buffer) <- get self, data
44 allocate data-ah
45 var data/eax: (addr gap-buffer) <- lookup *data-ah
46 initialize-gap-buffer-with data, s
47 }
48
49 fn allocate-sandbox-with _out: (addr handle sandbox), s: (addr array byte) {
50 var out/eax: (addr handle sandbox) <- copy _out
51 allocate out
52 var out-addr/eax: (addr sandbox) <- lookup *out
53 initialize-sandbox-with out-addr, s
54 }
55
56
57
58 fn render-sandbox screen: (addr screen), _self: (addr sandbox), xmin: int, ymin: int, xmax: int, ymax: int, globals: (addr global-table) {
59 clear-rect screen, xmin, ymin, xmax, ymax, 0/bg=black
60 var self/esi: (addr sandbox) <- copy _self
61
62 var data-ah/eax: (addr handle gap-buffer) <- get self, data
63 var _data/eax: (addr gap-buffer) <- lookup *data-ah
64 var data/edx: (addr gap-buffer) <- copy _data
65 var x/eax: int <- copy xmin
66 var y/ecx: int <- copy ymin
67 y <- maybe-render-empty-screen screen, self, xmin, y
68 y <- maybe-render-keyboard screen, self, xmin, y
69 var cursor-in-sandbox?/ebx: (addr boolean) <- get self, cursor-in-data?
70 x, y <- render-gap-buffer-wrapping-right-then-down screen, data, x, y, xmax, ymax, *cursor-in-sandbox?
71 y <- increment
72
73 var trace-ah/eax: (addr handle trace) <- get self, trace
74 var _trace/eax: (addr trace) <- lookup *trace-ah
75 var trace/edx: (addr trace) <- copy _trace
76 var cursor-in-trace?/eax: (addr boolean) <- get self, cursor-in-trace?
77 y <- render-trace screen, trace, xmin, y, xmax, ymax, *cursor-in-trace?
78
79 $render-sandbox:value: {
80 var value-ah/eax: (addr handle stream byte) <- get self, value
81 var _value/eax: (addr stream byte) <- lookup *value-ah
82 var value/esi: (addr stream byte) <- copy _value
83 rewind-stream value
84 var done?/eax: boolean <- stream-empty? value
85 compare done?, 0/false
86 break-if-!=
87 var x/eax: int <- copy 0
88 x, y <- draw-text-wrapping-right-then-down screen, "=> ", xmin, y, xmax, ymax, xmin, y, 7/fg, 0/bg
89 var x2/edx: int <- copy x
90 var dummy/eax: int <- draw-stream-rightward screen, value, x2, xmax, y, 7/fg=grey, 0/bg
91 }
92 y <- add 2
93 y <- maybe-render-screen screen, self, xmin, y
94
95 var cursor-in-data?/eax: (addr boolean) <- get self, cursor-in-data?
96 compare *cursor-in-data?, 0/false
97 {
98 break-if-=
99 render-sandbox-menu screen, self
100 return
101 }
102 var cursor-in-trace?/eax: (addr boolean) <- get self, cursor-in-trace?
103 compare *cursor-in-trace?, 0/false
104 {
105 break-if-=
106 render-trace-menu screen
107 return
108 }
109 var cursor-in-keyboard?/eax: (addr boolean) <- get self, cursor-in-keyboard?
110 compare *cursor-in-keyboard?, 0/false
111 {
112 break-if-=
113 render-keyboard-menu screen
114 return
115 }
116 }
117
118 fn maybe-render-empty-screen screen: (addr screen), _self: (addr sandbox), xmin: int, ymin: int -> _/ecx: int {
119 var self/esi: (addr sandbox) <- copy _self
120 var screen-obj-cell-ah/eax: (addr handle cell) <- get self, screen-var
121 var screen-obj-cell/eax: (addr cell) <- lookup *screen-obj-cell-ah
122 compare screen-obj-cell, 0
123 {
124 break-if-!=
125 return ymin
126 }
127 var screen-obj-cell-type/ecx: (addr int) <- get screen-obj-cell, type
128 compare *screen-obj-cell-type, 5/screen
129 {
130 break-if-=
131 return ymin
132 }
133 var y/ecx: int <- copy ymin
134 var screen-obj-ah/eax: (addr handle screen) <- get screen-obj-cell, screen-data
135 var _screen-obj/eax: (addr screen) <- lookup *screen-obj-ah
136 var screen-obj/edx: (addr screen) <- copy _screen-obj
137 var x/eax: int <- draw-text-rightward screen, "screen: ", xmin, 0x99/xmax, y, 7/fg, 0/bg
138 y <- render-empty-screen screen, screen-obj, x, y
139 return y
140 }
141
142 fn maybe-render-screen screen: (addr screen), _self: (addr sandbox), xmin: int, ymin: int -> _/ecx: int {
143 var self/esi: (addr sandbox) <- copy _self
144 var screen-obj-cell-ah/eax: (addr handle cell) <- get self, screen-var
145 var screen-obj-cell/eax: (addr cell) <- lookup *screen-obj-cell-ah
146 compare screen-obj-cell, 0
147 {
148 break-if-!=
149 return ymin
150 }
151 var screen-obj-cell-type/ecx: (addr int) <- get screen-obj-cell, type
152 compare *screen-obj-cell-type, 5/screen
153 {
154 break-if-=
155 return ymin
156 }
157 var screen-obj-ah/eax: (addr handle screen) <- get screen-obj-cell, screen-data
158 var _screen-obj/eax: (addr screen) <- lookup *screen-obj-ah
159 var screen-obj/edx: (addr screen) <- copy _screen-obj
160 {
161 var screen-empty?/eax: boolean <- fake-screen-empty? screen-obj
162 compare screen-empty?, 0/false
163 break-if-=
164 return ymin
165 }
166 var x/eax: int <- draw-text-rightward screen, "screen: ", xmin, 0x99/xmax, ymin, 7/fg, 0/bg
167 var y/ecx: int <- copy ymin
168 y <- render-screen screen, screen-obj, x, y
169 return y
170 }
171
172 fn render-empty-screen screen: (addr screen), _target-screen: (addr screen), xmin: int, ymin: int -> _/ecx: int {
173 var target-screen/esi: (addr screen) <- copy _target-screen
174 var screen-y/edi: int <- copy ymin
175
176 {
177 set-cursor-position screen, xmin, screen-y
178 move-cursor-right screen
179 var width/edx: (addr int) <- get target-screen, width
180 var x/ebx: int <- copy 0
181 {
182 compare x, *width
183 break-if->=
184 draw-code-point-at-cursor screen, 0x2d/horizontal-bar, 0x18/fg, 0/bg
185 move-cursor-right screen
186 x <- increment
187 loop
188 }
189 screen-y <- increment
190 }
191
192 var height/edx: (addr int) <- get target-screen, height
193 var y/ecx: int <- copy 0
194 {
195 compare y, *height
196 break-if->=
197 set-cursor-position screen, xmin, screen-y
198 draw-code-point-at-cursor screen, 0x7c/vertical-bar, 0x18/fg, 0/bg
199 move-cursor-right screen
200 var width/edx: (addr int) <- get target-screen, width
201 var x/ebx: int <- copy 0
202 {
203 compare x, *width
204 break-if->=
205 draw-code-point-at-cursor screen, 0x20/space, 0x18/fg, 0/bg
206 move-cursor-right screen
207 x <- increment
208 loop
209 }
210 draw-code-point-at-cursor screen, 0x7c/vertical-bar, 0x18/fg, 0/bg
211 y <- increment
212 screen-y <- increment
213 loop
214 }
215
216 {
217 set-cursor-position screen, xmin, screen-y
218 move-cursor-right screen
219 var width/edx: (addr int) <- get target-screen, width
220 var x/ebx: int <- copy 0
221 {
222 compare x, *width
223 break-if->=
224 draw-code-point-at-cursor screen, 0x2d/horizontal-bar, 0x18/fg, 0/bg
225 move-cursor-right screen
226 x <- increment
227 loop
228 }
229 screen-y <- increment
230 }
231 return screen-y
232 }
233
234 fn render-screen screen: (addr screen), _target-screen: (addr screen), xmin: int, ymin: int -> _/ecx: int {
235 var target-screen/esi: (addr screen) <- copy _target-screen
236 var screen-y/edi: int <- copy ymin
237
238 {
239 set-cursor-position screen, xmin, screen-y
240 move-cursor-right screen
241 var width/edx: (addr int) <- get target-screen, width
242 var x/ebx: int <- copy 0
243 {
244 compare x, *width
245 break-if->=
246 draw-code-point-at-cursor screen, 0x2d/horizontal-bar, 0x18/fg, 0/bg
247 move-cursor-right screen
248 x <- increment
249 loop
250 }
251 screen-y <- increment
252 }
253
254 var height/edx: (addr int) <- get target-screen, height
255 var y/ecx: int <- copy 0
256 {
257 compare y, *height
258 break-if->=
259 set-cursor-position screen, xmin, screen-y
260 draw-code-point-at-cursor screen, 0x7c/vertical-bar, 0x18/fg, 0/bg
261 move-cursor-right screen
262 var width/edx: (addr int) <- get target-screen, width
263 var x/ebx: int <- copy 0
264 {
265 compare x, *width
266 break-if->=
267 print-screen-cell-of-fake-screen screen, target-screen, x, y
268 move-cursor-right screen
269 x <- increment
270 loop
271 }
272 draw-code-point-at-cursor screen, 0x7c/vertical-bar, 0x18/fg, 0/bg
273 y <- increment
274 screen-y <- increment
275 loop
276 }
277
278 {
279 set-cursor-position screen, xmin, screen-y
280 move-cursor-right screen
281 var width/edx: (addr int) <- get target-screen, width
282 var x/ebx: int <- copy 0
283 {
284 compare x, *width
285 break-if->=
286 draw-code-point-at-cursor screen, 0x2d/horizontal-bar, 0x18/fg, 0/bg
287 move-cursor-right screen
288 x <- increment
289 loop
290 }
291 screen-y <- increment
292 }
293 return screen-y
294 }
295
296 fn has-keyboard? _self: (addr sandbox) -> _/eax: boolean {
297 var self/esi: (addr sandbox) <- copy _self
298 var keyboard-obj-cell-ah/eax: (addr handle cell) <- get self, keyboard-var
299 var keyboard-obj-cell/eax: (addr cell) <- lookup *keyboard-obj-cell-ah
300 compare keyboard-obj-cell, 0
301 {
302 break-if-!=
303 return 0/false
304 }
305 var keyboard-obj-cell-type/ecx: (addr int) <- get keyboard-obj-cell, type
306 compare *keyboard-obj-cell-type, 6/keyboard
307 {
308 break-if-=
309 return 0/false
310 }
311 var keyboard-obj-ah/eax: (addr handle gap-buffer) <- get keyboard-obj-cell, keyboard-data
312 var _keyboard-obj/eax: (addr gap-buffer) <- lookup *keyboard-obj-ah
313 var keyboard-obj/edx: (addr gap-buffer) <- copy _keyboard-obj
314 compare keyboard-obj, 0
315 {
316 break-if-!=
317 return 0/false
318 }
319 return 1/true
320 }
321
322 fn maybe-render-keyboard screen: (addr screen), _self: (addr sandbox), xmin: int, ymin: int -> _/ecx: int {
323 var self/esi: (addr sandbox) <- copy _self
324 var keyboard-obj-cell-ah/eax: (addr handle cell) <- get self, keyboard-var
325 var keyboard-obj-cell/eax: (addr cell) <- lookup *keyboard-obj-cell-ah
326 compare keyboard-obj-cell, 0
327 {
328 break-if-!=
329 return ymin
330 }
331 var keyboard-obj-cell-type/ecx: (addr int) <- get keyboard-obj-cell, type
332 compare *keyboard-obj-cell-type, 6/keyboard
333 {
334 break-if-=
335 return ymin
336 }
337 var keyboard-obj-ah/eax: (addr handle gap-buffer) <- get keyboard-obj-cell, keyboard-data
338 var _keyboard-obj/eax: (addr gap-buffer) <- lookup *keyboard-obj-ah
339 var keyboard-obj/edx: (addr gap-buffer) <- copy _keyboard-obj
340 var x/eax: int <- draw-text-rightward screen, "keyboard: ", xmin, 0x99/xmax, ymin, 7/fg, 0/bg
341 var y/ecx: int <- copy ymin
342 var cursor-in-keyboard?/esi: (addr boolean) <- get self, cursor-in-keyboard?
343 y <- render-keyboard screen, keyboard-obj, x, y, *cursor-in-keyboard?
344 y <- increment
345 return y
346 }
347
348
349 fn render-keyboard screen: (addr screen), _keyboard: (addr gap-buffer), xmin: int, ymin: int, render-cursor?: boolean -> _/ecx: int {
350 var keyboard/esi: (addr gap-buffer) <- copy _keyboard
351 var width/edx: int <- copy 0x10/keyboard-capacity
352 var y/edi: int <- copy ymin
353
354 {
355 set-cursor-position screen, xmin, y
356 move-cursor-right screen
357 var x/ebx: int <- copy 0
358 {
359 compare x, width
360 break-if->=
361 draw-code-point-at-cursor screen, 0x2d/horizontal-bar, 0x18/fg, 0/bg
362 move-cursor-right screen
363 x <- increment
364 loop
365 }
366 y <- increment
367 }
368
369 var x/eax: int <- copy xmin
370 draw-code-point screen, 0x7c/vertical-bar, x, y, 0x18/fg, 0/bg
371 x <- increment
372 x <- render-gap-buffer screen, keyboard, x, y, render-cursor?
373 x <- copy xmin
374 x <- add 1
375 x <- add 0x10/keyboard-capacity
376 draw-code-point screen, 0x7c/vertical-bar, x, y, 0x18/fg, 0/bg
377 y <- increment
378
379 {
380 set-cursor-position screen, xmin, y
381 move-cursor-right screen
382 var x/ebx: int <- copy 0
383 {
384 compare x, width
385 break-if->=
386 draw-code-point-at-cursor screen, 0x2d/horizontal-bar, 0x18/fg, 0/bg
387 move-cursor-right screen
388 x <- increment
389 loop
390 }
391 y <- increment
392 }
393 return y
394 }
395
396 fn print-screen-cell-of-fake-screen screen: (addr screen), _target: (addr screen), x: int, y: int {
397 var target/ecx: (addr screen) <- copy _target
398 var data-ah/eax: (addr handle array screen-cell) <- get target, data
399 var data/eax: (addr array screen-cell) <- lookup *data-ah
400 var index/ecx: int <- screen-cell-index target, x, y
401 var offset/ecx: (offset screen-cell) <- compute-offset data, index
402 var src-cell/esi: (addr screen-cell) <- index data, offset
403 var src-grapheme/eax: (addr grapheme) <- get src-cell, data
404 var src-color/ecx: (addr int) <- get src-cell, color
405 var src-background-color/edx: (addr int) <- get src-cell, background-color
406 draw-grapheme-at-cursor screen, *src-grapheme, *src-color, *src-background-color
407 }
408
409 fn render-sandbox-menu screen: (addr screen), _self: (addr sandbox) {
410 var _width/eax: int <- copy 0
411 var height/ecx: int <- copy 0
412 _width, height <- screen-size screen
413 var width/edx: int <- copy _width
414 var y/ecx: int <- copy height
415 y <- decrement
416 var height/ebx: int <- copy y
417 height <- increment
418 clear-rect screen, 0/x, y, width, height, 0/bg=black
419 set-cursor-position screen, 0/x, y
420 draw-text-rightward-from-cursor screen, " ctrl-s ", width, 0/fg, 7/bg=grey
421 draw-text-rightward-from-cursor screen, " run sandbox ", width, 7/fg, 0/bg
422 $render-sandbox-menu:render-tab: {
423 var self/eax: (addr sandbox) <- copy _self
424 var has-trace?/eax: boolean <- has-trace? self
425 compare has-trace?, 0/false
426 {
427 break-if-=
428 draw-text-rightward-from-cursor screen, " tab ", width, 0/fg, 9/bg=blue
429 draw-text-rightward-from-cursor screen, " move to trace ", width, 7/fg, 0/bg
430 break $render-sandbox-menu:render-tab
431 }
432 draw-text-rightward-from-cursor screen, " tab ", width, 0/fg, 0x18/bg=keyboard
433 draw-text-rightward-from-cursor screen, " move to keyboard ", width, 7/fg, 0/bg
434 }
435 }
436
437 fn render-keyboard-menu screen: (addr screen) {
438 var width/eax: int <- copy 0
439 var height/ecx: int <- copy 0
440 width, height <- screen-size screen
441 var y/ecx: int <- copy height
442 y <- decrement
443 var height/edx: int <- copy y
444 height <- increment
445 clear-rect screen, 0/x, y, width, height, 0/bg=black
446 set-cursor-position screen, 0/x, y
447 draw-text-rightward-from-cursor screen, " ctrl-s ", width, 0/fg, 7/bg=grey
448 draw-text-rightward-from-cursor screen, " run sandbox ", width, 7/fg, 0/bg
449 draw-text-rightward-from-cursor screen, " tab ", width, 0/fg, 3/bg=cyan
450 draw-text-rightward-from-cursor screen, " move to sandbox ", width, 7/fg, 0/bg
451 }
452
453 fn edit-sandbox _self: (addr sandbox), key: byte, globals: (addr global-table), real-screen: (addr screen), real-keyboard: (addr keyboard), data-disk: (addr disk) {
454 var self/esi: (addr sandbox) <- copy _self
455 var g/edx: grapheme <- copy key
456
457 {
458 compare g, 0x12/ctrl-r
459 break-if-!=
460
461
462
463 return
464 }
465
466 {
467 compare g, 0x13/ctrl-s
468 break-if-!=
469
470 var data-ah/eax: (addr handle gap-buffer) <- get self, data
471 var _data/eax: (addr gap-buffer) <- lookup *data-ah
472 var data/ecx: (addr gap-buffer) <- copy _data
473 {
474 compare data-disk, 0/no-disk
475 break-if-=
476 var stream-storage: (stream byte 0x200)
477 var stream/esi: (addr stream byte) <- address stream-storage
478 emit-gap-buffer data, stream
479 store-sector data-disk, 0/lba, stream
480 }
481
482 var value-ah/eax: (addr handle stream byte) <- get self, value
483 var _value/eax: (addr stream byte) <- lookup *value-ah
484 var value/edx: (addr stream byte) <- copy _value
485 var trace-ah/eax: (addr handle trace) <- get self, trace
486 var _trace/eax: (addr trace) <- lookup *trace-ah
487 var trace/ebx: (addr trace) <- copy _trace
488 clear-trace trace
489 var screen-cell/eax: (addr handle cell) <- get self, screen-var
490 clear-screen-cell screen-cell
491 var keyboard-cell/esi: (addr handle cell) <- get self, keyboard-var
492 rewind-keyboard-cell keyboard-cell
493 run data, value, globals, trace, screen-cell, keyboard-cell
494 return
495 }
496
497 {
498 compare g, 9/tab
499 break-if-!=
500
501 {
502 var cursor-in-data?/eax: (addr boolean) <- get self, cursor-in-data?
503 compare *cursor-in-data?, 0/false
504 break-if-=
505 var has-trace?/eax: boolean <- has-trace? self
506 compare has-trace?, 0/false
507 {
508 break-if-=
509 var cursor-in-data?/eax: (addr boolean) <- get self, cursor-in-data?
510 copy-to *cursor-in-data?, 0/false
511 var cursor-in-trace?/eax: (addr boolean) <- get self, cursor-in-trace?
512 copy-to *cursor-in-trace?, 1/false
513 return
514 }
515 var has-keyboard?/eax: boolean <- has-keyboard? self
516 compare has-keyboard?, 0/false
517 {
518 break-if-=
519 var cursor-in-data?/eax: (addr boolean) <- get self, cursor-in-data?
520 copy-to *cursor-in-data?, 0/false
521 var cursor-in-keyboard?/eax: (addr boolean) <- get self, cursor-in-keyboard?
522 copy-to *cursor-in-keyboard?, 1/false
523 return
524 }
525 return
526 }
527
528 {
529 var cursor-in-trace?/eax: (addr boolean) <- get self, cursor-in-trace?
530 compare *cursor-in-trace?, 0/false
531 break-if-=
532 copy-to *cursor-in-trace?, 0/false
533 var cursor-target/ecx: (addr boolean) <- get self, cursor-in-keyboard?
534 var has-keyboard?/eax: boolean <- has-keyboard? self
535 compare has-keyboard?, 0/false
536 {
537 break-if-!=
538 cursor-target <- get self, cursor-in-data?
539 }
540 copy-to *cursor-target, 1/true
541 return
542 }
543
544 {
545 var cursor-in-keyboard?/eax: (addr boolean) <- get self, cursor-in-keyboard?
546 compare *cursor-in-keyboard?, 0/false
547 break-if-=
548 copy-to *cursor-in-keyboard?, 0/false
549 var cursor-in-data?/eax: (addr boolean) <- get self, cursor-in-data?
550 copy-to *cursor-in-data?, 1/true
551 return
552 }
553 return
554 }
555
556 {
557 var cursor-in-data?/eax: (addr boolean) <- get self, cursor-in-data?
558 compare *cursor-in-data?, 0/false
559 break-if-=
560 var data-ah/eax: (addr handle gap-buffer) <- get self, data
561 var data/eax: (addr gap-buffer) <- lookup *data-ah
562 edit-gap-buffer data, g
563 return
564 }
565
566 {
567 var cursor-in-keyboard?/eax: (addr boolean) <- get self, cursor-in-keyboard?
568 compare *cursor-in-keyboard?, 0/false
569 break-if-=
570 var keyboard-cell-ah/eax: (addr handle cell) <- get self, keyboard-var
571 var keyboard-cell/eax: (addr cell) <- lookup *keyboard-cell-ah
572 compare keyboard-cell, 0
573 {
574 break-if-!=
575 return
576 }
577 var keyboard-cell-type/ecx: (addr int) <- get keyboard-cell, type
578 compare *keyboard-cell-type, 6/keyboard
579 {
580 break-if-=
581 return
582 }
583 var keyboard-ah/eax: (addr handle gap-buffer) <- get keyboard-cell, keyboard-data
584 var keyboard/eax: (addr gap-buffer) <- lookup *keyboard-ah
585 edit-gap-buffer keyboard, g
586 return
587 }
588
589 {
590 var cursor-in-trace?/eax: (addr boolean) <- get self, cursor-in-trace?
591 compare *cursor-in-trace?, 0/false
592 break-if-=
593 var trace-ah/eax: (addr handle trace) <- get self, trace
594 var trace/eax: (addr trace) <- lookup *trace-ah
595 edit-trace trace, g
596 return
597 }
598 }
599
600 fn run in: (addr gap-buffer), out: (addr stream byte), globals: (addr global-table), trace: (addr trace), screen-cell: (addr handle cell), keyboard-cell: (addr handle cell) {
601 var read-result-storage: (handle cell)
602 var read-result/esi: (addr handle cell) <- address read-result-storage
603 read-cell in, read-result, trace
604 var error?/eax: boolean <- has-errors? trace
605 {
606 compare error?, 0/false
607 break-if-=
608 return
609 }
610 var nil-storage: (handle cell)
611 var nil-ah/eax: (addr handle cell) <- address nil-storage
612 allocate-pair nil-ah
613 var eval-result-storage: (handle cell)
614 var eval-result/edi: (addr handle cell) <- address eval-result-storage
615 evaluate read-result, eval-result, *nil-ah, globals, trace, screen-cell, keyboard-cell
616 var error?/eax: boolean <- has-errors? trace
617 {
618 compare error?, 0/false
619 break-if-=
620 return
621 }
622 clear-stream out
623 print-cell eval-result, out, trace
624 mark-lines-dirty trace
625 }
626
627 fn test-run-integer {
628 var sandbox-storage: sandbox
629 var sandbox/esi: (addr sandbox) <- address sandbox-storage
630 initialize-sandbox sandbox, 0/no-screen-or-keyboard
631
632 edit-sandbox sandbox, 0x31/1, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
633
634 edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
635
636 var screen-on-stack: screen
637 var screen/edi: (addr screen) <- address screen-on-stack
638 initialize-screen screen, 0x80/width, 0x10/height
639
640 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 0/no-globals
641 check-screen-row screen, 0/y, "1 ", "F - test-run-integer/0"
642 check-screen-row screen, 1/y, "... ", "F - test-run-integer/1"
643 check-screen-row screen, 2/y, "=> 1 ", "F - test-run-integer/2"
644 }
645
646 fn test-run-with-spaces {
647 var sandbox-storage: sandbox
648 var sandbox/esi: (addr sandbox) <- address sandbox-storage
649 initialize-sandbox sandbox, 0/no-screen-or-keyboard
650
651 edit-sandbox sandbox, 0x20/space, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
652 edit-sandbox sandbox, 0x31/1, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
653 edit-sandbox sandbox, 0x20/space, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
654 edit-sandbox sandbox, 0xa/newline, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
655
656 edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
657
658 var screen-on-stack: screen
659 var screen/edi: (addr screen) <- address screen-on-stack
660 initialize-screen screen, 0x80/width, 0x10/height
661
662 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 0/no-globals
663 check-screen-row screen, 0/y, " 1 ", "F - test-run-with-spaces/0"
664 check-screen-row screen, 1/y, " ", "F - test-run-with-spaces/1"
665 check-screen-row screen, 2/y, "... ", "F - test-run-with-spaces/2"
666 check-screen-row screen, 3/y, "=> 1 ", "F - test-run-with-spaces/3"
667 }
668
669 fn test-run-quote {
670 var sandbox-storage: sandbox
671 var sandbox/esi: (addr sandbox) <- address sandbox-storage
672 initialize-sandbox sandbox, 0/no-screen-or-keyboard
673
674 edit-sandbox sandbox, 0x27/quote, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
675 edit-sandbox sandbox, 0x61/a, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
676
677 edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
678
679 var screen-on-stack: screen
680 var screen/edi: (addr screen) <- address screen-on-stack
681 initialize-screen screen, 0x80/width, 0x10/height
682
683 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 0/no-globals
684 check-screen-row screen, 0/y, "'a ", "F - test-run-quote/0"
685 check-screen-row screen, 1/y, "... ", "F - test-run-quote/1"
686 check-screen-row screen, 2/y, "=> a ", "F - test-run-quote/2"
687 }
688
689 fn test-run-error-invalid-integer {
690 var sandbox-storage: sandbox
691 var sandbox/esi: (addr sandbox) <- address sandbox-storage
692 initialize-sandbox sandbox, 0/no-screen-or-keyboard
693
694 edit-sandbox sandbox, 0x31/1, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
695 edit-sandbox sandbox, 0x61/a, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
696
697 edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
698
699 var screen-on-stack: screen
700 var screen/edi: (addr screen) <- address screen-on-stack
701 initialize-screen screen, 0x80/width, 0x10/height
702
703 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 0/no-globals
704 check-screen-row screen, 0/y, "1a ", "F - test-run-error-invalid-integer/0"
705 check-screen-row screen, 1/y, "... ", "F - test-run-error-invalid-integer/0"
706 check-screen-row screen, 2/y, "invalid number ", "F - test-run-error-invalid-integer/2"
707 }
708
709 fn test-run-move-cursor-into-trace {
710 var sandbox-storage: sandbox
711 var sandbox/esi: (addr sandbox) <- address sandbox-storage
712 initialize-sandbox sandbox, 0/no-screen-or-keyboard
713
714 edit-sandbox sandbox, 0x31/1, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
715 edit-sandbox sandbox, 0x32/2, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
716
717 edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
718
719 var screen-on-stack: screen
720 var screen/edi: (addr screen) <- address screen-on-stack
721 initialize-screen screen, 0x80/width, 0x10/height
722
723 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 0/no-globals
724 check-screen-row screen, 0/y, "12 ", "F - test-run-move-cursor-into-trace/pre-0"
725 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " | ", "F - test-run-move-cursor-into-trace/pre-0/cursor"
726 check-screen-row screen, 1/y, "... ", "F - test-run-move-cursor-into-trace/pre-1"
727 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-run-move-cursor-into-trace/pre-1/cursor"
728 check-screen-row screen, 2/y, "=> 12 ", "F - test-run-move-cursor-into-trace/pre-2"
729 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-run-move-cursor-into-trace/pre-2/cursor"
730
731 edit-sandbox sandbox, 9/tab, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
732
733 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 0/no-globals
734 check-screen-row screen, 0/y, "12 ", "F - test-run-move-cursor-into-trace/trace-0"
735 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " ", "F - test-run-move-cursor-into-trace/trace-0/cursor"
736 check-screen-row screen, 1/y, "... ", "F - test-run-move-cursor-into-trace/trace-1"
737 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, "||| ", "F - test-run-move-cursor-into-trace/trace-1/cursor"
738 check-screen-row screen, 2/y, "=> 12 ", "F - test-run-move-cursor-into-trace/trace-2"
739 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-run-move-cursor-into-trace/trace-2/cursor"
740
741 edit-sandbox sandbox, 9/tab, 0/no-globals, 0/no-screen, 0/no-keyboard, 0/no-disk
742
743 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 0/no-globals
744 check-screen-row screen, 0/y, "12 ", "F - test-run-move-cursor-into-trace/input-0"
745 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " | ", "F - test-run-move-cursor-into-trace/input-0/cursor"
746 check-screen-row screen, 1/y, "... ", "F - test-run-move-cursor-into-trace/input-1"
747 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-run-move-cursor-into-trace/input-1/cursor"
748 check-screen-row screen, 2/y, "=> 12 ", "F - test-run-move-cursor-into-trace/input-2"
749 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-run-move-cursor-into-trace/input-2/cursor"
750 }
751
752 fn has-trace? _self: (addr sandbox) -> _/eax: boolean {
753 var self/esi: (addr sandbox) <- copy _self
754 var trace-ah/eax: (addr handle trace) <- get self, trace
755 var _trace/eax: (addr trace) <- lookup *trace-ah
756 var trace/edx: (addr trace) <- copy _trace
757 compare trace, 0
758 {
759 break-if-!=
760 return 0/false
761 }
762 var first-free/ebx: (addr int) <- get trace, first-free
763 compare *first-free, 0
764 {
765 break-if->
766 return 0/false
767 }
768 return 1/true
769 }