about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2016-03-14 18:24:33 -0700
committerKartik K. Agaram <vc@akkartik.com>2016-03-14 18:24:33 -0700
commit637cc4139be5849ce7a12b75153667d54313627e (patch)
treea0b1a71e9a9f42d7a7776d9161f05d904da7f022
parent540c290de5d2cd940a799a35a2f78e10958fb36e (diff)
downloadmu-637cc4139be5849ce7a12b75153667d54313627e.tar.gz
2784 - make channels generic
I've ignored Mu's concurrency primitives for a while, but they're
starting to return to front-and-center as I work on the file system
interfaces.
-rw-r--r--072channel.mu120
-rw-r--r--084console.mu2
-rw-r--r--channel.mu10
-rw-r--r--chessboard.mu56
4 files changed, 94 insertions, 94 deletions
diff --git a/072channel.mu b/072channel.mu
index a9068603..557079c8 100644
--- a/072channel.mu
+++ b/072channel.mu
@@ -10,9 +10,9 @@
 
 scenario channel [
   run [
-    1:address:shared:channel <- new-channel 3/capacity
-    1:address:shared:channel <- write 1:address:shared:channel, 34
-    2:character, 1:address:shared:channel <- read 1:address:shared:channel
+    1:address:shared:channel:character <- new-channel 3/capacity
+    1:address:shared:channel:character <- write 1:address:shared:channel:character, 34
+    2:character, 1:address:shared:channel:character <- read 1:address:shared:channel:character
   ]
   memory-should-contain [
     2 <- 34
@@ -31,10 +31,10 @@ container channel [
   data:address:shared:array:character
 ]
 
-def new-channel capacity:number -> result:address:shared:channel [
+def new-channel capacity:number -> result:address:shared:channel:_elem [
   local-scope
   load-ingredients
-  result <- new channel:type
+  result <- new {(channel _elem): type}
   # result.first-full = 0
   full:address:number <- get-address *result, first-full:offset
   *full <- copy 0
@@ -47,7 +47,7 @@ def new-channel capacity:number -> result:address:shared:channel [
   *dest <- new character:type, capacity
 ]
 
-def write chan:address:shared:channel, val:character -> chan:address:shared:channel [
+def write chan:address:shared:channel:_elem, val:character -> chan:address:shared:channel:_elem [
   local-scope
   load-ingredients
   {
@@ -73,7 +73,7 @@ def write chan:address:shared:channel, val:character -> chan:address:shared:chan
   }
 ]
 
-def read chan:address:shared:channel -> result:character, chan:address:shared:channel [
+def read chan:address:shared:channel:_elem -> result:character, chan:address:shared:channel:_elem [
   local-scope
   load-ingredients
   {
@@ -98,7 +98,7 @@ def read chan:address:shared:channel -> result:character, chan:address:shared:ch
   }
 ]
 
-def clear-channel chan:address:shared:channel -> chan:address:shared:channel [
+def clear-channel chan:address:shared:channel:_elem -> chan:address:shared:channel:_elem [
   local-scope
   load-ingredients
   {
@@ -110,9 +110,9 @@ def clear-channel chan:address:shared:channel -> chan:address:shared:channel [
 
 scenario channel-initialization [
   run [
-    1:address:shared:channel <- new-channel 3/capacity
-    2:number <- get *1:address:shared:channel, first-full:offset
-    3:number <- get *1:address:shared:channel, first-free:offset
+    1:address:shared:channel:character <- new-channel 3/capacity
+    2:number <- get *1:address:shared:channel:character, first-full:offset
+    3:number <- get *1:address:shared:channel:character, first-free:offset
   ]
   memory-should-contain [
     2 <- 0  # first-full
@@ -122,10 +122,10 @@ scenario channel-initialization [
 
 scenario channel-write-increments-free [
   run [
-    1:address:shared:channel <- new-channel 3/capacity
-    1:address:shared:channel <- write 1:address:shared:channel, 34
-    2:number <- get *1:address:shared:channel, first-full:offset
-    3:number <- get *1:address:shared:channel, first-free:offset
+    1:address:shared:channel:character <- new-channel 3/capacity
+    1:address:shared:channel:character <- write 1:address:shared:channel:character, 34
+    2:number <- get *1:address:shared:channel:character, first-full:offset
+    3:number <- get *1:address:shared:channel:character, first-free:offset
   ]
   memory-should-contain [
     2 <- 0  # first-full
@@ -135,11 +135,11 @@ scenario channel-write-increments-free [
 
 scenario channel-read-increments-full [
   run [
-    1:address:shared:channel <- new-channel 3/capacity
-    1:address:shared:channel <- write 1:address:shared:channel, 34
-    _, 1:address:shared:channel <- read 1:address:shared:channel
-    2:number <- get *1:address:shared:channel, first-full:offset
-    3:number <- get *1:address:shared:channel, first-free:offset
+    1:address:shared:channel:character <- new-channel 3/capacity
+    1:address:shared:channel:character <- write 1:address:shared:channel:character, 34
+    _, 1:address:shared:channel:character <- read 1:address:shared:channel:character
+    2:number <- get *1:address:shared:channel:character, first-full:offset
+    3:number <- get *1:address:shared:channel:character, first-free:offset
   ]
   memory-should-contain [
     2 <- 1  # first-full
@@ -150,19 +150,19 @@ scenario channel-read-increments-full [
 scenario channel-wrap [
   run [
     # channel with just 1 slot
-    1:address:shared:channel <- new-channel 1/capacity
+    1:address:shared:channel:character <- new-channel 1/capacity
     # write and read a value
-    1:address:shared:channel <- write 1:address:shared:channel, 34
-    _, 1:address:shared:channel <- read 1:address:shared:channel
+    1:address:shared:channel:character <- write 1:address:shared:channel:character, 34
+    _, 1:address:shared:channel:character <- read 1:address:shared:channel:character
     # first-free will now be 1
-    2:number <- get *1:address:shared:channel, first-free:offset
-    3:number <- get *1:address:shared:channel, first-free:offset
+    2:number <- get *1:address:shared:channel:character, first-free:offset
+    3:number <- get *1:address:shared:channel:character, first-free:offset
     # write second value, verify that first-free wraps
-    1:address:shared:channel <- write 1:address:shared:channel, 34
-    4:number <- get *1:address:shared:channel, first-free:offset
+    1:address:shared:channel:character <- write 1:address:shared:channel:character, 34
+    4:number <- get *1:address:shared:channel:character, first-free:offset
     # read second value, verify that first-full wraps
-    _, 1:address:shared:channel <- read 1:address:shared:channel
-    5:number <- get *1:address:shared:channel, first-full:offset
+    _, 1:address:shared:channel:character <- read 1:address:shared:channel:character
+    5:number <- get *1:address:shared:channel:character, first-full:offset
   ]
   memory-should-contain [
     2 <- 1  # first-free after first write
@@ -175,7 +175,7 @@ scenario channel-wrap [
 ## helpers
 
 # An empty channel has first-empty and first-full both at the same value.
-def channel-empty? chan:address:shared:channel -> result:boolean [
+def channel-empty? chan:address:shared:channel:_elem -> result:boolean [
   local-scope
   load-ingredients
   # return chan.first-full == chan.first-free
@@ -186,7 +186,7 @@ def channel-empty? chan:address:shared:channel -> result:boolean [
 
 # A full channel has first-empty just before first-full, wasting one slot.
 # (Other alternatives: https://en.wikipedia.org/wiki/Circular_buffer#Full_.2F_Empty_Buffer_Distinction)
-def channel-full? chan:address:shared:channel -> result:boolean [
+def channel-full? chan:address:shared:channel:_elem -> result:boolean [
   local-scope
   load-ingredients
   # tmp = chan.first-free + 1
@@ -204,7 +204,7 @@ def channel-full? chan:address:shared:channel -> result:boolean [
   result <- equal full, tmp
 ]
 
-def channel-capacity chan:address:shared:channel -> result:number [
+def channel-capacity chan:address:shared:channel:_elem -> result:number [
   local-scope
   load-ingredients
   q:address:shared:array:character <- get *chan, data:offset
@@ -213,9 +213,9 @@ def channel-capacity chan:address:shared:channel -> result:number [
 
 scenario channel-new-empty-not-full [
   run [
-    1:address:shared:channel <- new-channel 3/capacity
-    2:boolean <- channel-empty? 1:address:shared:channel
-    3:boolean <- channel-full? 1:address:shared:channel
+    1:address:shared:channel:character <- new-channel 3/capacity
+    2:boolean <- channel-empty? 1:address:shared:channel:character
+    3:boolean <- channel-full? 1:address:shared:channel:character
   ]
   memory-should-contain [
     2 <- 1  # empty?
@@ -225,10 +225,10 @@ scenario channel-new-empty-not-full [
 
 scenario channel-write-not-empty [
   run [
-    1:address:shared:channel <- new-channel 3/capacity
-    1:address:shared:channel <- write 1:address:shared:channel, 34
-    2:boolean <- channel-empty? 1:address:shared:channel
-    3:boolean <- channel-full? 1:address:shared:channel
+    1:address:shared:channel:character <- new-channel 3/capacity
+    1:address:shared:channel:character <- write 1:address:shared:channel:character, 34
+    2:boolean <- channel-empty? 1:address:shared:channel:character
+    3:boolean <- channel-full? 1:address:shared:channel:character
   ]
   memory-should-contain [
     2 <- 0  # empty?
@@ -238,10 +238,10 @@ scenario channel-write-not-empty [
 
 scenario channel-write-full [
   run [
-    1:address:shared:channel <- new-channel 1/capacity
-    1:address:shared:channel <- write 1:address:shared:channel, 34
-    2:boolean <- channel-empty? 1:address:shared:channel
-    3:boolean <- channel-full? 1:address:shared:channel
+    1:address:shared:channel:character <- new-channel 1/capacity
+    1:address:shared:channel:character <- write 1:address:shared:channel:character, 34
+    2:boolean <- channel-empty? 1:address:shared:channel:character
+    3:boolean <- channel-full? 1:address:shared:channel:character
   ]
   memory-should-contain [
     2 <- 0  # empty?
@@ -251,11 +251,11 @@ scenario channel-write-full [
 
 scenario channel-read-not-full [
   run [
-    1:address:shared:channel <- new-channel 1/capacity
-    1:address:shared:channel <- write 1:address:shared:channel, 34
-    _, 1:address:shared:channel <- read 1:address:shared:channel
-    2:boolean <- channel-empty? 1:address:shared:channel
-    3:boolean <- channel-full? 1:address:shared:channel
+    1:address:shared:channel:character <- new-channel 1/capacity
+    1:address:shared:channel:character <- write 1:address:shared:channel:character, 34
+    _, 1:address:shared:channel:character <- read 1:address:shared:channel:character
+    2:boolean <- channel-empty? 1:address:shared:channel:character
+    3:boolean <- channel-full? 1:address:shared:channel:character
   ]
   memory-should-contain [
     2 <- 1  # empty?
@@ -264,7 +264,7 @@ scenario channel-read-not-full [
 ]
 
 # helper for channels of characters in particular
-def buffer-lines in:address:shared:channel, out:address:shared:channel -> out:address:shared:channel, in:address:shared:channel [
+def buffer-lines in:address:shared:channel:character, out:address:shared:channel:character -> out:address:shared:channel:character, in:address:shared:channel:character [
   local-scope
   load-ingredients
   # repeat forever
@@ -316,36 +316,36 @@ def buffer-lines in:address:shared:channel, out:address:shared:channel -> out:ad
 
 scenario buffer-lines-blocks-until-newline [
   run [
-    1:address:shared:channel/stdin <- new-channel 10/capacity
-    2:address:shared:channel/buffered-stdin <- new-channel 10/capacity
-    3:boolean <- channel-empty? 2:address:shared:channel/buffered-stdin
+    1:address:shared:channel:character/stdin <- new-channel 10/capacity
+    2:address:shared:channel:character/buffered-stdin <- new-channel 10/capacity
+    3:boolean <- channel-empty? 2:address:shared:channel:character/buffered-stdin
     assert 3:boolean, [
 F buffer-lines-blocks-until-newline: channel should be empty after init]
     # buffer stdin into buffered-stdin, try to read from buffered-stdin
-    4:number/buffer-routine <- start-running buffer-lines, 1:address:shared:channel/stdin, 2:address:shared:channel/buffered-stdin
+    4:number/buffer-routine <- start-running buffer-lines, 1:address:shared:channel:character/stdin, 2:address:shared:channel:character/buffered-stdin
     wait-for-routine 4:number/buffer-routine
-    5:boolean <- channel-empty? 2:address:shared:channel/buffered-stdin
+    5:boolean <- channel-empty? 2:address:shared:channel:character/buffered-stdin
     assert 5:boolean, [
 F buffer-lines-blocks-until-newline: channel should be empty after buffer-lines bring-up]
     # write 'a'
-    1:address:shared:channel <- write 1:address:shared:channel, 97/a
+    1:address:shared:channel:character <- write 1:address:shared:channel:character, 97/a
     restart 4:number/buffer-routine
     wait-for-routine 4:number/buffer-routine
-    6:boolean <- channel-empty? 2:address:shared:channel/buffered-stdin
+    6:boolean <- channel-empty? 2:address:shared:channel:character/buffered-stdin
     assert 6:boolean, [
 F buffer-lines-blocks-until-newline: channel should be empty after writing 'a']
     # write 'b'
-    1:address:shared:channel <- write 1:address:shared:channel, 98/b
+    1:address:shared:channel:character <- write 1:address:shared:channel:character, 98/b
     restart 4:number/buffer-routine
     wait-for-routine 4:number/buffer-routine
-    7:boolean <- channel-empty? 2:address:shared:channel/buffered-stdin
+    7:boolean <- channel-empty? 2:address:shared:channel:character/buffered-stdin
     assert 7:boolean, [
 F buffer-lines-blocks-until-newline: channel should be empty after writing 'b']
     # write newline
-    1:address:shared:channel <- write 1:address:shared:channel, 10/newline
+    1:address:shared:channel:character <- write 1:address:shared:channel:character, 10/newline
     restart 4:number/buffer-routine
     wait-for-routine 4:number/buffer-routine
-    8:boolean <- channel-empty? 2:address:shared:channel/buffered-stdin
+    8:boolean <- channel-empty? 2:address:shared:channel:character/buffered-stdin
     9:boolean/completed? <- not 8:boolean
     assert 9:boolean/completed?, [
 F buffer-lines-blocks-until-newline: channel should contain data after writing newline]
diff --git a/084console.mu b/084console.mu
index 83fb2f1d..805e28d4 100644
--- a/084console.mu
+++ b/084console.mu
@@ -72,7 +72,7 @@ def read-key console:address:shared:console -> result:character, console:address
   return *c, console/same-as-ingredient:0, 1/found, 0/quit
 ]
 
-def send-keys-to-channel console:address:shared:console, chan:address:shared:channel, screen:address:shared:screen -> console:address:shared:console, chan:address:shared:channel, screen:address:shared:screen [
+def send-keys-to-channel console:address:shared:console, chan:address:shared:channel:character, screen:address:shared:screen -> console:address:shared:console, chan:address:shared:channel:character, screen:address:shared:screen [
   local-scope
   load-ingredients
   {
diff --git a/channel.mu b/channel.mu
index 6e948da0..1dbae8e0 100644
--- a/channel.mu
+++ b/channel.mu
@@ -1,6 +1,6 @@
 # example program: communicating between routines using channels
 
-def producer chan:address:shared:channel -> chan:address:shared:channel [
+def producer chan:address:shared:channel:character -> chan:address:shared:channel:character [
   # produce characters 1 to 5 on a channel
   local-scope
   load-ingredients
@@ -12,19 +12,19 @@ def producer chan:address:shared:channel -> chan:address:shared:channel [
     # other threads might get between these prints
     $print [produce: ], n, [ 
 ]
-    chan:address:shared:channel <- write chan, n
+    chan <- write chan, n
     n <- add n, 1
     loop
   }
 ]
 
-def consumer chan:address:shared:channel -> chan:address:shared:channel [
+def consumer chan:address:shared:channel:character -> chan:address:shared:channel:character [
   # consume and print integers from a channel
   local-scope
   load-ingredients
   {
     # read an integer from the channel
-    n:character, chan:address:shared:channel <- read chan
+    n:character, chan <- read chan
     # other threads might get between these prints
     $print [consume: ], n:character, [ 
 ]
@@ -34,7 +34,7 @@ def consumer chan:address:shared:channel -> chan:address:shared:channel [
 
 def main [
   local-scope
-  chan:address:shared:channel <- new-channel 3
+  chan:address:shared:channel:character <- new-channel 3
   # create two background 'routines' that communicate by a channel
   routine1:number <- start-running producer, chan
   routine2:number <- start-running consumer, chan
diff --git a/chessboard.mu b/chessboard.mu
index 9c7f17e4..67374413 100644
--- a/chessboard.mu
+++ b/chessboard.mu
@@ -70,10 +70,10 @@ def chessboard screen:address:shared:screen, console:address:shared:console -> s
   load-ingredients
   board:address:shared:array:address:shared:array:character <- initial-position
   # hook up stdin
-  stdin:address:shared:channel <- new-channel 10/capacity
+  stdin:address:shared:channel:character <- new-channel 10/capacity
   start-running send-keys-to-channel, console, stdin, screen
   # buffer lines in stdin
-  buffered-stdin:address:shared:channel <- new-channel 10/capacity
+  buffered-stdin:address:shared:channel:character <- new-channel 10/capacity
   start-running buffer-lines, stdin, buffered-stdin
   {
     print screen, [Stupid text-mode chessboard. White pieces in uppercase; black pieces in lowercase. No checking for legal moves.
@@ -233,7 +233,7 @@ container move [
 ]
 
 # prints only error messages to screen
-def read-move stdin:address:shared:channel, screen:address:shared:screen -> result:address:shared:move, quit?:boolean, error?:boolean, stdin:address:shared:channel, screen:address:shared:screen [
+def read-move stdin:address:shared:channel:character, screen:address:shared:screen -> result:address:shared:move, quit?:boolean, error?:boolean, stdin:address:shared:channel:character, screen:address:shared:screen [
   local-scope
   load-ingredients
   from-file:number, quit?:boolean, error?:boolean <- read-file stdin, screen
@@ -263,7 +263,7 @@ def read-move stdin:address:shared:channel, screen:address:shared:screen -> resu
 ]
 
 # valid values for file: 0-7
-def read-file stdin:address:shared:channel, screen:address:shared:screen -> file:number, quit:boolean, error:boolean, stdin:address:shared:channel, screen:address:shared:screen [
+def read-file stdin:address:shared:channel:character, screen:address:shared:screen -> file:number, quit:boolean, error:boolean, stdin:address:shared:channel:character, screen:address:shared:screen [
   local-scope
   load-ingredients
   c:character, stdin <- read stdin
@@ -309,7 +309,7 @@ def read-file stdin:address:shared:channel, screen:address:shared:screen -> file
 ]
 
 # valid values: 0-7, -1 (quit), -2 (error)
-def read-rank stdin:address:shared:channel, screen:address:shared:screen -> rank:number, quit?:boolean, error?:boolean, stdin:address:shared:channel, screen:address:shared:screen [
+def read-rank stdin:address:shared:channel:character, screen:address:shared:screen -> rank:number, quit?:boolean, error?:boolean, stdin:address:shared:channel:character, screen:address:shared:screen [
   local-scope
   load-ingredients
   c:character, stdin <- read stdin
@@ -350,7 +350,7 @@ def read-rank stdin:address:shared:channel, screen:address:shared:screen -> rank
 
 # read a character from the given channel and check that it's what we expect
 # return true on error
-def expect-from-channel stdin:address:shared:channel, expected:character, screen:address:shared:screen -> result:boolean, stdin:address:shared:channel, screen:address:shared:screen [
+def expect-from-channel stdin:address:shared:channel:character, expected:character, screen:address:shared:screen -> result:boolean, stdin:address:shared:channel:character, screen:address:shared:screen [
   local-scope
   load-ingredients
   c:character, stdin <- read stdin
@@ -365,8 +365,8 @@ def expect-from-channel stdin:address:shared:channel, expected:character, screen
 scenario read-move-blocking [
   assume-screen 20/width, 2/height
   run [
-    1:address:shared:channel <- new-channel 2
-    2:number/routine <- start-running read-move, 1:address:shared:channel, screen:address:shared:screen
+    1:address:shared:channel:character <- new-channel 2
+    2:number/routine <- start-running read-move, 1:address:shared:channel:character, screen:address:shared:screen
     # 'read-move' is waiting for input
     wait-for-routine 2:number
     3:number <- routine-state 2:number/id
@@ -374,7 +374,7 @@ scenario read-move-blocking [
     assert 4:boolean/waiting?, [ 
 F read-move-blocking: routine failed to pause after coming up (before any keys were pressed)]
     # press 'a'
-    1:address:shared:channel <- write 1:address:shared:channel, 97/a
+    1:address:shared:channel:character <- write 1:address:shared:channel:character, 97/a
     restart 2:number/routine
     # 'read-move' still waiting for input
     wait-for-routine 2:number
@@ -383,7 +383,7 @@ F read-move-blocking: routine failed to pause after coming up (before any keys w
     assert 4:boolean/waiting?, [ 
 F read-move-blocking: routine failed to pause after rank 'a']
     # press '2'
-    1:address:shared:channel <- write 1:address:shared:channel, 50/'2'
+    1:address:shared:channel:character <- write 1:address:shared:channel:character, 50/'2'
     restart 2:number/routine
     # 'read-move' still waiting for input
     wait-for-routine 2:number
@@ -392,7 +392,7 @@ F read-move-blocking: routine failed to pause after rank 'a']
     assert 4:boolean/waiting?, [ 
 F read-move-blocking: routine failed to pause after file 'a2']
     # press '-'
-    1:address:shared:channel <- write 1:address:shared:channel, 45/'-'
+    1:address:shared:channel:character <- write 1:address:shared:channel:character, 45/'-'
     restart 2:number/routine
     # 'read-move' still waiting for input
     wait-for-routine 2:number
@@ -401,7 +401,7 @@ F read-move-blocking: routine failed to pause after file 'a2']
     assert 4:boolean/waiting?/routine-state, [ 
 F read-move-blocking: routine failed to pause after hyphen 'a2-']
     # press 'a'
-    1:address:shared:channel <- write 1:address:shared:channel, 97/a
+    1:address:shared:channel:character <- write 1:address:shared:channel:character, 97/a
     restart 2:number/routine
     # 'read-move' still waiting for input
     wait-for-routine 2:number
@@ -410,7 +410,7 @@ F read-move-blocking: routine failed to pause after hyphen 'a2-']
     assert 4:boolean/waiting?/routine-state, [ 
 F read-move-blocking: routine failed to pause after rank 'a2-a']
     # press '4'
-    1:address:shared:channel <- write 1:address:shared:channel, 52/'4'
+    1:address:shared:channel:character <- write 1:address:shared:channel:character, 52/'4'
     restart 2:number/routine
     # 'read-move' still waiting for input
     wait-for-routine 2:number
@@ -419,7 +419,7 @@ F read-move-blocking: routine failed to pause after rank 'a2-a']
     assert 4:boolean/waiting?, [ 
 F read-move-blocking: routine failed to pause after file 'a2-a4']
     # press 'newline'
-    1:address:shared:channel <- write 1:address:shared:channel, 10  # newline
+    1:address:shared:channel:character <- write 1:address:shared:channel:character, 10  # newline
     restart 2:number/routine
     # 'read-move' now completes
     wait-for-routine 2:number
@@ -437,8 +437,8 @@ F read-move-blocking: routine failed to terminate on newline]
 scenario read-move-quit [
   assume-screen 20/width, 2/height
   run [
-    1:address:shared:channel <- new-channel 2
-    2:number/routine <- start-running read-move, 1:address:shared:channel, screen:address:shared:screen
+    1:address:shared:channel:character <- new-channel 2
+    2:number/routine <- start-running read-move, 1:address:shared:channel:character, screen:address:shared:screen
     # 'read-move' is waiting for input
     wait-for-routine 2:number
     3:number <- routine-state 2:number/id
@@ -446,7 +446,7 @@ scenario read-move-quit [
     assert 4:boolean/waiting?, [ 
 F read-move-quit: routine failed to pause after coming up (before any keys were pressed)]
     # press 'q'
-    1:address:shared:channel <- write 1:address:shared:channel, 113/q
+    1:address:shared:channel:character <- write 1:address:shared:channel:character, 113/q
     restart 2:number/routine
     # 'read-move' completes
     wait-for-routine 2:number
@@ -464,15 +464,15 @@ F read-move-quit: routine failed to terminate on 'q']
 scenario read-move-illegal-file [
   assume-screen 20/width, 2/height
   run [
-    1:address:shared:channel <- new-channel 2
-    2:number/routine <- start-running read-move, 1:address:shared:channel, screen:address:shared:screen
+    1:address:shared:channel:character <- new-channel 2
+    2:number/routine <- start-running read-move, 1:address:shared:channel:character, screen:address:shared:screen
     # 'read-move' is waiting for input
     wait-for-routine 2:number
     3:number <- routine-state 2:number/id
     4:boolean/waiting? <- equal 3:number/routine-state, 3/waiting
     assert 4:boolean/waiting?, [ 
 F read-move-file: routine failed to pause after coming up (before any keys were pressed)]
-    1:address:shared:channel <- write 1:address:shared:channel, 50/'2'
+    1:address:shared:channel:character <- write 1:address:shared:channel:character, 50/'2'
     restart 2:number/routine
     wait-for-routine 2:number
   ]
@@ -485,16 +485,16 @@ F read-move-file: routine failed to pause after coming up (before any keys were
 scenario read-move-illegal-rank [
   assume-screen 20/width, 2/height
   run [
-    1:address:shared:channel <- new-channel 2
-    2:number/routine <- start-running read-move, 1:address:shared:channel, screen:address:shared:screen
+    1:address:shared:channel:character <- new-channel 2
+    2:number/routine <- start-running read-move, 1:address:shared:channel:character, screen:address:shared:screen
     # 'read-move' is waiting for input
     wait-for-routine 2:number
     3:number <- routine-state 2:number/id
     4:boolean/waiting? <- equal 3:number/routine-state, 3/waiting
     assert 4:boolean/waiting?, [ 
 F read-move-file: routine failed to pause after coming up (before any keys were pressed)]
-    1:address:shared:channel <- write 1:address:shared:channel, 97/a
-    1:address:shared:channel <- write 1:address:shared:channel, 97/a
+    1:address:shared:channel:character <- write 1:address:shared:channel:character, 97/a
+    1:address:shared:channel:character <- write 1:address:shared:channel:character, 97/a
     restart 2:number/routine
     wait-for-routine 2:number
   ]
@@ -507,16 +507,16 @@ F read-move-file: routine failed to pause after coming up (before any keys were
 scenario read-move-empty [
   assume-screen 20/width, 2/height
   run [
-    1:address:shared:channel <- new-channel 2
-    2:number/routine <- start-running read-move, 1:address:shared:channel, screen:address:shared:screen
+    1:address:shared:channel:character <- new-channel 2
+    2:number/routine <- start-running read-move, 1:address:shared:channel:character, screen:address:shared:screen
     # 'read-move' is waiting for input
     wait-for-routine 2:number
     3:number <- routine-state 2:number/id
     4:boolean/waiting? <- equal 3:number/routine-state, 3/waiting
     assert 4:boolean/waiting?, [ 
 F read-move-file: routine failed to pause after coming up (before any keys were pressed)]
-    1:address:shared:channel <- write 1:address:shared:channel, 10/newline
-    1:address:shared:channel <- write 1:address:shared:channel, 97/a
+    1:address:shared:channel:character <- write 1:address:shared:channel:character, 10/newline
+    1:address:shared:channel:character <- write 1:address:shared:channel:character, 97/a
     restart 2:number/routine
     wait-for-routine 2:number
   ]