<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Mu - 071print.mu</title>
<meta name="Generator" content="Vim/7.4">
<meta name="plugin-version" content="vim7.4_v1">
<meta name="syntax" content="none">
<meta name="settings" content="use_css,pre_wrap,no_foldcolumn,expand_tabs,prevent_copy=">
<meta name="colorscheme" content="minimal">
<style type="text/css">
<!--
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
.Special { color: #ff6060; }
.Comment { color: #9090ff; }
.Underlined { color: #c000c0; text-decoration: underline; }
.Identifier { color: #804000; }
-->
</style>
<script type='text/javascript'>
<!--
-->
</script>
</head>
<body>
<pre id='vimCodeElement'>
<span class="Comment"># Wrappers around print primitives that take a 'screen' object and are thus</span>
<span class="Comment"># easier to test.</span>
container screen [
num-rows:number
num-columns:number
cursor-row:number
cursor-column:number
data:address:<span class="Identifier">array</span>:screen-cell
]
container screen-cell [
contents:character
color:number
]
recipe <span class="Identifier">new</span>-fake-screen [
<span class="Underlined">local</span>-scope
result:address:screen<span class="Special"> <- </span><span class="Identifier">new</span> screen:<span class="Identifier">type</span>
width:address:number<span class="Special"> <- </span>get-address *result, num-columns:offset
*width<span class="Special"> <- </span>next-ingredient
height:address:number<span class="Special"> <- </span>get-address *result, num-rows:offset
*height<span class="Special"> <- </span>next-ingredient
row:address:number<span class="Special"> <- </span>get-address *result, cursor-row:offset
*row<span class="Special"> <- </span><span class="Identifier">copy</span> 0
column:address:number<span class="Special"> <- </span>get-address *result, cursor-column:offset
*column<span class="Special"> <- </span><span class="Identifier">copy</span> 0
bufsize:number<span class="Special"> <- </span>multiply *width, *height
buf:address:address:<span class="Identifier">array</span>:screen-cell<span class="Special"> <- </span>get-address *result, data:offset
*buf<span class="Special"> <- </span><span class="Identifier">new</span> screen-cell:<span class="Identifier">type</span>, bufsize
clear-screen result
reply result
]
recipe clear-screen [
<span class="Underlined">local</span>-scope
sc:address:screen<span class="Special"> <- </span>next-ingredient
<span class="Comment"># if x exists</span>
{
break-unless sc
<span class="Comment"># clear fake screen</span>
buf:address:<span class="Identifier">array</span>:screen-cell<span class="Special"> <- </span>get *sc, data:offset
<span class="Identifier">max</span>:number<span class="Special"> <- </span><span class="Identifier">length</span> *buf
i:number<span class="Special"> <- </span><span class="Identifier">copy</span> 0
{
done?:boolean<span class="Special"> <- </span>greater-or-equal i, <span class="Identifier">max</span>
break-if done?
curr:address:screen-cell<span class="Special"> <- </span>index-address *buf, i
curr-<span class="Identifier">content</span>:address:character<span class="Special"> <- </span>get-address *curr, contents:offset
*curr-<span class="Identifier">content</span><span class="Special"> <- </span><span class="Identifier">copy</span> [ ]
curr-color:address:character<span class="Special"> <- </span>get-address *curr, color:offset
*curr-color<span class="Special"> <- </span><span class="Identifier">copy</span> 7/white
i<span class="Special"> <- </span>add i, 1
loop
}
<span class="Comment"># reset cursor</span>
x:address:number<span class="Special"> <- </span>get-address *sc, cursor-row:offset
*x<span class="Special"> <- </span><span class="Identifier">copy</span> 0
x<span class="Special"> <- </span>get-address *sc, cursor-column:offset
*x<span class="Special"> <- </span><span class="Identifier">copy</span> 0
reply sc/same-as-ingredient:0
}
<span class="Comment"># otherwise, real screen</span>
clear-display
reply sc/same-as-ingredient:0
]
recipe sync-screen [
<span class="Underlined">local</span>-scope
sc:address:screen<span class="Special"> <- </span>next-ingredient
{
break-if sc
sync-display
}
<span class="Comment"># do nothing for fake screens</span>
]
recipe fake-screen-<span class="Identifier">is</span>-empty? [
<span class="Underlined">local</span>-scope
sc:address:screen<span class="Special"> <- </span>next-ingredient
reply-unless sc, 1/true
buf:address:<span class="Identifier">array</span>:screen-cell<span class="Special"> <- </span>get *sc, data:offset
i:number<span class="Special"> <- </span><span class="Identifier">copy</span> 0
len:number<span class="Special"> <- </span><span class="Identifier">length</span> *buf
{
done?:boolean<span class="Special"> <- </span>greater-or-equal i, len
break-if done?
curr:screen-cell<span class="Special"> <- </span>index *buf, i
curr-contents:character<span class="Special"> <- </span>get curr, contents:offset
i<span class="Special"> <- </span>add i, 1
loop-unless curr-contents
<span class="Comment"># not 0</span>
reply 0/false
}
reply 1/true
]
recipe <span class="Identifier">print</span>-character [
<span class="Underlined">local</span>-scope
sc:address:screen<span class="Special"> <- </span>next-ingredient
c:character<span class="Special"> <- </span>next-ingredient
color:number, color-found?:boolean<span class="Special"> <- </span>next-ingredient
{
<span class="Comment"># default color to white</span>
break-if color-found?
color<span class="Special"> <- </span><span class="Identifier">copy</span> 7/white
}
bg-color:number, bg-color-found?:boolean<span class="Special"> <- </span>next-ingredient
{
<span class="Comment"># default bg-color to black</span>
break-if bg-color-found?
bg-color<span class="Special"> <- </span><span class="Identifier">copy</span> 0/black
}
trace 90, [<span class="Identifier">print</span>-character], c
{
<span class="Comment"># if x exists</span>
<span class="Comment"># (handle special cases exactly like in the real screen)</span>
break-unless sc
width:number<span class="Special"> <- </span>get *sc, num-columns:offset
height:number<span class="Special"> <- </span>get *sc, num-rows:offset
<span class="Comment"># if cursor is out of bounds, silently exit</span>
row:address:number<span class="Special"> <- </span>get-address *sc, cursor-row:offset
legal?:boolean<span class="Special"> <- </span>greater-or-equal *row, 0
reply-unless legal?, sc
legal?<span class="Special"> <- </span>lesser-than *row, height
reply-unless legal?, sc
column:address:number<span class="Special"> <- </span>get-address *sc, cursor-column:offset
legal?<span class="Special"> <- </span>greater-or-equal *column, 0
reply-unless legal?, sc
legal?<span class="Special"> <- </span>lesser-than *column, width
reply-unless legal?, sc
<span class="Comment"># special-case: newline</span>
{
newline?:boolean<span class="Special"> <- </span>equal c, 10/newline
break-unless newline?
{
<span class="Comment"># unless cursor is already at bottom</span>
bottom:number<span class="Special"> <- </span>subtract height, 1
at-bottom?:boolean<span class="Special"> <- </span>greater-or-equal *row, bottom
break-if at-bottom?
<span class="Comment"># move it to the next row</span>
*column<span class="Special"> <- </span><span class="Identifier">copy</span> 0
*row<span class="Special"> <- </span>add *row, 1
}
reply sc/same-as-ingredient:0
}
<span class="Comment"># save character in fake screen</span>
index:number<span class="Special"> <- </span>multiply *row, width
index<span class="Special"> <- </span>add index, *column
buf:address:<span class="Identifier">array</span>:screen-cell<span class="Special"> <- </span>get *sc, data:offset
len:number<span class="Special"> <- </span><span class="Identifier">length</span> *buf
<span class="Comment"># special-case: backspace</span>
{
backspace?:boolean<span class="Special"> <- </span>equal c, 8
break-unless backspace?
{
<span class="Comment"># unless cursor is already at left margin</span>
at-left?:boolean<span class="Special"> <- </span>lesser-or-equal *column, 0
break-if at-left?
<span class="Comment"># clear previous location</span>
*column<span class="Special"> <- </span>subtract *column, 1
index<span class="Special"> <- </span>subtract index, 1
cursor:address:screen-cell<span class="Special"> <- </span>index-address *buf, index
cursor-contents:address:character<span class="Special"> <- </span>get-address *cursor, contents:offset
*cursor-contents<span class="Special"> <- </span><span class="Identifier">copy</span> 32/space
cursor-color:address:number<span class="Special"> <- </span>get-address *cursor, color:offset
*cursor-color<span class="Special"> <- </span><span class="Identifier">copy</span> 7/white
}
reply sc/same-as-ingredient:0
}
cursor:address:screen-cell<span class="Special"> <- </span>index-address *buf, index
cursor-contents:address:character<span class="Special"> <- </span>get-address *cursor, contents:offset
*cursor-contents<span class="Special"> <- </span><span class="Identifier">copy</span> c
cursor-color:address:number<span class="Special"> <- </span>get-address *cursor, color:offset
*cursor-color<span class="Special"> <- </span><span class="Identifier">copy</span> color
<span class="Comment"># increment column unless it's already all the way to the right</span>
{
right:number<span class="Special"> <- </span>subtract width, 1
at-right?:boolean<span class="Special"> <- </span>greater-or-equal *column, right
break-if at-right?
*column<span class="Special"> <- </span>add *column, 1
}
reply sc/same-as-ingredient:0
}
<span class="Comment"># otherwise, real screen</span>
<span class="Identifier">print</span>-character-to-display c, color, bg-color
reply sc/same-as-ingredient:0
]
scenario <span class="Identifier">print</span>-character-at-top-left [
run [
1:address:screen<span class="Special"> <- </span><span class="Identifier">new</span>-fake-screen 3/width, 2/height
1:address:screen<span class="Special"> <- </span><span class="Identifier">print</span>-character 1:address:screen, 97 <span class="Comment"># 'a'</span>
2:address:<span class="Identifier">array</span>:screen-cell<span class="Special"> <- </span>get *1:address:screen, data:offset
3:<span class="Identifier">array</span>:screen-cell<span class="Special"> <- </span><span class="Identifier">copy</span> *2:address:<span class="Identifier">array</span>:screen-cell
]
memory-should-contain [
3<span class="Special"> <- </span>6 <span class="Comment"># width*height</span>
4<span class="Special"> <- </span>97 <span class="Comment"># 'a'</span>
5<span class="Special"> <- </span>7 <span class="Comment"># white</span>
6<span class="Special"> <- </span>0
]
]
scenario <span class="Identifier">print</span>-character-color [
run [
1:address:screen<span class="Special"> <- </span><span class="Identifier">new</span>-fake-screen 3/width, 2/height
1:address:screen<span class="Special"> <- </span><span class="Identifier">print</span>-character 1:address:screen, 97/a, 1/red
2:address:<span class="Identifier">array</span>:screen-cell<span class="Special"> <- </span>get *1:address:screen, data:offset
3:<span class="Identifier">array</span>:screen-cell<span class="Special"> <- </span><span class="Identifier">copy</span> *2:address:<span class="Identifier">array</span>:screen-cell
]
memory-should-contain [
3<span class="Special"> <- </span>6 <span class="Comment"># width*height</span>
4<span class="Special"> <- </span>97 <span class="Comment"># 'a'</span>
5<span class="Special"> <- </span>1 <span class="Comment"># red</span>
6<span class="Special"> <- </span>0
]
]
scenario <span class="Identifier">print</span>-backspace-character [
run [
1:address:screen<span class="Special"> <- </span><span class="Identifier">new</span>-fake-screen 3/width, 2/height
1:address:screen<span class="Special"> <- </span><span class="Identifier">print</span>-character 1:address:screen, 97 <span class="Comment"># 'a'</span>
1:address:screen<span class="Special"> <- </span><span class="Identifier">print</span>-character 1:address:screen, 8 <span class="Comment"># backspace</span>
2:number<span class="Special"> <- </span>get *1:address:screen, cursor-column:offset
3:address:<span class="Identifier">array</span>:screen-cell<span class="Special"> <- </span>get *1:address:screen, data:offset
4:<span class="Identifier">array</span>:screen-cell<span class="Special"> <- </span><span class="Identifier">copy</span> *3:address:<span class="Identifier">array</span>:screen-cell
]
memory-should-contain [
2<span class="Special"> <- </span>0 <span class="Comment"># cursor column</span>
4<span class="Special"> <- </span>6 <span class="Comment"># width*height</span>
5<span class="Special"> <- </span>32 <span class="Comment"># space, not 'a'</span>
6<span class="Special"> <- </span>7 <span class="Comment"># white</span>
7<span class="Special"> <- </span>0
]
]
scenario <span class="Identifier">print</span>-extra-backspace-character [
run [
1:address:screen<span class="Special"> <- </span><span class="Identifier">new</span>-fake-screen 3/width, 2/height
1:address:screen<span class="Special"> <- </span><span class="Identifier">print</span>-character 1:address:screen, 97 <span class="Comment"># 'a'</span>
1:address:screen<span class="Special"> <- </span><span class="Identifier">print</span>-character 1:address:screen, 8 <span class="Comment"># backspace</span>
1:address:screen<span class="Special"> <- </span><span class="Identifier">print</span>-character 1:address:screen, 8 <span class="Comment"># backspace</span>
2:number<span class="Special"> <- </span>get *1:address:screen, cursor-column:offset
3:address:<span class="Identifier">array</span>:screen-cell<span class="Special"> <- </span>get *1:address:screen, data:offset
4:<span class="Identifier">array</span>:screen-cell<span class="Special"> <- </span><span class="Identifier">copy</span> *3:address:<span class="Identifier">array</span>:screen-cell
]
memory-should-contain [
2<span class="Special"> <- </span>0 <span class="Comment"># cursor column</span>
4<span class="Special"> <- </span>6 <span class="Comment"># width*height</span>
5<span class="Special"> <- </span>32 <span class="Comment"># space, not 'a'</span>
6<span class="Special"> <- </span>7 <span class="Comment"># white</span>
7<span class="Special"> <- </span>0
]
]
scenario <span class="Identifier">print</span>-at-right-margin [
run [
1:address:screen<span class="Special"> <- </span><span class="Identifier">new</span>-fake-screen 2/width, 2/height
1:address:screen<span class="Special"> <- </span><span class="Identifier">print</span>-character 1:address:screen, 97 <span class="Comment"># 'a'</span>
1:address:screen<span class="Special"> <- </span><span class="Identifier">print</span>-character 1:address:screen, 98 <span class="Comment"># 'b'</span>
1:address:screen<span class="Special"> <- </span><span class="Identifier">print</span>-character 1:address:screen, 99 <span class="Comment"># 'c'</span>
2:number<span class="Special"> <- </span>get *1:address:screen, cursor-column:offset
3:address:<span class="Identifier">array</span>:screen-cell<span class="Special"> <- </span>get *1:address:screen, data:offset
4:<span class="Identifier">array</span>:screen-cell<span class="Special"> <- </span><span class="Identifier">copy</span> *3:address:<span class="Identifier">array</span>:screen-cell
]
memory-should-contain [
2<span class="Special"> <- </span>1 <span class="Comment"># cursor column</span>
4<span class="Special"> <- </span>4 <span class="Comment"># width*height</span>
5<span class="Special"> <- </span>97 <span class="Comment"># 'a'</span>
6<span class="Special"> <- </span>7 <span class="Comment"># white</span>
7<span class="Special"> <- </span>99 <span class="Comment"># 'c' over 'b'</span>
8<span class="Special"> <- </span>7 <span class="Comment"># white</span>
9<span class="Special"> <- </span>0
]
]
scenario <span class="Identifier">print</span>-newline-character [
run [
1:address:screen<span class="Special"> <- </span><span class="Identifier">new</span>-fake-screen 3/width, 2/height
1:address:screen<span class="Special"> <- </span><span class="Identifier">print</span>-character 1:address:screen, 97 <span class="Comment"># 'a'</span>
1:address:screen<span class="Special"> <- </span><span class="Identifier">print</span>-character 1:address:screen, 10/newline
2:number<span class="Special"> <- </span>get *1:address:screen, cursor-row:offset
3:number<span class="Special"> <- </span>get *1:address:screen, cursor-column:offset
4:address:<span class="Identifier">array</span>:screen-cell<span class="Special"> <- </span>get *1:address:screen, data:offset
5:<span class="Identifier">array</span>:screen-cell<span class="Special"> <- </span><span class="Identifier">copy</span> *4:address:<span class="Identifier">array</span>:screen-cell
]
memory-should-contain [
2<span class="Special"> <- </span>1 <span class="Comment"># cursor row</span>
3<span class="Special"> <- </span>0 <span class="Comment"># cursor column</span>
5<span class="Special"> <- </span>6 <span class="Comment"># width*height</span>
6<span class="Special"> <- </span>97 <span class="Comment"># 'a'</span>
7<span class="Special"> <- </span>7 <span class="Comment"># white</span>
8<span class="Special"> <- </span>0
]
]
scenario <span class="Identifier">print</span>-newline-at-bottom-line [
run [
1:address:screen<span class="Special"> <- </span><span class="Identifier">new</span>-fake-screen 3/width, 2/height
1:address:screen<span class="Special"> <- </span><span class="Identifier">print</span>-character 1:address:screen, 10/newline
1:address:screen<span class="Special"> <- </span><span class="Identifier">print</span>-character 1:address:screen, 10/newline
1:address:screen<span class="Special"> <- </span><span class="Identifier">print</span>-character 1:address:screen, 10/newline
2:number<span class="Special"> <- </span>get *1:address:screen, cursor-row:offset
3:number<span class="Special"> <- </span>get *1:address:screen, cursor-column:offset
]
memory-should-contain [
2<span class="Special"> <- </span>1 <span class="Comment"># cursor row</span>
3<span class="Special"> <- </span>0 <span class="Comment"># cursor column</span>
]
]
scenario <span class="Identifier">print</span>-at-bottom-right [
run [
1:address:screen<span class="Special"> <- </span><span class="Identifier">new</span>-fake-screen 2/width, 2/height
1:address:screen<span class="Special"> <- </span><span class="Identifier">print</span>-character 1:address:screen, 10/newline
1:address:screen<span class="Special"> <- </span><span class="Identifier">print</span>-character 1:address:screen, 97 <span class="Comment"># 'a'</span>
1:address:screen<span class="Special"> <- </span><span class="Identifier">print</span>-character 1:address:screen, 98 <span class="Comment"># 'b'</span>
1:address:screen<span class="Special"> <- </span><span class="Identifier">print</span>-character 1:address:screen, 99 <span class="Comment"># 'c'</span>
1:address:screen<span class="Special"> <- </span><span class="Identifier">print</span>-character 1:address:screen, 10/newline
1:address:screen<span class="Special"> <- </span><span class="Identifier">print</span>-character 1:address:screen, 100 <span class="Comment"># 'd'</span>
2:number<span class="Special"> <- </span>get *1:address:screen, cursor-row:offset
3:number<span class="Special"> <- </span>get *1:address:screen, cursor-column:offset
4:address:<span class="Identifier">array</span>:screen-cell<span class="Special"> <- </span>get *1:address:screen, data:offset
5:<span class="Identifier">array</span>:screen-cell<span class="Special"> <- </span><span class="Identifier">copy</span> *4:address:<span class="Identifier">array</span>:screen-cell
]
memory-should-contain [
2<span class="Special"> <- </span>1 <span class="Comment"># cursor row</span>
3<span class="Special"> <- </span>1 <span class="Comment"># cursor column</span>
5<span class="Special"> <- </span>4 <span class="Comment"># width*height</span>
6<span class="Special"> <- </span>0 <span class="Comment"># unused</span>
7<span class="Special"> <- </span>7 <span class="Comment"># white</span>
8<span class="Special"> <- </span>0 <span class="Comment"># unused</span>
9<span class="Special"> <- </span>7 <span class="Comment"># white</span>
10<span class="Special"> <- </span>97 <span class="Comment"># 'a'</span>
11<span class="Special"> <- </span>7 <span class="Comment"># white</span>
12<span class="Special"> <- </span>100 <span class="Comment"># 'd' over 'b' and 'c' and newline</span>
13<span class="Special"> <- </span>7 <span class="Comment"># white</span>
14<span class="Special"> <- </span>0
]
]
recipe clear-line [
<span class="Underlined">local</span>-scope
sc:address:screen<span class="Special"> <- </span>next-ingredient
<span class="Comment"># if x exists, clear line in fake screen</span>
{
break-unless sc
width:number<span class="Special"> <- </span>get *sc, num-columns:offset
column:address:number<span class="Special"> <- </span>get-address *sc, cursor-column:offset
original-column:number<span class="Special"> <- </span><span class="Identifier">copy</span> *column
<span class="Comment"># space over the entire line</span>
{
right:number<span class="Special"> <- </span>subtract width, 1
done?:boolean<span class="Special"> <- </span>greater-or-equal *column, right
break-if done?
<span class="Identifier">print</span>-character sc, [ ] <span class="Comment"># implicitly updates 'column'</span>
loop
}
<span class="Comment"># now back to where the cursor was</span>
*column<span class="Special"> <- </span><span class="Identifier">copy</span> original-column
reply sc/same-as-ingredient:0
}
<span class="Comment"># otherwise, real screen</span>
clear-line-on-display
reply sc/same-as-ingredient:0
]
recipe cursor-position [
<span class="Underlined">local</span>-scope
sc:address:screen<span class="Special"> <- </span>next-ingredient
<span class="Comment"># if x exists, lookup cursor in fake screen</span>
{
break-unless sc
row:number<span class="Special"> <- </span>get *sc, cursor-row:offset
column:number<span class="Special"> <- </span>get *sc, cursor-column:offset
reply row, column, sc/same-as-ingredient:0
}
row, column<span class="Special"> <- </span>cursor-position-on-display
reply row, column, sc/same-as-ingredient:0
]
recipe move-cursor [
<span class="Underlined">local</span>-scope
sc:address:screen<span class="Special"> <- </span>next-ingredient
<span class="Identifier">new</span>-row:number<span class="Special"> <- </span>next-ingredient
<span class="Identifier">new</span>-column:number<span class="Special"> <- </span>next-ingredient
<span class="Comment"># if x exists, move cursor in fake screen</span>
{
break-unless sc
row:address:number<span class="Special"> <- </span>get-address *sc, cursor-row:offset
*row<span class="Special"> <- </span><span class="Identifier">copy</span> <span class="Identifier">new</span>-row
column:address:number<span class="Special"> <- </span>get-address *sc, cursor-column:offset
*column<span class="Special"> <- </span><span class="Identifier">copy</span> <span class="Identifier">new</span>-column
reply sc/same-as-ingredient:0
}
<span class="Comment"># otherwise, real screen</span>
move-cursor-on-display <span class="Identifier">new</span>-row, <span class="Identifier">new</span>-column
reply sc/same-as-ingredient:0
]
scenario clear-line-erases-printed-characters [
run [
1:address:screen<span class="Special"> <- </span><span class="Identifier">new</span>-fake-screen 3/width, 2/height
<span class="Comment"># print a character</span>
1:address:screen<span class="Special"> <- </span><span class="Identifier">print</span>-character 1:address:screen, 97 <span class="Comment"># 'a'</span>
<span class="Comment"># move cursor to start of line</span>
1:address:screen<span class="Special"> <- </span>move-cursor 1:address:screen, 0/row, 0/column
<span class="Comment"># clear line</span>
1:address:screen<span class="Special"> <- </span>clear-line 1:address:screen
2:address:<span class="Identifier">array</span>:screen-cell<span class="Special"> <- </span>get *1:address:screen, data:offset
3:<span class="Identifier">array</span>:screen-cell<span class="Special"> <- </span><span class="Identifier">copy</span> *2:address:<span class="Identifier">array</span>:screen-cell
]
<span class="Comment"># screen should be blank</span>
memory-should-contain [
3<span class="Special"> <- </span>6 <span class="Comment"># width*height</span>
4<span class="Special"> <- </span>0
5<span class="Special"> <- </span>7
6<span class="Special"> <- </span>0
7<span class="Special"> <- </span>7
8<span class="Special"> <- </span>0
9<span class="Special"> <- </span>7
10<span class="Special"> <- </span>0
11<span class="Special"> <- </span>7
12<span class="Special"> <- </span>0
13<span class="Special"> <- </span>7
14<span class="Special"> <- </span>0
15<span class="Special"> <- </span>7
]
]
recipe cursor-down [
<span class="Underlined">local</span>-scope
sc:address:screen<span class="Special"> <- </span>next-ingredient
<span class="Comment"># if x exists, move cursor in fake screen</span>
{
break-unless sc
{
<span class="Comment"># increment row unless it's already all the way down</span>
height:number<span class="Special"> <- </span>get *sc, num-rows:offset
row:address:number<span class="Special"> <- </span>get-address *sc, cursor-row:offset
<span class="Identifier">max</span>:number<span class="Special"> <- </span>subtract height, 1
at-bottom?:boolean<span class="Special"> <- </span>greater-or-equal *row, <span class="Identifier">max</span>
break-if at-bottom?
*row<span class="Special"> <- </span>add *row, 1
}
reply sc/same-as-ingredient:0
}
<span class="Comment"># otherwise, real screen</span>
move-cursor-down-on-display
reply sc/same-as-ingredient:0
]
recipe cursor-up [
<span class="Underlined">local</span>-scope
sc:address:screen<span class="Special"> <- </span>next-ingredient
<span class="Comment"># if x exists, move cursor in fake screen</span>
{
break-unless sc
{
<span class="Comment"># decrement row unless it's already all the way up</span>
row:address:number<span class="Special"> <- </span>get-address *sc, cursor-row:offset
at-top?:boolean<span class="Special"> <- </span>lesser-or-equal *row, 0
break-if at-top?
*row<span class="Special"> <- </span>subtract *row, 1
}
reply sc/same-as-ingredient:0
}
<span class="Comment"># otherwise, real screen</span>
move-cursor-up-on-display
reply sc/same-as-ingredient:0
]
recipe cursor-right [
<span class="Underlined">local</span>-scope
sc:address:screen<span class="Special"> <- </span>next-ingredient
<span class="Comment"># if x exists, move cursor in fake screen</span>
{
break-unless sc
{
<span class="Comment"># increment column unless it's already all the way to the right</span>
width:number<span class="Special"> <- </span>get *sc, num-columns:offset
column:address:number<span class="Special"> <- </span>get-address *sc, cursor-column:offset
<span class="Identifier">max</span>:number<span class="Special"> <- </span>subtract width, 1
at-bottom?:boolean<span class="Special"> <- </span>greater-or-equal *column, <span class="Identifier">max</span>
break-if at-bottom?
*column<span class="Special"> <- </span>add *column, 1
}
reply sc/same-as-ingredient:0
}
<span class="Comment"># otherwise, real screen</span>
move-cursor-right-on-display
reply sc/same-as-ingredient:0
]
recipe cursor-left [
<span class="Underlined">local</span>-scope
sc:address:screen<span class="Special"> <- </span>next-ingredient
<span class="Comment"># if x exists, move cursor in fake screen</span>
{
break-unless sc
{
<span class="Comment"># decrement column unless it's already all the way to the left</span>
column:address:number<span class="Special"> <- </span>get-address *sc, cursor-column:offset
at-top?:boolean<span class="Special"> <- </span>lesser-or-equal *column, 0
break-if at-top?
*column<span class="Special"> <- </span>subtract *column, 1
}
reply sc/same-as-ingredient:0
}
<span class="Comment"># otherwise, real screen</span>
move-cursor-left-on-display
reply sc/same-as-ingredient:0
]
recipe cursor-to-start-of-line [
<span class="Underlined">local</span>-scope
sc:address:screen<span class="Special"> <- </span>next-ingredient
row:number, _, sc<span class="Special"> <- </span>cursor-position sc
column:number<span class="Special"> <- </span><span class="Identifier">copy</span> 0
sc<span class="Special"> <- </span>move-cursor sc, row, column
reply sc/same-as-ingredient:0
]
recipe cursor-to-next-line [
<span class="Underlined">local</span>-scope
screen:address<span class="Special"> <- </span>next-ingredient
screen<span class="Special"> <- </span>cursor-down screen
screen<span class="Special"> <- </span>cursor-to-start-of-line screen
reply screen/same-as-ingredient:0
]
recipe screen-width [
<span class="Underlined">local</span>-scope
sc:address:screen<span class="Special"> <- </span>next-ingredient
<span class="Comment"># if x exists, move cursor in fake screen</span>
{
break-unless sc
width:number<span class="Special"> <- </span>get *sc, num-columns:offset
reply width
}
<span class="Comment"># otherwise, real screen</span>
width:number<span class="Special"> <- </span>display-width
reply width
]
recipe screen-height [
<span class="Underlined">local</span>-scope
sc:address:screen<span class="Special"> <- </span>next-ingredient
<span class="Comment"># if x exists, move cursor in fake screen</span>
{
break-unless sc
height:number<span class="Special"> <- </span>get *sc, num-rows:offset
reply height
}
<span class="Comment"># otherwise, real screen</span>
height:number<span class="Special"> <- </span>display-height
reply height
]
recipe hide-cursor [
<span class="Underlined">local</span>-scope
screen:address<span class="Special"> <- </span>next-ingredient
<span class="Comment"># if x exists (not real display), do nothing</span>
{
break-unless screen
reply screen
}
<span class="Comment"># otherwise, real screen</span>
hide-cursor-on-display
reply screen
]
recipe show-cursor [
<span class="Underlined">local</span>-scope
screen:address<span class="Special"> <- </span>next-ingredient
<span class="Comment"># if x exists (not real display), do nothing</span>
{
break-unless screen
reply screen
}
<span class="Comment"># otherwise, real screen</span>
show-cursor-on-display
reply screen
]
recipe hide-screen [
<span class="Underlined">local</span>-scope
screen:address<span class="Special"> <- </span>next-ingredient
<span class="Comment"># if x exists (not real display), do nothing</span>
<span class="Comment"># todo: help test this</span>
{
break-unless screen
reply screen
}
<span class="Comment"># otherwise, real screen</span>
hide-display
reply screen
]
recipe show-screen [
<span class="Underlined">local</span>-scope
screen:address<span class="Special"> <- </span>next-ingredient
<span class="Comment"># if x exists (not real display), do nothing</span>
<span class="Comment"># todo: help test this</span>
{
break-unless screen
reply screen
}
<span class="Comment"># otherwise, real screen</span>
show-display
reply screen
]
recipe <span class="Identifier">print</span>-string [
<span class="Underlined">local</span>-scope
screen:address<span class="Special"> <- </span>next-ingredient
s:address:<span class="Identifier">array</span>:character<span class="Special"> <- </span>next-ingredient
color:number, color-found?:boolean<span class="Special"> <- </span>next-ingredient
{
<span class="Comment"># default color to white</span>
break-if color-found?
color<span class="Special"> <- </span><span class="Identifier">copy</span> 7/white
}
bg-color:number, bg-color-found?:boolean<span class="Special"> <- </span>next-ingredient
{
<span class="Comment"># default bg-color to black</span>
break-if bg-color-found?
bg-color<span class="Special"> <- </span><span class="Identifier">copy</span> 0/black
}
len:number<span class="Special"> <- </span><span class="Identifier">length</span> *s
i:number<span class="Special"> <- </span><span class="Identifier">copy</span> 0
{
done?:boolean<span class="Special"> <- </span>greater-or-equal i, len
break-if done?
c:character<span class="Special"> <- </span>index *s, i
<span class="Identifier">print</span>-character screen, c, color, bg-color
i<span class="Special"> <- </span>add i, 1
loop
}
reply screen/same-as-ingredient:0
]
scenario <span class="Identifier">print</span>-string-stops-at-right-margin [
run [
1:address:screen<span class="Special"> <- </span><span class="Identifier">new</span>-fake-screen 3/width, 2/height
2:address:<span class="Identifier">array</span>:character<span class="Special"> <- </span><span class="Identifier">new</span> [abcd]
1:address:screen<span class="Special"> <- </span><span class="Identifier">print</span>-string 1:address:screen, 2:address:<span class="Identifier">array</span>:character
3:address:<span class="Identifier">array</span>:screen-cell<span class="Special"> <- </span>get *1:address:screen, data:offset
4:<span class="Identifier">array</span>:screen-cell<span class="Special"> <- </span><span class="Identifier">copy</span> *3:address:<span class="Identifier">array</span>:screen-cell
]
memory-should-contain [
4<span class="Special"> <- </span>6 <span class="Comment"># width*height</span>
5<span class="Special"> <- </span>97 <span class="Comment"># 'a'</span>
6<span class="Special"> <- </span>7 <span class="Comment"># white</span>
7<span class="Special"> <- </span>98 <span class="Comment"># 'b'</span>
8<span class="Special"> <- </span>7 <span class="Comment"># white</span>
9<span class="Special"> <- </span>100 <span class="Comment"># 'd' overwrites 'c'</span>
10<span class="Special"> <- </span>7 <span class="Comment"># white</span>
11<span class="Special"> <- </span>0 <span class="Comment"># unused</span>
]
]
recipe <span class="Identifier">print</span>-integer [
<span class="Underlined">local</span>-scope
screen:address<span class="Special"> <- </span>next-ingredient
n:number<span class="Special"> <- </span>next-ingredient
color:number, color-found?:boolean<span class="Special"> <- </span>next-ingredient
{
<span class="Comment"># default color to white</span>
break-if color-found?
color<span class="Special"> <- </span><span class="Identifier">copy</span> 7/white
}
bg-color:number, bg-color-found?:boolean<span class="Special"> <- </span>next-ingredient
{
<span class="Comment"># default bg-color to black</span>
break-if bg-color-found?
bg-color<span class="Special"> <- </span><span class="Identifier">copy</span> 0/black
}
<span class="Comment"># todo: other bases besides decimal</span>
s:address:<span class="Identifier">array</span>:character<span class="Special"> <- </span>integer-to-decimal-string n
<span class="Identifier">print</span>-string screen, s, color, bg-color
reply screen/same-as-ingredient:0
]
</pre>
</body>
</html>
<!-- vim: set foldmethod=manual : -->