1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 container screen [
17 num-rows:num
18 num-columns:num
19 cursor-row:num
20 cursor-column:num
21 data:&:@:screen-cell
22 pending-scroll?:bool
23 top-idx:num
24 ¦ ¦ ¦ ¦ ¦ ¦ ¦
25 ]
26
27 container screen-cell [
28 contents:char
29 color:num
30 ]
31
32 def new-fake-screen w:num, h:num -> result:&:screen [
33 local-scope
34 load-ingredients
35 result <- new screen:type
36 non-zero-width?:bool <- greater-than w, 0
37 assert non-zero-width?, [screen can't have zero width]
38 non-zero-height?:bool <- greater-than h, 0
39 assert non-zero-height?, [screen can't have zero height]
40 bufsize:num <- multiply w, h
41 data:&:@:screen-cell <- new screen-cell:type, bufsize
42 *result <- merge h/num-rows, w/num-columns, 0/cursor-row, 0/cursor-column, data, 0/pending-scroll?, 0/top-idx
43 result <- clear-screen result
44 ]
45
46 def clear-screen screen:&:screen -> screen:&:screen [
47 local-scope
48 load-ingredients
49
50 {
51 ¦ break-if screen
52 ¦
53 ¦ clear-display
54 ¦ return
55 }
56
57 buf:&:@:screen-cell <- get *screen, data:offset
58 max:num <- length *buf
59 i:num <- copy 0
60 {
61 ¦ done?:bool <- greater-or-equal i, max
62 ¦ break-if done?
63 ¦ curr:screen-cell <- merge 0/empty, 7/white
64 ¦ *buf <- put-index *buf, i, curr
65 ¦ i <- add i, 1
66 ¦ loop
67 }
68
69 *screen <- put *screen, cursor-row:offset, 0
70 *screen <- put *screen, cursor-column:offset, 0
71 *screen <- put *screen, top-idx:offset, 0
72 ]
73
74 def fake-screen-is-empty? screen:&:screen -> result:bool [
75 local-scope
76 load-ingredients
77
78 return-unless screen, 1/true
79 buf:&:@:screen-cell <- get *screen, data:offset
80 i:num <- copy 0
81 len:num <- length *buf
82 {
83 ¦ done?:bool <- greater-or-equal i, len
84 ¦ break-if done?
85 ¦ curr:screen-cell <- index *buf, i
86 ¦ curr-contents:char <- get curr, contents:offset
87 ¦ i <- add i, 1
88 ¦ loop-unless curr-contents
89 ¦
90 ¦ return 0/false
91 }
92 return 1/true
93 ]
94
95 def print screen:&:screen, c:char -> screen:&:screen [
96 local-scope
97 load-ingredients
98 color:num, color-found?:bool <- next-ingredient
99 {
100 ¦
101 ¦ break-if color-found?
102 ¦ color <- copy 7/white
103 }
104 bg-color:num, bg-color-found?:bool <- next-ingredient
105 {
106 ¦
107 ¦ break-if bg-color-found?
108 ¦ bg-color <- copy 0/black
109 }
110 c2:num <- character-to-code c
111 trace 90, [print-character], c2
112 {
113 ¦
114 ¦ break-if screen
115 ¦ print-character-to-display c, color, bg-color
116 ¦ return
117 }
118
119
120 width:num <- get *screen, num-columns:offset
121 height:num <- get *screen, num-rows:offset
122 capacity:num <- multiply width, height
123 row:num <- get *screen, cursor-row:offset
124 column:num <- get *screen, cursor-column:offset
125 buf:&:@:screen-cell <- get *screen, data:offset
126
127
128 row <- round row
129 column <- round column
130
131 {
132 ¦ too-far-left?:bool <- lesser-than column, 0
133 ¦ break-unless too-far-left?
134 ¦ column <- copy 0
135 ¦ *screen <- put *screen, cursor-column:offset, column
136 }
137
138 {
139 ¦ at-right?:bool <- greater-or-equal column, width
140 ¦ break-unless at-right?
141 ¦ column <- copy 0
142 ¦ *screen <- put *screen, cursor-column:offset, column
143 ¦ row <- add row, 1
144 ¦ *screen <- put *screen, cursor-row:offset, row
145 }
146
147
148 {
149 ¦ pending-scroll?:bool <- get *screen, pending-scroll?:offset
150 ¦ break-unless pending-scroll?
151
152 ¦ scroll-fake-screen screen
153 ¦ *screen <- put *screen, pending-scroll?:offset, 0/false
154 }
155
156
157 {
158 ¦ newline?:bool <- equal c, 10/newline
159 ¦ break-unless newline?
160 ¦ cursor-down-on-fake-screen screen
161 ¦ return
162 }
163
164 {
165 ¦ linefeed?:bool <- equal c, 13/linefeed
166 ¦ break-unless linefeed?
167 ¦ *screen <- put *screen, cursor-column:offset, 0
168 ¦ return
169 }
170
171
172 {
173 ¦ backspace?:bool <- equal c, 8/backspace
174 ¦ break-unless backspace?
175 ¦ {
176 ¦ ¦ break-unless column
177 ¦ ¦ column <- subtract column, 1
178 ¦ ¦ *screen <- put *screen, cursor-column:offset, column
179 ¦ }
180 ¦ return
181 }
182
183 top-idx:num <- get *screen, top-idx:offset
184 index:num <- data-index row, column, width, height, top-idx
185 cursor:screen-cell <- merge c, color
186 *buf <- put-index *buf, index, cursor
187
188
189 column <- add column, 1
190 {
191 ¦ past-right?:bool <- greater-or-equal column, width
192 ¦ break-unless past-right?
193 ¦ column <- copy 0
194 ¦ row <- add row, 1
195 ¦ past-bottom?:bool <- greater-or-equal row, height
196 ¦ break-unless past-bottom?
197 ¦
198
199 ¦ *screen <- put *screen, pending-scroll?:offset, 1/true
200 ¦ row <- subtract row, 1
201 }
202 *screen <- put *screen, cursor-row:offset, row
203 *screen <- put *screen, cursor-column:offset, column
204 ]
205
206 def cursor-down-on-fake-screen screen:&:screen -> screen:&:screen [
207 local-scope
208 load-ingredients
209
210 row:num <- get *screen, cursor-row:offset
211 height:num <- get *screen, num-rows:offset
212 bottom:num <- subtract height, 1
213 at-bottom?:bool <- greater-or-equal row, bottom
214 {
215 ¦ break-if at-bottom?
216 ¦ row <- add row, 1
217 ¦ *screen <- put *screen, cursor-row:offset, row
218 }
219 {
220 ¦ break-unless at-bottom?
221 ¦ scroll-fake-screen screen
222 }
223 ]
224
225 def scroll-fake-screen screen:&:screen -> screen:&:screen [
226 local-scope
227 load-ingredients
228
229 width:num <- get *screen, num-columns:offset
230 height:num <- get *screen, num-rows:offset
231 buf:&:@:screen-cell <- get *screen, data:offset
232
233 top-idx:num <- get *screen, top-idx:offset
234 next-top-idx:num <- add top-idx, width
235 empty-cell:screen-cell <- merge 0/empty, 7/white
236 {
237 ¦ done?:bool <- greater-or-equal top-idx, next-top-idx
238 ¦ break-if done?
239 ¦ put-index *buf, top-idx, empty-cell
240 ¦ top-idx <- add top-idx, 1
241 ¦
242 ¦
243 ¦ loop
244 }
245
246 capacity:num <- multiply width, height
247 _, top-idx <- divide-with-remainder, top-idx, capacity
248 *screen <- put *screen, top-idx:offset, top-idx
249 ]
250
251
252
253 def data-index row:num, column:num, width:num, height:num, top-idx:num -> result:num [
254 local-scope
255 load-ingredients
256 {
257 ¦ overflow?:bool <- greater-or-equal row, height
258 ¦ break-unless overflow?
259 ¦ row <- subtract height, 1
260 }
261 result <- multiply width, row
262 result <- add result, column, top-idx
263 capacity:num <- multiply width, height
264 _, result <- divide-with-remainder result, capacity
265 ]
266
267 scenario print-character-at-top-left [
268 local-scope
269 fake-screen:&:screen <- new-fake-screen 3/width, 2/height
270 run [
271 ¦ a:char <- copy 97/a
272 ¦ fake-screen <- print fake-screen, a:char
273 ¦ cell:&:@:screen-cell <- get *fake-screen, data:offset
274 ¦ 1:@:screen-cell/raw <- copy *cell
275 ]
276 memory-should-contain [
277 ¦ 1 <- 6
278 ¦ 2 <- 97
279 ¦ 3 <- 7
280 ¦
281 ¦ 4 <- 0
282 ]
283 ]
284
285 scenario print-character-at-fractional-coordinate [
286 local-scope
287 fake-screen:&:screen <- new-fake-screen 3/width, 2/height
288 a:char <- copy 97/a
289 run [
290 ¦ move-cursor fake-screen, 0.5, 0
291 ¦ fake-screen <- print fake-screen, a:char
292 ¦ cell:&:@:screen-cell <- get *fake-screen, data:offset
293 ¦ 1:@:screen-cell/raw <- copy *cell
294 ]
295 memory-should-contain [
296 ¦ 1 <- 6
297 ¦ 2 <- 97
298 ¦ 3 <- 7
299 ¦
300 ¦ 4 <- 0
301 ]
302 ]
303
304 scenario print-character-in-color [
305 local-scope
306 fake-screen:&:screen <- new-fake-screen 3/width, 2/height
307 run [
308 ¦ a:char <- copy 97/a
309 ¦ fake-screen <- print fake-screen, a:char, 1/red
310 ¦ cell:&:@:screen-cell <- get *fake-screen, data:offset
311 ¦ 1:@:screen-cell/raw <- copy *cell
312 ]
313 memory-should-contain [
314 ¦ 1 <- 6
315 ¦ 2 <- 97
316 ¦ 3 <- 1
317 ¦
318 ¦ 4 <- 0
319 ]
320 ]
321
322 scenario print-backspace-character [
323 local-scope
324 fake-screen:&:screen <- new-fake-screen 3/width, 2/height
325 a:char <- copy 97/a
326 fake-screen <- print fake-screen, a
327 run [
328 ¦ backspace:char <- copy 8/backspace
329 ¦ fake-screen <- print fake-screen, backspace
330 ¦ 10:num/raw <- get *fake-screen, cursor-column:offset
331 ¦ cell:&:@:screen-cell <- get *fake-screen, data:offset
332 ¦ 11:@:screen-cell/raw <- copy *cell
333 ]
334 memory-should-contain [
335 ¦ 10 <- 0
336 ¦ 11 <- 6
337 ¦ 12 <- 97
338 ¦ 13 <- 7
339 ¦
340 ¦ 14 <- 0
341 ]
342 ]
343
344 scenario print-extra-backspace-character [
345 local-scope
346 fake-screen:&:screen <- new-fake-screen 3/width, 2/height
347 a:char <- copy 97/a
348 fake-screen <- print fake-screen, a
349 run [
350 ¦ backspace:char <- copy 8/backspace
351 ¦ fake-screen <- print fake-screen, backspace
352 ¦ fake-screen <- print fake-screen, backspace
353 ¦ 1:num/raw <- get *fake-screen, cursor-column:offset
354 ¦ cell:&:@:screen-cell <- get *fake-screen, data:offset
355 ¦ 3:@:screen-cell/raw <- copy *cell
356 ]
357 memory-should-contain [
358 ¦ 1 <- 0
359 ¦ 3 <- 6
360 ¦ 4 <- 97
361 ¦ 5 <- 7
362 ¦
363 ¦ 6 <- 0
364 ]
365 ]
366
367 scenario print-character-at-right-margin [
368
369 local-scope
370 fake-screen:&:screen <- new-fake-screen 2/width, 2/height
371 a:char <- copy 97/a
372 fake-screen <- print fake-screen, a
373 b:char <- copy 98/b
374 fake-screen <- print fake-screen, b
375 run [
376 ¦
377 ¦ c:char <- copy 99/c
378 ¦ fake-screen <- print fake-screen, c
379 ¦ 10:num/raw <- get *fake-screen, cursor-row:offset
380 ¦ 11:num/raw <- get *fake-screen, cursor-column:offset
381 ¦ cell:&:@:screen-cell <- get *fake-screen, data:offset
382 ¦ 12:@:screen-cell/raw <- copy *cell
383 ]
384 memory-should-contain [
385 ¦ 10 <- 1
386 ¦ 11 <- 1
387 ¦ 12 <- 4
388 ¦ 13 <- 97
389 ¦ 14 <- 7
390 ¦ 15 <- 98
391 ¦ 16 <- 7
392 ¦ 17 <- 99
393 ¦ 18 <- 7
394 ¦ 19 <- 0
395 ¦ 20 <- 7
396 ]
397 ]
398
399 scenario print-newline-character [
400 local-scope
401 fake-screen:&:screen <- new-fake-screen 3/width, 2/height
402 a:char <- copy 97/a
403 fake-screen <- print fake-screen, a
404 run [
405 ¦ newline:char <- copy 10/newline
406 ¦ fake-screen <- print fake-screen, newline
407 ¦ 10:num/raw <- get *fake-screen, cursor-row:offset
408 ¦ 11:num/raw <- get *fake-screen, cursor-column:offset
409 ¦ cell:&:@:screen-cell <- get *fake-screen, data:offset
410 ¦ 12:@:screen-cell/raw <- copy *cell
411 ]
412 memory-should-contain [
413 ¦ 10 <- 1
414 ¦ 11 <- 1
415 ¦ 12 <- 6
416 ¦ 13 <- 97
417 ¦ 14 <- 7
418 ¦
419 ¦ 15 <- 0
420 ]
421 ]
422
423 scenario print-newline-at-bottom-line [
424 local-scope
425 fake-screen:&:screen <- new-fake-screen 3/width, 2/height
426 newline:char <- copy 10/newline
427 fake-screen <- print fake-screen, newline
428 fake-screen <- print fake-screen, newline
429 run [
430 ¦
431 ¦ fake-screen <- print fake-screen, newline
432 ¦ 10:num/raw <- get *fake-screen, cursor-row:offset
433 ¦ 11:num/raw <- get *fake-screen, cursor-column:offset
434 ]
435
436 memory-should-contain [
437 ¦ 10 <- 1
438 ¦ 11 <- 0
439 ]
440 ]
441
442 scenario print-character-at-bottom-right [
443 local-scope
444 fake-screen:&:screen <- new-fake-screen 2/width, 2/height
445 a:char <- copy 97/a
446 fake-screen <- print fake-screen, a
447 b:char <- copy 98/b
448 fake-screen <- print fake-screen, b
449 c:char <- copy 99/c
450 fake-screen <- print fake-screen, c
451 run [
452 ¦
453 ¦ d:char <- copy 100/d
454 ¦ fake-screen <- print fake-screen, d
455 ¦ 10:num/raw <- get *fake-screen, cursor-row:offset
456 ¦ 11:num/raw <- get *fake-screen, cursor-column:offset
457 ¦ 12:num/raw <- get *fake-screen, top-idx:offset
458 ¦ 13:num/raw <- get *fake-screen, pending-scroll?:offset
459 ¦ cell:&:@:screen-cell <- get *fake-screen, data:offset
460 ¦ 20:@:screen-cell/raw <- copy *cell
461 ]
462
463 memory-should-contain [
464 ¦ 10 <- 1
465 ¦ 11 <- 0
466 ¦ 12 <- 0
467 ¦ 13 <- 1
468 ¦ 20 <- 4
469 ¦ 21 <- 97
470 ¦ 22 <- 7
471 ¦ 23 <- 98
472 ¦ 24 <- 7
473 ¦ 25 <- 99
474 ¦ 26 <- 7
475 ¦ 27 <- 100
476 ¦ 28 <- 7
477 ]
478 run [
479 ¦ e:char <- copy 101/e
480 ¦ print fake-screen, e
481 ¦ 10:num/raw <- get *fake-screen, cursor-row:offset
482 ¦ 11:num/raw <- get *fake-screen, cursor-column:offset
483 ¦ 12:num/raw <- get *fake-screen, top-idx:offset
484 ¦ cell:&:@:screen-cell <- get *fake-screen, data:offset
485 ¦ 20:@:screen-cell/raw <- copy *cell
486 ]
487 memory-should-contain [
488 ¦
489 ¦ 10 <- 1
490 ¦ 11 <- 1
491 ¦ 12 <- 2
492 ¦ 20 <- 4
493 ¦
494 ¦ 25 <- 99
495 ¦ 26 <- 7
496 ¦ 27 <- 100
497 ¦ 28 <- 7
498 ¦
499 ¦ 21 <- 101
500 ¦ 22 <- 7
501 ¦ 23 <- 0
502 ¦ 24 <- 7
503 ]
504 ]
505
506
507
508
509 def save-top-idx screen:&:screen -> result:num [
510 local-scope
511 load-ingredients
512 return-unless screen, 0
513 result <- get *screen, top-idx:offset
514 ]
515 def assert-no-scroll screen:&:screen, old-top-idx:num [
516 local-scope
517 load-ingredients
518 return-unless screen
519 new-top-idx:num <- get *screen, top-idx:offset
520 no-scroll?:bool <- equal old-top-idx, new-top-idx
521 assert no-scroll?, [render should never use screen's scrolling capabilities]
522 ]
523
524 def clear-line screen:&:screen -> screen:&:screen [
525 local-scope
526 load-ingredients
527
528 space:char <- copy 0/nul
529 {
530 ¦ break-if screen
531 ¦
532 ¦ clear-line-on-display
533 ¦ return
534 }
535
536 width:num <- get *screen, num-columns:offset
537 column:num <- get *screen, cursor-column:offset
538 original-column:num <- copy column
539
540 {
541 ¦ right:num <- subtract width, 1
542 ¦ done?:bool <- greater-or-equal column, right
543 ¦ break-if done?
544 ¦ print screen, space
545 ¦ column <- add column, 1
546 ¦ loop
547 }
548
549 *screen <- put *screen, cursor-column:offset, original-column
550 ]
551
552
553 def clear-line-until screen:&:screen, right:num/inclusive -> screen:&:screen [
554 local-scope
555 load-ingredients
556 row:num, column:num <- cursor-position screen
557
558 height:num <- screen-height screen
559 past-bottom?:bool <- greater-or-equal row, height
560 return-if past-bottom?
561 space:char <- copy 32/space
562 bg-color:num, bg-color-found?:bool <- next-ingredient
563 {
564 ¦
565 ¦ break-if bg-color-found?
566 ¦ bg-color <- copy 0/black
567 }
568 {
569 ¦ done?:bool <- greater-than column, right
570 ¦ break-if done?
571 ¦ screen <- print screen, space, 7/white, bg-color
572 ¦ column <- add column, 1
573 ¦ loop
574 }
575 ]
576
577 def cursor-position screen:&:screen -> row:num, column:num [
578 local-scope
579 load-ingredients
580 {
581 ¦ break-if screen
582 ¦
583 ¦ row, column <- cursor-position-on-display
584 ¦ return
585 }
586
587 row:num <- get *screen, cursor-row:offset
588 column:num <- get *screen, cursor-column:offset
589 ]
590
591 def move-cursor screen:&:screen, new-row:num, new-column:num -> screen:&:screen [
592 local-scope
593 load-ingredients
594
595 {
596 ¦ break-if screen
597 ¦
598 ¦ move-cursor-on-display new-row, new-column
599 ¦ return
600 }
601
602 *screen <- put *screen, cursor-row:offset, new-row
603 *screen <- put *screen, cursor-column:offset, new-column
604
605 {
606 ¦ width:num <- get *screen, num-columns:offset
607 ¦ scroll?:bool <- greater-or-equal new-column, width
608 ¦ break-if scroll?
609
610 ¦ *screen <- put *screen, pending-scroll?:offset, 0/false
611 }
612 ]
613
614 scenario clear-line-erases-printed-characters [
615 local-scope
616 fake-screen:&:screen <- new-fake-screen 3/width, 2/height
617
618 a:char <- copy 97/a
619 fake-screen <- print fake-screen, a
620
621 fake-screen <- move-cursor fake-screen, 0/row, 0/column
622 run [
623 ¦ fake-screen <- clear-line fake-screen
624 ¦ cell:&:@:screen-cell <- get *fake-screen, data:offset
625 ¦ 10:@:screen-cell/raw <- copy *cell
626 ]
627
628 memory-should-contain [
629 ¦ 10 <- 6
630 ¦ 11 <- 0
631 ¦ 12 <- 7
632 ¦ 13 <- 0
633 ¦ 14 <- 7
634 ¦ 15 <- 0
635 ¦ 16 <- 7
636 ¦ 17 <- 0
637 ¦ 18 <- 7
638 ¦ 19 <- 0
639 ¦ 20 <- 7
640 ¦ 21 <- 0
641 ¦ 22 <- 7
642 ]
643 ]
644
645 def cursor-down screen:&:screen -> screen:&:screen [
646 local-scope
647 load-ingredients
648
649 {
650 ¦ break-if screen
651 ¦
652 ¦ move-cursor-down-on-display
653 ¦ return
654 }
655
656 cursor-down-on-fake-screen screen
657 ]
658
659 scenario cursor-down-scrolls [
660 local-scope
661 fake-screen:&:screen <- new-fake-screen 3/width, 2/height
662
663 run [
664 ¦ print fake-screen, [abc]
665 ¦ cursor-to-next-line fake-screen
666 ¦ cursor-to-next-line fake-screen
667 ¦ data:&:@:screen-cell <- get *fake-screen, data:offset
668 ¦ 10:@:screen-cell/raw <- copy *data
669 ]
670
671 memory-should-contain [
672 ¦ 10 <- 6
673 ¦ 11 <- 0
674 ¦ 12 <- 7
675 ¦ 13 <- 0
676 ¦ 14 <- 7
677 ¦ 15 <- 0
678 ¦ 16 <- 7
679 ¦ 17 <- 0
680 ¦ 18 <- 7
681 ¦ 19 <- 0
682 ¦ 20 <- 7
683 ¦ 21 <- 0
684 ¦ 22 <- 7
685 ]
686 ]
687
688 def cursor-up screen:&:screen -> screen:&:screen [
689 local-scope
690 load-ingredients
691
692 {
693 ¦ break-if screen
694 ¦
695 ¦ move-cursor-up-on-display
696 ¦ return
697 }
698
699 row:num <- get *screen, cursor-row:offset
700 at-top?:bool <- lesser-or-equal row, 0
701 return-if at-top?
702 row <- subtract row, 1
703 *screen <- put *screen, cursor-row:offset, row
704 ]
705
706 def cursor-right screen:&:screen -> screen:&:screen [
707 local-scope
708 load-ingredients
709
710 {
711 ¦ break-if screen
712 ¦
713 ¦ move-cursor-right-on-display
714 ¦ return
715 }
716
717 width:num <- get *screen, num-columns:offset
718 column:num <- get *screen, cursor-column:offset
719 max:num <- subtract width, 1
720 at-bottom?:bool <- greater-or-equal column, max
721 return-if at-bottom?
722 column <- add column, 1
723 *screen <- put *screen, cursor-column:offset, column
724 ]
725
726 def cursor-left screen:&:screen -> screen:&:screen [
727 local-scope
728 load-ingredients
729
730 {
731 ¦ break-if screen
732 ¦
733 ¦ move-cursor-left-on-display
734 ¦ return
735 }
736
737 column:num <- get *screen, cursor-column:offset
738 at-top?:bool <- lesser-or-equal column, 0
739 return-if at-top?
740 column <- subtract column, 1
741 *screen <- put *screen, cursor-column:offset, column
742 ]
743
744 def cursor-to-start-of-line screen:&:screen -> screen:&:screen [
745 local-scope
746 load-ingredients
747
748 row:num <- cursor-position screen
749 screen <- move-cursor screen, row, 0/column
750 ]
751
752 def cursor-to-next-line screen:&:screen -> screen:&:screen [
753 local-scope
754 load-ingredients
755
756 screen <- cursor-down screen
757 screen <- cursor-to-start-of-line screen
758 ]
759
760 def move-cursor-to-column screen:&:screen, column:num -> screen:&:screen [
761 local-scope
762 load-ingredients
763 row:num, _ <- cursor-position screen
764
765 move-cursor screen, row, column
766 ]
767
768 def screen-width screen:&:screen -> width:num [
769 local-scope
770 load-ingredients
771
772 {
773 ¦ break-unless screen
774 ¦
775 ¦ width <- get *screen, num-columns:offset
776 ¦ return
777 }
778
779 width <- display-width
780 ]
781
782 def screen-height screen:&:screen -> height:num [
783 local-scope
784 load-ingredients
785
786 {
787 ¦ break-unless screen
788 ¦
789 ¦ height <- get *screen, num-rows:offset
790 ¦ return
791 }
792
793 height <- display-height
794 ]
795
796 def print screen:&:screen, s:text -> screen:&:screen [
797 local-scope
798 load-ingredients
799 color:num, color-found?:bool <- next-ingredient
800 {
801 ¦
802 ¦ break-if color-found?
803 ¦ color <- copy 7/white
804 }
805 bg-color:num, bg-color-found?:bool <- next-ingredient
806 {
807 ¦
808 ¦ break-if bg-color-found?
809 ¦ bg-color <- copy 0/black
810 }
811 len:num <- length *s
812 i:num <- copy 0
813 {
814 ¦ done?:bool <- greater-or-equal i, len
815 ¦ break-if done?
816 ¦ c:char <- index *s, i
817 ¦ print screen, c, color, bg-color
818 ¦ i <- add i, 1
819 ¦ loop
820 }
821 ]
822
823 scenario print-text-wraps-past-right-margin [
824 local-scope
825 fake-screen:&:screen <- new-fake-screen 3/width, 2/height
826 run [
827 ¦ fake-screen <- print fake-screen, [abcd]
828 ¦ 5:num/raw <- get *fake-screen, cursor-row:offset
829 ¦ 6:num/raw <- get *fake-screen, cursor-column:offset
830 ¦ 7:num/raw <- get *fake-screen, top-idx:offset
831 ¦ cell:&:@:screen-cell <- get *fake-screen, data:offset
832 ¦ 10:@:screen-cell/raw <- copy *cell
833 ]
834 memory-should-contain [
835 ¦ 5 <- 1
836 ¦ 6 <- 1
837 ¦ 7 <- 0
838 ¦ 10 <- 6
839 ¦ 11 <- 97
840 ¦ 12 <- 7
841 ¦ 13 <- 98
842 ¦ 14 <- 7
843 ¦ 15 <- 99
844 ¦ 16 <- 7
845 ¦ 17 <- 100
846 ¦ 18 <- 7
847 ¦
848 ¦ 19 <- 0
849 ]
850 ]
851
852 def print screen:&:screen, n:num -> screen:&:screen [
853 local-scope
854 load-ingredients
855 color:num, color-found?:bool <- next-ingredient
856 {
857 ¦
858 ¦ break-if color-found?
859 ¦ color <- copy 7/white
860 }
861 bg-color:num, bg-color-found?:bool <- next-ingredient
862 {
863 ¦
864 ¦ break-if bg-color-found?
865 ¦ bg-color <- copy 0/black
866 }
867
868 s:text <- to-text n
869 screen <- print screen, s, color, bg-color
870 ]
871
872 def print screen:&:screen, n:bool -> screen:&:screen [
873 local-scope
874 load-ingredients
875 color:num, color-found?:bool <- next-ingredient
876 {
877 ¦
878 ¦ break-if color-found?
879 ¦ color <- copy 7/white
880 }
881 bg-color:num, bg-color-found?:bool <- next-ingredient
882 {
883 ¦
884 ¦ break-if bg-color-found?
885 ¦ bg-color <- copy 0/black
886 }
887 n2:num <- copy n
888 screen <- print screen, n2, color, bg-color
889 ]
890
891 def print screen:&:screen, n:&:_elem -> screen:&:screen [
892 local-scope
893 load-ingredients
894 color:num, color-found?:bool <- next-ingredient
895 {
896 ¦
897 ¦ break-if color-found?
898 ¦ color <- copy 7/white
899 }
900 bg-color:num, bg-color-found?:bool <- next-ingredient
901 {
902 ¦
903 ¦ break-if bg-color-found?
904 ¦ bg-color <- copy 0/black
905 }
906 n2:num <- copy n
907 screen <- print screen, n2, color, bg-color
908 ]