about summary refs log tree commit diff stats
path: root/074console.mu
blob: 1d9702dac83898573341f36c1965cafe94c84075 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { 
# Wrappers around interaction primitives that take a potentially fake object
# and are thus easier to test.

exclusive-container event [
  text:character
  keycode:number  # keys on keyboard without a unicode representation
  touch:touch-event  # mouse, track ball, etc.
  # update the assume-console handler if you add more variants
]

container touch-event [
  type:number
  row:number
  column:number
]

container console [
  index:number
  data:address:array:event
]

recipe new-fake-console [
  default-space:address:array:location <- new location:type, 30:literal
  result:address:console <- new console:type
  buf:address:address:array:character <- get-address result:address:console/deref, data:offset
#?   $start-tracing #? 1
  buf:address:address:array:character/deref <- next-ingredient
#?   $stop-tracing #? 1
  idx:address:number <- get-address result:address:console/deref, index:offset
  idx:address:number/deref <- copy 0:literal
  reply result:address:console
]

recipe read-event [
  default-space:address:array:location <- new location:type, 30:literal
  x:address:console <- next-ingredient
  {
    break-unless x:address:console
    idx:address:number <- get-address x:address:console/deref, index:offset
    buf:address:array:event <- get x:address:console/deref, data:offset
    {
      max:number <- length buf:address:array:event/deref
      done?:boolean <- greater-or-equal idx:address:number/deref, max:number
      break-unless done?:boolean
      dummy:address:event <- new event:type
      reply dummy:address:event/deref, x:address:console/same-as-ingredient:0, 1:literal/found, 1:literal/quit
    }
    result:event <- index buf:address:array:event/deref, idx:address:number/deref
    idx:address:number/deref <- add idx:address:number/deref, 1:literal
    reply result:event, x:address:console/same-as-ingredient:0, 1:literal/found, 0:literal/quit
  }
  # real event source is infrequent; avoid polling it too much
  switch
  result:event, found?:boolean <- check-for-interaction
  reply result:event, x:address:console/same-as-ingredient:0, found?:boolean, 0:literal/quit
]

# variant of read-event for just keyboard events. Discards everything that
# isn't unicode, so no arrow keys, page-up/page-down, etc. But you still get
# newlines, tabs, ctrl-d..
recipe read-key [
  default-space:address:array:location <- new location:type, 30:literal
#?   $print default-space:address:array:location #? 1
#?   $exit #? 1
#?   $start-tracing #? 1
  console:address <- next-ingredient
  x:event, console:address, found?:boolean, quit?:boolean <- read-event console:address
#?   $print [aaa 1] #? 1
  reply-if quit?:boolean, 0:literal, console:address/same-as-ingredient:0, found?:boolean, quit?:boolean
#?   $print [aaa 2] #? 1
  reply-unless found?:boolean, 0:literal, console:address/same-as-ingredient:0, found?:boolean, quit?:boolean
#?   $print [aaa 3] #? 1
  c:address:character <- maybe-convert x:event, text:variant
  reply-unless c:address:character, 0:literal, console:address/same-as-ingredient:0, 0:literal/found, 0:literal/quit
#?   $print [aaa 4] #? 1
  reply c:address:character/deref, console:address/same-as-ingredient:0, 1:literal/found, 0:literal/quit
]

recipe send-keys-to-channel [
  default-space:address:array:location <- new location:type, 30:literal
  console:address <- next-ingredient
  chan:address:channel <- next-ingredient
  screen:address <- next-ingredient
  {
    c:character, console:address, found?:boolean, quit?:boolean <- read-key console:address
    loop-unless found?:boolean
    break-if quit?:boolean
    assert c:character, [invalid event, expected text]
    print-character screen:address, c:character
    chan:address:channel <- write chan:address:channel, c:character
    loop
  }
]

recipe wait-for-event [
  default-space:address:array:location <- new location:type, 30:literal
  console:address <- next-ingredient
  {
    _, console:address, found?:boolean <- read-event console:address
    loop-unless found?:boolean
  }
]