about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--081print.mu126
-rw-r--r--082scenario_screen.cc21
-rw-r--r--083scenario_screen_test.mu6
-rw-r--r--chessboard.mu3
-rw-r--r--edit/001-editor.mu6
-rw-r--r--edit/003-shortcuts.mu6
-rw-r--r--edit/004-programming-environment.mu24
-rw-r--r--edit/005-sandbox.mu15
-rw-r--r--edit/008-sandbox-test.mu3
-rw-r--r--edit/009-sandbox-trace.mu5
-rw-r--r--sandbox/001-editor.mu6
-rw-r--r--sandbox/003-shortcuts.mu6
-rw-r--r--sandbox/004-programming-environment.mu12
-rw-r--r--sandbox/005-sandbox.mu15
-rw-r--r--sandbox/009-sandbox-trace.mu5
-rw-r--r--screen.mu3
16 files changed, 164 insertions, 98 deletions
diff --git a/081print.mu b/081print.mu
index af49b012..445b6fa6 100644
--- a/081print.mu
+++ b/081print.mu
@@ -187,7 +187,8 @@ recipe print screen:address:screen, c:character -> screen:address:screen [
 scenario print-character-at-top-left [
   run [
     1:address:screen <- new-fake-screen 3/width, 2/height
-    1:address:screen <- print 1:address:screen, 97  # 'a'
+    11:character <- copy 97/a
+    1:address:screen <- print 1:address:screen, 11:character/a
     2:address:array:screen-cell <- get *1:address:screen, data:offset
     3:array:screen-cell <- copy *2:address:array:screen-cell
   ]
@@ -202,7 +203,8 @@ scenario print-character-at-top-left [
 scenario print-character-in-color [
   run [
     1:address:screen <- new-fake-screen 3/width, 2/height
-    1:address:screen <- print 1:address:screen, 97/a, 1/red
+    11:character <- copy 97/a
+    1:address:screen <- print 1:address:screen, 11:character/a, 1/red
     2:address:array:screen-cell <- get *1:address:screen, data:offset
     3:array:screen-cell <- copy *2:address:array:screen-cell
   ]
@@ -217,8 +219,10 @@ scenario print-character-in-color [
 scenario print-backspace-character [
   run [
     1:address:screen <- new-fake-screen 3/width, 2/height
-    1:address:screen <- print 1:address:screen, 97  # 'a'
-    1:address:screen <- print 1:address:screen, 8  # backspace
+    11:character <- copy 97/a
+    1:address:screen <- print 1:address:screen, 11:character/a
+    12:character <- copy 8/backspace
+    1:address:screen <- print 1:address:screen, 12:character/backspace
     2:number <- get *1:address:screen, cursor-column:offset
     3:address:array:screen-cell <- get *1:address:screen, data:offset
     4:array:screen-cell <- copy *3:address:array:screen-cell
@@ -235,9 +239,12 @@ scenario print-backspace-character [
 scenario print-extra-backspace-character [
   run [
     1:address:screen <- new-fake-screen 3/width, 2/height
-    1:address:screen <- print 1:address:screen, 97  # 'a'
-    1:address:screen <- print 1:address:screen, 8  # backspace
-    1:address:screen <- print 1:address:screen, 8  # backspace
+    11:character <- copy 97/a
+    1:address:screen <- print 1:address:screen, 11:character/a
+    12:character <- copy 8/backspace
+    1:address:screen <- print 1:address:screen, 12:character/backspace
+    12:character <- copy 8/backspace
+    1:address:screen <- print 1:address:screen, 12:character/backspace
     2:number <- get *1:address:screen, cursor-column:offset
     3:address:array:screen-cell <- get *1:address:screen, data:offset
     4:array:screen-cell <- copy *3:address:array:screen-cell
@@ -254,9 +261,12 @@ scenario print-extra-backspace-character [
 scenario print-character-at-right-margin [
   run [
     1:address:screen <- new-fake-screen 2/width, 2/height
-    1:address:screen <- print 1:address:screen, 97  # 'a'
-    1:address:screen <- print 1:address:screen, 98  # 'b'
-    1:address:screen <- print 1:address:screen, 99  # 'c'
+    11:character <- copy 97/a
+    1:address:screen <- print 1:address:screen, 11:character/a
+    12:character <- copy 98/b
+    1:address:screen <- print 1:address:screen, 12:character/b
+    13:character <- copy 99/b
+    1:address:screen <- print 1:address:screen, 13:character/c
     2:number <- get *1:address:screen, cursor-column:offset
     3:address:array:screen-cell <- get *1:address:screen, data:offset
     4:array:screen-cell <- copy *3:address:array:screen-cell
@@ -275,8 +285,10 @@ scenario print-character-at-right-margin [
 scenario print-newline-character [
   run [
     1:address:screen <- new-fake-screen 3/width, 2/height
-    1:address:screen <- print 1:address:screen, 97  # 'a'
-    1:address:screen <- print 1:address:screen, 10/newline
+    10:character <- copy 10/newline
+    11:character <- copy 97/a
+    1:address:screen <- print 1:address:screen, 11:character/a
+    1:address:screen <- print 1:address:screen, 10:character/newline
     2:number <- get *1:address:screen, cursor-row:offset
     3:number <- get *1:address:screen, cursor-column:offset
     4:address:array:screen-cell <- get *1:address:screen, data:offset
@@ -295,9 +307,10 @@ scenario print-newline-character [
 scenario print-newline-at-bottom-line [
   run [
     1:address:screen <- new-fake-screen 3/width, 2/height
-    1:address:screen <- print 1:address:screen, 10/newline
-    1:address:screen <- print 1:address:screen, 10/newline
-    1:address:screen <- print 1:address:screen, 10/newline
+    10:character <- copy 10/newline
+    1:address:screen <- print 1:address:screen, 10:character/newline
+    1:address:screen <- print 1:address:screen, 10:character/newline
+    1:address:screen <- print 1:address:screen, 10:character/newline
     2:number <- get *1:address:screen, cursor-row:offset
     3:number <- get *1:address:screen, cursor-column:offset
   ]
@@ -310,36 +323,42 @@ scenario print-newline-at-bottom-line [
 scenario print-character-at-bottom-right [
   run [
     1:address:screen <- new-fake-screen 2/width, 2/height
-    1:address:screen <- print 1:address:screen, 10/newline
-    1:address:screen <- print 1:address:screen, 97  # 'a'
-    1:address:screen <- print 1:address:screen, 98  # 'b'
-    1:address:screen <- print 1:address:screen, 99  # 'c'
-    1:address:screen <- print 1:address:screen, 10/newline
-    1:address:screen <- print 1:address:screen, 100  # 'd'
+    10:character <- copy 10/newline
+    1:address:screen <- print 1:address:screen, 10:character/newline
+    11:character <- copy 97/a
+    1:address:screen <- print 1:address:screen, 11:character/a
+    12:character <- copy 98/b
+    1:address:screen <- print 1:address:screen, 12:character/b
+    13:character <- copy 99/c
+    1:address:screen <- print 1:address:screen, 13:character/c
+    1:address:screen <- print 1:address:screen, 10:character/newline
+    14:character <- copy 100/d
+    1:address:screen <- print 1:address:screen, 14:character/d
     2:number <- get *1:address:screen, cursor-row:offset
     3:number <- get *1:address:screen, cursor-column:offset
     4:address:array:screen-cell <- get *1:address:screen, data:offset
-    5:array:screen-cell <- copy *4:address:array:screen-cell
+    20:array:screen-cell <- copy *4:address:array:screen-cell
   ]
   memory-should-contain [
     2 <- 1  # cursor row
     3 <- 1  # cursor column
-    5 <- 4  # width*height
-    6 <- 0  # unused
-    7 <- 7  # white
-    8 <- 0  # unused
-    9 <- 7  # white
-    10 <- 97 # 'a'
-    11 <- 7  # white
-    12 <- 100  # 'd' over 'b' and 'c' and newline
-    13 <- 7  # white
-    14 <- 0
+    20 <- 4  # width*height
+    21 <- 0  # unused
+    22 <- 7  # white
+    23 <- 0  # unused
+    24 <- 7  # white
+    25 <- 97 # 'a'
+    26 <- 7  # white
+    27 <- 100  # 'd' over 'b' and 'c' and newline
+    28 <- 7  # white
+    29 <- 0
   ]
 ]
 
 recipe clear-line screen:address:screen -> screen:address:screen [
   local-scope
   load-ingredients
+  space:character <- copy 0/nul
   # if x exists, clear line in fake screen
   {
     break-unless screen
@@ -351,7 +370,7 @@ recipe clear-line screen:address:screen -> screen:address:screen [
       right:number <- subtract width, 1
       done?:boolean <- greater-or-equal *column, right
       break-if done?
-      print screen, [ ]  # implicitly updates 'column'
+      print screen, space  # implicitly updates 'column'
       loop
     }
     # now back to where the cursor was
@@ -395,29 +414,30 @@ scenario clear-line-erases-printed-characters [
   run [
     1:address:screen <- new-fake-screen 3/width, 2/height
     # print a character
-    1:address:screen <- print 1:address:screen, 97  # 'a'
+    10:character <- copy 97/a
+    1:address:screen <- print 1:address:screen, 10:character/a
     # move cursor to start of line
     1:address:screen <- move-cursor 1:address:screen, 0/row, 0/column
     # clear line
     1:address:screen <- clear-line 1:address:screen
     2:address:array:screen-cell <- get *1:address:screen, data:offset
-    3:array:screen-cell <- copy *2:address:array:screen-cell
+    20:array:screen-cell <- copy *2:address:array:screen-cell
   ]
   # screen should be blank
   memory-should-contain [
-    3 <- 6  # width*height
-    4 <- 0
-    5 <- 7
-    6 <- 0
-    7 <- 7
-    8 <- 0
-    9 <- 7
-    10 <- 0
-    11 <- 7
-    12 <- 0
-    13 <- 7
-    14 <- 0
-    15 <- 7
+    20 <- 6  # width*height
+    21 <- 0
+    22 <- 7
+    23 <- 0
+    24 <- 7
+    25 <- 0
+    26 <- 7
+    27 <- 0
+    28 <- 7
+    29 <- 0
+    30 <- 7
+    31 <- 0
+    32 <- 7
   ]
 ]
 
@@ -641,8 +661,7 @@ scenario print-text-stops-at-right-margin [
 
 recipe print-integer screen:address:screen, n:number -> screen:address:screen [
   local-scope
-  screen:address:screen <- next-ingredient
-  n:number <- next-ingredient
+  load-ingredients
   color:number, color-found?:boolean <- next-ingredient
   {
     # default color to white
@@ -659,3 +678,10 @@ recipe print-integer screen:address:screen, n:number -> screen:address:screen [
   s:address:array:character <- to-text n
   screen <- print screen, s, color, bg-color
 ]
+
+# for now, we can only print integers
+recipe print screen:address:screen, n:number -> screen:address:screen [
+  local-scope
+  load-ingredients
+  screen <- print-integer screen, n
+]
diff --git a/082scenario_screen.cc b/082scenario_screen.cc
index 433b37c8..fc667311 100644
--- a/082scenario_screen.cc
+++ b/082scenario_screen.cc
@@ -9,7 +9,8 @@
 scenario screen-in-scenario [
   assume-screen 5/width, 3/height
   run [
-    screen:address:screen <- print screen:address:screen, 97  # 'a'
+    1:character <- copy 97/a
+    screen:address:screen <- print screen:address:screen, 1:character/a
   ]
   screen-should-contain [
   #  01234
@@ -23,8 +24,10 @@ scenario screen-in-scenario [
 scenario screen-in-scenario-unicode-color [
   assume-screen 5/width, 3/height
   run [
-    screen:address:screen <- print screen:address:screen, 955/greek-small-lambda, 1/red
-    screen:address:screen <- print screen:address:screen, 97/a
+    1:character <- copy 955/greek-small-lambda
+    screen:address:screen <- print screen:address:screen, 1:character/lambda, 1/red
+    2:character <- copy 97/a
+    screen:address:screen <- print screen:address:screen, 2:character/a
   ]
   screen-should-contain [
   #  01234
@@ -39,8 +42,10 @@ scenario screen-in-scenario-unicode-color [
 scenario screen-in-scenario-color [
   assume-screen 5/width, 3/height
   run [
-    screen:address:screen <- print screen:address:screen, 955/greek-small-lambda, 1/red
-    screen:address:screen <- print screen:address:screen, 97/a, 7/white
+    1:character <- copy 955/greek-small-lambda
+    screen:address:screen <- print screen:address:screen, 1:character/lambda, 1/red
+    2:character <- copy 97/a
+    screen:address:screen <- print screen:address:screen, 2:character/a, 7/white
   ]
   # screen-should-contain shows everything
   screen-should-contain [
@@ -72,7 +77,8 @@ scenario screen-in-scenario-color [
 scenario screen-in-scenario-error [
   assume-screen 5/width, 3/height
   run [
-    screen:address:screen <- print screen:address:screen, 97  # 'a'
+    1:character <- copy 97/a
+    screen:address:screen <- print screen:address:screen, 1:character/a
   ]
   screen-should-contain [
   #  01234
@@ -90,7 +96,8 @@ scenario screen-in-scenario-error [
 scenario screen-in-scenario-color [
   assume-screen 5/width, 3/height
   run [
-    screen:address:screen <- print screen:address:screen, 97/a, 1/red
+    1:character <- copy 97/a
+    screen:address:screen <- print screen:address:screen, 1:character/a, 1/red
   ]
   screen-should-contain-in-color 2/green, [
   #  01234
diff --git a/083scenario_screen_test.mu b/083scenario_screen_test.mu
index 17a3f140..9679e9cf 100644
--- a/083scenario_screen_test.mu
+++ b/083scenario_screen_test.mu
@@ -3,7 +3,8 @@
 scenario print-character-at-top-left-2 [
   assume-screen 3/width, 2/height
   run [
-    screen:address:screen <- print screen:address:screen, 97/a
+    1:character <- copy 97/a
+    screen:address:screen <- print screen:address:screen, 1:character/a
   ]
   screen-should-contain [
     .a  .
@@ -15,7 +16,8 @@ scenario clear-line-erases-printed-characters-2 [
   assume-screen 5/width, 3/height
   run [
     # print a character
-    screen:address:screen <- print screen:address:screen, 97/a
+    1:character <- copy 97/a
+    screen:address:screen <- print screen:address:screen, 1:character/a
     # move cursor to start of line
     screen:address:screen <- move-cursor screen:address:screen, 0/row, 0/column
     # clear line
diff --git a/chessboard.mu b/chessboard.mu
index c8c84eed..e5f894fa 100644
--- a/chessboard.mu
+++ b/chessboard.mu
@@ -149,6 +149,7 @@ recipe print-board screen:address:screen, board:address:array:address:array:char
   local-scope
   load-ingredients
   row:number <- copy 7  # start printing from the top of the board
+  space:character <- copy 32/space
   # print each row
   {
     done?:boolean <- lesser-than row, 0
@@ -166,7 +167,7 @@ recipe print-board screen:address:screen, board:address:array:address:array:char
       f:address:array:character <- index *board, col
       c:character <- index *f, row
       print screen, c
-      print screen, 32/space
+      print screen, space
       col <- add col, 1
       loop
     }
diff --git a/edit/001-editor.mu b/edit/001-editor.mu
index 4ef9be36..fd44d493 100644
--- a/edit/001-editor.mu
+++ b/edit/001-editor.mu
@@ -193,7 +193,8 @@ recipe render screen:address:screen, editor:address:editor-data -> last-row:numb
       at-right?:boolean <- equal column, right
       break-unless at-right?
       # print wrap icon
-      print screen, 8617/loop-back-to-left, 245/grey
+      wrap-icon:character <- copy 8617/loop-back-to-left
+      print screen, wrap-icon, 245/grey
       column <- copy left
       row <- add row, 1
       screen <- move-cursor screen, row, column
@@ -227,10 +228,11 @@ recipe render screen:address:screen, editor:address:editor-data -> last-row:numb
 recipe clear-line-delimited screen:address:screen, column:number, right:number -> screen:address:screen [
   local-scope
   load-ingredients
+  space:character <- copy 32/space
   {
     done?:boolean <- greater-than column, right
     break-if done?
-    screen <- print screen, 32/space
+    screen <- print screen, space
     column <- add column, 1
     loop
   }
diff --git a/edit/003-shortcuts.mu b/edit/003-shortcuts.mu
index 79d53b2a..feab04ea 100644
--- a/edit/003-shortcuts.mu
+++ b/edit/003-shortcuts.mu
@@ -125,7 +125,8 @@ recipe delete-before-cursor editor:address:editor-data, screen:address:screen ->
     loop
   }
   # we're guaranteed not to be at the right margin
-  screen <- print screen, 32/space
+  space:character <- copy 32/space
+  screen <- print screen, space
   go-render? <- copy 0/false
 ]
 
@@ -366,7 +367,8 @@ recipe delete-at-cursor editor:address:editor-data, screen:address:screen -> edi
     loop
   }
   # we're guaranteed not to be at the right margin
-  screen <- print screen, 32/space
+  space:character <- copy 32/space
+  screen <- print screen, space
   go-render? <- copy 0/false
 ]
 
diff --git a/edit/004-programming-environment.mu b/edit/004-programming-environment.mu
index 44a812c5..7ed6376e 100644
--- a/edit/004-programming-environment.mu
+++ b/edit/004-programming-environment.mu
@@ -267,7 +267,8 @@ scenario edit-multiple-editors [
   ]
   # show the cursor at the right window
   run [
-    print screen:address:screen, 9251/␣/cursor
+    8:character/cursor <- copy 9251/␣
+    print screen:address:screen, 8:character/cursor
   ]
   screen-should-contain [
     .           run (F4)           .
@@ -307,7 +308,8 @@ scenario editor-in-focus-keeps-cursor [
   assume-console []
   run [
     event-loop screen:address:screen, console:address:console, 3:address:programming-environment-data
-    print screen:address:screen, 9251/␣/cursor
+    4:character/cursor <- copy 9251/␣
+    print screen:address:screen, 4:character/cursor
   ]
   # is cursor at the right place?
   screen-should-contain [
@@ -322,7 +324,8 @@ scenario editor-in-focus-keeps-cursor [
   ]
   run [
     event-loop screen:address:screen, console:address:console, 3:address:programming-environment-data
-    print screen:address:screen, 9251/␣/cursor
+    4:character/cursor <- copy 9251/␣
+    print screen:address:screen, 4:character/cursor
   ]
   # cursor should still be right
   screen-should-contain [
@@ -356,7 +359,8 @@ def]
   ]
   run [
     event-loop screen:address:screen, console:address:console, 3:address:programming-environment-data
-    print screen:address:screen, 9251/␣/cursor
+    4:character/cursor <- copy 9251/␣
+    print screen:address:screen, 4:character/cursor
   ]
   # cursor moves to end of old line
   screen-should-contain [
@@ -473,7 +477,8 @@ recipe render screen:address:screen, s:address:array:character, left:number, rig
       at-right?:boolean <- equal column, right
       break-unless at-right?
       # print wrap icon
-      print screen, 8617/loop-back-to-left, 245/grey
+      wrap-icon:character <- copy 8617/loop-back-to-left
+      print screen, wrap-icon, 245/grey
       column <- copy left
       row <- add row, 1
       screen <- move-cursor screen, row, column
@@ -488,7 +493,8 @@ recipe render screen:address:screen, s:address:array:character, left:number, rig
       {
         done?:boolean <- greater-than column, right
         break-if done?
-        print screen, 32/space
+        space:character <- copy 32/space
+        print screen, space
         column <- add column, 1
         loop
       }
@@ -534,7 +540,8 @@ recipe render-code screen:address:screen, s:address:array:character, left:number
       at-right?:boolean <- equal column, right
       break-unless at-right?
       # print wrap icon
-      print screen, 8617/loop-back-to-left, 245/grey
+      wrap-icon:character <- copy 8617/loop-back-to-left
+      print screen, wrap-icon, 245/grey
       column <- copy left
       row <- add row, 1
       screen <- move-cursor screen, row, column
@@ -549,7 +556,8 @@ recipe render-code screen:address:screen, s:address:array:character, left:number
       {
         done?:boolean <- greater-than column, right
         break-if done?
-        print screen, 32/space
+        space:character <- copy 32/space
+        print screen, space
         column <- add column, 1
         loop
       }
diff --git a/edit/005-sandbox.mu b/edit/005-sandbox.mu
index a8a4c5a3..3929fb76 100644
--- a/edit/005-sandbox.mu
+++ b/edit/005-sandbox.mu
@@ -253,7 +253,8 @@ recipe render-sandboxes screen:address:screen, sandbox:address:sandbox-data, lef
   row <- add row, 1
   screen <- move-cursor screen, row, left
   clear-line-delimited screen, left, right
-  print screen, 120/x, 245/grey
+  delete-icon:character <- copy 120/x
+  print screen, delete-icon, 245/grey
   # save menu row so we can detect clicks to it later
   starting-row:address:number <- get-address *sandbox, starting-row-on-screen:offset
   *starting-row <- copy row
@@ -349,9 +350,11 @@ recipe render-screen screen:address:screen, sandbox-screen:address:screen, left:
     column <- copy left
     screen <- move-cursor screen, row, column
     # initial leader for each row: two spaces and a '.'
-    print screen, 32/space, 245/grey
-    print screen, 32/space, 245/grey
-    print screen, 46/full-stop, 245/grey
+    space:character <- copy 32/space
+    print screen, space, 245/grey
+    print screen, space, 245/grey
+    full-stop:character <- copy 46/period
+    print screen, full-stop, 245/grey
     column <- add left, 3
     {
       # print row
@@ -372,13 +375,13 @@ recipe render-screen screen:address:screen, sandbox-screen:address:screen, left:
       loop
     }
     # print final '.'
-    print screen, 46/full-stop, 245/grey
+    print screen, full-stop, 245/grey
     column <- add column, 1
     {
       # clear rest of current line
       line-done?:boolean <- greater-than column, right
       break-if line-done?
-      print screen, 32/space
+      print screen, space
       column <- add column, 1
       loop
     }
diff --git a/edit/008-sandbox-test.mu b/edit/008-sandbox-test.mu
index 0ba1941e..77cac2ce 100644
--- a/edit/008-sandbox-test.mu
+++ b/edit/008-sandbox-test.mu
@@ -45,7 +45,8 @@ recipe foo [
   ]
   # cursor should remain unmoved
   run [
-    print screen:address:screen, 9251/␣/cursor
+    4:character/cursor <- copy 9251/␣
+    print screen:address:screen, 4:character/cursor
   ]
   screen-should-contain [
     .                     run (F4)           .
diff --git a/edit/009-sandbox-trace.mu b/edit/009-sandbox-trace.mu
index f3e78701..03bde749 100644
--- a/edit/009-sandbox-trace.mu
+++ b/edit/009-sandbox-trace.mu
@@ -30,7 +30,8 @@ recipe foo [
   ]
   run [
     event-loop screen:address:screen, console:address:console, 3:address:programming-environment-data
-    print screen:address:screen, 9251/␣/cursor
+    4:character/cursor-icon <- copy 9251/␣
+    print screen:address:screen, 4:character/cursor-icon
   ]
   # trace now printed and cursor shouldn't have budged
   screen-should-contain [
@@ -59,7 +60,7 @@ recipe foo [
   ]
   run [
     event-loop screen:address:screen, console:address:console, 3:address:programming-environment-data
-    print screen:address:screen, 9251/␣/cursor
+    print screen:address:screen, 4:character/cursor-icon
   ]
   # trace hidden again
   screen-should-contain [
diff --git a/sandbox/001-editor.mu b/sandbox/001-editor.mu
index 4ef9be36..fd44d493 100644
--- a/sandbox/001-editor.mu
+++ b/sandbox/001-editor.mu
@@ -193,7 +193,8 @@ recipe render screen:address:screen, editor:address:editor-data -> last-row:numb
       at-right?:boolean <- equal column, right
       break-unless at-right?
       # print wrap icon
-      print screen, 8617/loop-back-to-left, 245/grey
+      wrap-icon:character <- copy 8617/loop-back-to-left
+      print screen, wrap-icon, 245/grey
       column <- copy left
       row <- add row, 1
       screen <- move-cursor screen, row, column
@@ -227,10 +228,11 @@ recipe render screen:address:screen, editor:address:editor-data -> last-row:numb
 recipe clear-line-delimited screen:address:screen, column:number, right:number -> screen:address:screen [
   local-scope
   load-ingredients
+  space:character <- copy 32/space
   {
     done?:boolean <- greater-than column, right
     break-if done?
-    screen <- print screen, 32/space
+    screen <- print screen, space
     column <- add column, 1
     loop
   }
diff --git a/sandbox/003-shortcuts.mu b/sandbox/003-shortcuts.mu
index 79d53b2a..feab04ea 100644
--- a/sandbox/003-shortcuts.mu
+++ b/sandbox/003-shortcuts.mu
@@ -125,7 +125,8 @@ recipe delete-before-cursor editor:address:editor-data, screen:address:screen ->
     loop
   }
   # we're guaranteed not to be at the right margin
-  screen <- print screen, 32/space
+  space:character <- copy 32/space
+  screen <- print screen, space
   go-render? <- copy 0/false
 ]
 
@@ -366,7 +367,8 @@ recipe delete-at-cursor editor:address:editor-data, screen:address:screen -> edi
     loop
   }
   # we're guaranteed not to be at the right margin
-  screen <- print screen, 32/space
+  space:character <- copy 32/space
+  screen <- print screen, space
   go-render? <- copy 0/false
 ]
 
diff --git a/sandbox/004-programming-environment.mu b/sandbox/004-programming-environment.mu
index 1535e75c..4a16d2fa 100644
--- a/sandbox/004-programming-environment.mu
+++ b/sandbox/004-programming-environment.mu
@@ -223,7 +223,8 @@ recipe render screen:address:screen, s:address:array:character, left:number, rig
       at-right?:boolean <- equal column, right
       break-unless at-right?
       # print wrap icon
-      print screen, 8617/loop-back-to-left, 245/grey
+      wrap-icon:character <- copy 8617/loop-back-to-left
+      print screen, wrap-icon, 245/grey
       column <- copy left
       row <- add row, 1
       screen <- move-cursor screen, row, column
@@ -238,7 +239,8 @@ recipe render screen:address:screen, s:address:array:character, left:number, rig
       {
         done?:boolean <- greater-than column, right
         break-if done?
-        print screen, 32/space
+        space:character <- copy 32/space
+        print screen, space
         column <- add column, 1
         loop
       }
@@ -284,7 +286,8 @@ recipe render-code screen:address:screen, s:address:array:character, left:number
       at-right?:boolean <- equal column, right
       break-unless at-right?
       # print wrap icon
-      print screen, 8617/loop-back-to-left, 245/grey
+      wrap-icon:character <- copy 8617/loop-back-to-left
+      print screen, wrap-icon, 245/grey
       column <- copy left
       row <- add row, 1
       screen <- move-cursor screen, row, column
@@ -299,7 +302,8 @@ recipe render-code screen:address:screen, s:address:array:character, left:number
       {
         done?:boolean <- greater-than column, right
         break-if done?
-        print screen, 32/space
+        space:character <- copy 32/space
+        print screen, space
         column <- add column, 1
         loop
       }
diff --git a/sandbox/005-sandbox.mu b/sandbox/005-sandbox.mu
index db0a195b..a424209a 100644
--- a/sandbox/005-sandbox.mu
+++ b/sandbox/005-sandbox.mu
@@ -234,7 +234,8 @@ recipe render-sandboxes screen:address:screen, sandbox:address:sandbox-data, lef
   row <- add row, 1
   screen <- move-cursor screen, row, left
   clear-line-delimited screen, left, right
-  print screen, 120/x, 245/grey
+  delete-icon:character <- copy 120/x
+  print screen, delete-icon, 245/grey
   # save menu row so we can detect clicks to it later
   starting-row:address:number <- get-address *sandbox, starting-row-on-screen:offset
   *starting-row <- copy row
@@ -330,9 +331,11 @@ recipe render-screen screen:address:screen, sandbox-screen:address:screen, left:
     column <- copy left
     screen <- move-cursor screen, row, column
     # initial leader for each row: two spaces and a '.'
-    print screen, 32/space, 245/grey
-    print screen, 32/space, 245/grey
-    print screen, 46/full-stop, 245/grey
+    space:character <- copy 32/space
+    print screen, space, 245/grey
+    print screen, space, 245/grey
+    full-stop:character <- copy 46/period
+    print screen, full-stop, 245/grey
     column <- add left, 3
     {
       # print row
@@ -353,13 +356,13 @@ recipe render-screen screen:address:screen, sandbox-screen:address:screen, left:
       loop
     }
     # print final '.'
-    print screen, 46/full-stop, 245/grey
+    print screen, full-stop, 245/grey
     column <- add column, 1
     {
       # clear rest of current line
       line-done?:boolean <- greater-than column, right
       break-if line-done?
-      print screen, 32/space
+      print screen, space
       column <- add column, 1
       loop
     }
diff --git a/sandbox/009-sandbox-trace.mu b/sandbox/009-sandbox-trace.mu
index df74df47..45759b75 100644
--- a/sandbox/009-sandbox-trace.mu
+++ b/sandbox/009-sandbox-trace.mu
@@ -25,7 +25,8 @@ scenario sandbox-click-on-code-toggles-app-trace [
   ]
   run [
     event-loop screen:address:screen, console:address:console, 2:address:programming-environment-data
-    print screen:address:screen, 9251/␣/cursor
+    4:character/cursor-icon <- copy 9251/␣
+    print screen:address:screen, 4:character/cursor-icon
   ]
   # trace now printed and cursor shouldn't have budged
   screen-should-contain [
@@ -54,7 +55,7 @@ scenario sandbox-click-on-code-toggles-app-trace [
   ]
   run [
     event-loop screen:address:screen, console:address:console, 2:address:programming-environment-data
-    print screen:address:screen, 9251/␣/cursor
+    print screen:address:screen, 4:character/cursor-icon
   ]
   # trace hidden again
   screen-should-contain [
diff --git a/screen.mu b/screen.mu
index 665822ac..1061d191 100644
--- a/screen.mu
+++ b/screen.mu
@@ -5,7 +5,8 @@
 
 recipe main [
   open-console
-  print 0/screen, 97/a, 2/red
+  10:character <- copy 97/a
+  print 0/screen, 10:character/a, 2/red
   1:number/raw, 2:number/raw <- cursor-position 0/screen
   wait-for-event 0/console
   clear-screen 0/screen