6794 - cleaner interface for keyboard

So far I've been assuming that read-key only works for ascii, and that
I'd need to get more sophisticated both for multi-byte utf-8 and multi-byte
terminal escape codes like arrow keys. Rather to my surprise, both work
fine. We just need to adjust the types to reflect this fact.
This commit is contained in:
Kartik Agaram 2020-09-16 18:54:12 -07:00
parent 797c93e054
commit e403d15732
37 changed files with 61 additions and 53 deletions

View File

@ -119,15 +119,22 @@ $enable-keyboard-type-mode:end:
5d/pop-to-ebp
c3/return
read-key-from-real-keyboard: # -> result/eax: byte
# read keys or escapes up to 4 bytes
#
# fun fact: terminal escapes and graphemes in utf-8 don't conflict!
# - in graphemes all but the first/lowest byte will have a 1 in the MSB (be
# greater than 0x7f)
# - in escapes every byte will have a 0 in the MSB
# the two categories overlap only when the first/lowest byte is 0x1b or 'esc'
read-key-from-real-keyboard: # -> result/eax: grapheme
# . prologue
55/push-ebp
89/<- %ebp 4/r32/esp
# . save registers
51/push-ecx
# var buf/ecx: (stream byte 1)
# var buf/ecx: (stream byte 4)
68/push 0/imm32/data
68/push 1/imm32/size # 3 bytes of data unused
68/push 4/imm32/size
68/push 0/imm32/read
68/push 0/imm32/write
89/<- %ecx 4/r32/esp

2
400.mu
View File

@ -161,7 +161,7 @@ sig hide-cursor-on-real-screen
sig show-cursor-on-real-screen
sig enable-keyboard-immediate-mode
sig enable-keyboard-type-mode
sig read-key-from-real-keyboard -> result/eax: byte
sig read-key-from-real-keyboard -> result/eax: grapheme
sig read-line-from-real-keyboard in: (addr stream byte)
sig open filename: (addr array byte), write?: boolean, out: (addr handle buffered-file)
sig populate-buffered-file-containing contents: (addr array byte), out: (addr handle buffered-file)

View File

@ -13,7 +13,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
enable-keyboard-immediate-mode
{
render file, nrows, ncols
var key/eax: byte <- read-key
var key/eax: grapheme <- read-key-from-real-keyboard
compare key, 0x71 # 'q'
loop-if-!=
}

View File

@ -11,7 +11,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
enable-keyboard-immediate-mode
{
render file, nrows, ncols
var key/eax: byte <- read-key
var key/eax: grapheme <- read-key-from-real-keyboard
compare key, 0x71 # 'q'
loop-if-!=
}

View File

@ -10,7 +10,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
enable-keyboard-immediate-mode
{
render file, nrows, ncols
var key/eax: byte <- read-key
var key/eax: grapheme <- read-key-from-real-keyboard
compare key, 0x71 # 'q'
loop-if-!=
}

View File

@ -10,7 +10,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
enable-keyboard-immediate-mode
{
render file, nrows, ncols
var key/eax: byte <- read-key
var key/eax: grapheme <- read-key-from-real-keyboard
compare key, 0x71 # 'q'
loop-if-!=
}

View File

@ -8,7 +8,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
enable-keyboard-immediate-mode
{
render file, nrows, ncols
var key/eax: byte <- read-key
var key/eax: grapheme <- read-key-from-real-keyboard
compare key, 0x71 # 'q'
loop-if-!=
}

View File

@ -13,7 +13,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
enable-keyboard-immediate-mode
{
render file, nrows, ncols
var key/eax: byte <- read-key
var key/eax: grapheme <- read-key-from-real-keyboard
compare key, 0x71 # 'q'
loop-if-!=
}

View File

@ -32,7 +32,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
init-screen-position-state screen-position-state, nrows, ncols
{
render file, screen-position-state
var key/eax: byte <- read-key
var key/eax: grapheme <- read-key-from-real-keyboard
compare key, 0x71 # 'q'
loop-if-!=
}

View File

@ -19,7 +19,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
compare done?, 0
break-if-=
render fs, screen-position-state
var key/eax: byte <- read-key
var key/eax: grapheme <- read-key-from-real-keyboard
compare key, 0x71 # 'q'
loop-if-!=
}

View File

@ -13,7 +13,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
init-screen-position-state screen-position-state
{
render fs, screen-position-state
var key/eax: byte <- read-key
var key/eax: grapheme <- read-key-from-real-keyboard
}
enable-keyboard-type-mode
enable-screen-type-mode

View File

@ -13,7 +13,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
init-screen-position-state screen-position-state
{
render fs, screen-position-state
var key/eax: byte <- read-key
var key/eax: grapheme <- read-key-from-real-keyboard
}
enable-keyboard-type-mode
enable-screen-type-mode

View File

@ -13,7 +13,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
init-screen-position-state screen-position-state
{
render fs, screen-position-state
var key/eax: byte <- read-key
var key/eax: grapheme <- read-key-from-real-keyboard
}
enable-keyboard-type-mode
enable-screen-type-mode

View File

@ -13,7 +13,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
init-screen-position-state screen-position-state
{
render fs, screen-position-state
var key/eax: byte <- read-key
var key/eax: grapheme <- read-key-from-real-keyboard
}
enable-keyboard-type-mode
enable-screen-type-mode

View File

@ -13,7 +13,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
init-screen-position-state screen-position-state
{
render fs, screen-position-state
var key/eax: byte <- read-key
var key/eax: grapheme <- read-key-from-real-keyboard
compare key, 0x71 # 'q'
loop-if-!=
}

View File

@ -14,7 +14,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
normal-text
{
render fs, screen-position-state
var key/eax: byte <- read-key
var key/eax: grapheme <- read-key-from-real-keyboard
compare key, 0x71 # 'q'
loop-if-!=
}

View File

@ -14,7 +14,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
normal-text
{
render fs, screen-position-state
var key/eax: byte <- read-key
var key/eax: grapheme <- read-key-from-real-keyboard
compare key, 0x71 # 'q'
loop-if-!=
}

View File

@ -14,7 +14,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
normal-text
{
render fs, screen-position-state
var key/eax: byte <- read-key
var key/eax: grapheme <- read-key-from-real-keyboard
compare key, 0x71 # 'q'
loop-if-!=
}

View File

@ -14,7 +14,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
normal-text
{
render fs, screen-position-state
var key/eax: byte <- read-key
var key/eax: grapheme <- read-key-from-real-keyboard
compare key, 0x71 # 'q'
loop-if-!=
}

View File

@ -14,7 +14,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
normal-text
{
render fs, screen-position-state
var key/eax: byte <- read-key
var key/eax: grapheme <- read-key-from-real-keyboard
compare key, 0x71 # 'q'
loop-if-!=
}

View File

@ -14,7 +14,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
normal-text
{
render fs, screen-position-state
var key/eax: byte <- read-key
var key/eax: grapheme <- read-key-from-real-keyboard
compare key, 0x71 # 'q'
loop-if-!=
}

View File

@ -4,8 +4,8 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
enable-screen-grid-mode
enable-keyboard-immediate-mode
{
render file, 5, 5, 30, 30
var key/eax: byte <- read-key
render file, 5, 5, 0x30, 0x30
var key/eax: grapheme <- read-key-from-real-keyboard
compare key, 0x71 # 'q'
loop-if-!=
}

View File

@ -4,8 +4,8 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
enable-screen-grid-mode
enable-keyboard-immediate-mode
{
render file, 5, 5, 30, 30
var key/eax: byte <- read-key
render file, 5, 5, 0x30, 0x30
var key/eax: grapheme <- read-key-from-real-keyboard
compare key, 0x71 # 'q'
loop-if-!=
}

View File

@ -5,7 +5,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
enable-keyboard-immediate-mode
{
render file, 0x20, 0x30 # nrows, ncols
var key/eax: byte <- read-key
var key/eax: grapheme <- read-key-from-real-keyboard
compare key, 0x71 # 'q'
loop-if-!=
}

View File

@ -8,7 +8,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
enable-keyboard-immediate-mode
{
render file, nrows, ncols
var key/eax: byte <- read-key
var key/eax: grapheme <- read-key-from-real-keyboard
compare key, 0x71 # 'q'
loop-if-!=
}

View File

@ -8,7 +8,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
enable-keyboard-immediate-mode
{
render file, nrows, ncols
var key/eax: byte <- read-key
var key/eax: grapheme <- read-key-from-real-keyboard
compare key, 0x71 # 'q'
loop-if-!=
}

View File

@ -8,7 +8,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
enable-keyboard-immediate-mode
{
render file, nrows, ncols
var key/eax: byte <- read-key
var key/eax: grapheme <- read-key-from-real-keyboard
compare key, 0x71 # 'q'
loop-if-!=
}

4
prototypes/tile/1.mu generated
View File

@ -14,7 +14,7 @@ fn main -> exit-status/ebx: int {
move-cursor 0, 5, 5
print-string 0, "_________"
enable-keyboard-immediate-mode
var dummy/eax: byte <- read-key
var dummy/eax: grapheme <- read-key-from-real-keyboard
var row/eax: int <- copy 5
{
compare row, 0xe # 15
@ -24,7 +24,7 @@ fn main -> exit-status/ebx: int {
sleep 0 0x5f5e100 # 100ms
loop
}
var dummy/eax: byte <- read-key
var dummy/eax: grapheme <- read-key-from-real-keyboard
enable-keyboard-type-mode
clear-screen 0
exit-status <- copy 0

6
prototypes/tile/10.mu generated
View File

@ -63,14 +63,14 @@ fn interactive -> exit-status/ebx: int {
$main:loop: {
# process key
{
var c/eax: byte <- read-key
var c/eax: grapheme <- read-key-from-real-keyboard
compare c, 4 # ctrl-d
break-if-= $main:loop
process c, root, cursor
}
# render tree
var _root-addr/eax: (addr cell) <- lookup root-handle
var root-addr/ecx: (addr cell) <- copy _root-addr
root-addr <- copy _root-addr
var cursor-addr/eax: (addr cell) <- lookup *cursor
render root-addr, cursor-addr
loop
@ -84,7 +84,7 @@ $main:loop: {
# Tree mutations
#######################################################
fn process c: byte, root: (addr handle cell), cursor: (addr handle cell) {
fn process c: grapheme, root: (addr handle cell), cursor: (addr handle cell) {
$process:body: {
# if c == 'h' move cursor to its parent if possible
{

4
prototypes/tile/11.mu generated
View File

@ -63,7 +63,7 @@ fn interactive -> exit-status/ebx: int {
$main:loop: {
# process key
{
var c/eax: byte <- read-key
var c/eax: grapheme <- read-key-from-real-keyboard
compare c, 4 # ctrl-d
break-if-= $main:loop
process c, root, cursor
@ -84,7 +84,7 @@ $main:loop: {
# Tree mutations
#######################################################
fn process c: byte, root: (addr handle cell), cursor: (addr handle cell) {
fn process c: grapheme, root: (addr handle cell), cursor: (addr handle cell) {
$process:body: {
# if c == 'h' move cursor to its parent if possible
{

2
prototypes/tile/2.mu generated
View File

@ -32,7 +32,7 @@ fn main -> exit-status/ebx: int {
# wait for a key
{
enable-keyboard-immediate-mode
var dummy/eax: byte <- read-key
var dummy/eax: grapheme <- read-key-from-real-keyboard
enable-keyboard-type-mode
}
# clean up

4
prototypes/tile/4.mu generated
View File

@ -9,7 +9,7 @@
fn main -> exit-status/ebx: int {
clear-screen 0
enable-keyboard-immediate-mode
var dummy/eax: byte <- read-key
var dummy/eax: grapheme <- read-key-from-real-keyboard
draw-box 5, 5, 0x23, 0x23 # 35, 35
sleep 0 0x5f5e100 # 100ms
sleep 0 0x5f5e100 # 100ms
@ -17,7 +17,7 @@ fn main -> exit-status/ebx: int {
sleep 0 0x5f5e100 # 100ms
sleep 0 0x5f5e100 # 100ms
draw-box 5, 5, 0x23, 0xaf # 35, 175
var dummy/eax: byte <- read-key
var dummy/eax: grapheme <- read-key-from-real-keyboard
enable-keyboard-type-mode
clear-screen 0
exit-status <- copy 0

4
prototypes/tile/5.mu generated
View File

@ -31,7 +31,7 @@ fn main -> exit-status/ebx: int {
$main:loop: {
# process key
{
var c/eax: byte <- read-key
var c/eax: grapheme <- read-key-from-real-keyboard
compare c, 4 # ctrl-d
break-if-= $main:loop
process c, root, cursor
@ -50,7 +50,7 @@ $main:loop: {
# Tree mutations
#######################################################
fn process c: byte, root: (addr handle cell), cursor: (addr handle cell) {
fn process c: grapheme, root: (addr handle cell), cursor: (addr handle cell) {
var c1/eax: (addr handle cell) <- copy cursor
var c2/eax: (addr cell) <- lookup *c1
create-child c2

4
prototypes/tile/6.mu generated
View File

@ -58,7 +58,7 @@ fn interactive -> exit-status/ebx: int {
$main:loop: {
# process key
{
var c/eax: byte <- read-key
var c/eax: grapheme <- read-key-from-real-keyboard
compare c, 4 # ctrl-d
break-if-= $main:loop
process c, root, cursor
@ -77,7 +77,7 @@ $main:loop: {
# Tree mutations
#######################################################
fn process c: byte, root: (addr handle cell), cursor: (addr handle cell) {
fn process c: grapheme, root: (addr handle cell), cursor: (addr handle cell) {
# increase depth by 1
var c1/ecx: (addr handle cell) <- copy cursor
var c2/eax: (addr cell) <- lookup *c1

4
prototypes/tile/7.mu generated
View File

@ -62,7 +62,7 @@ fn interactive -> exit-status/ebx: int {
$main:loop: {
# process key
{
var c/eax: byte <- read-key
var c/eax: grapheme <- read-key-from-real-keyboard
compare c, 4 # ctrl-d
break-if-= $main:loop
process c, root, cursor
@ -81,7 +81,7 @@ $main:loop: {
# Tree mutations
#######################################################
fn process c: byte, root: (addr handle cell), cursor: (addr handle cell) {
fn process c: grapheme, root: (addr handle cell), cursor: (addr handle cell) {
var c1/ecx: (addr handle cell) <- copy cursor
var c2/eax: (addr cell) <- lookup *c1
create-child c2

4
prototypes/tile/8.mu generated
View File

@ -62,7 +62,7 @@ fn interactive -> exit-status/ebx: int {
$main:loop: {
# process key
{
var c/eax: byte <- read-key
var c/eax: grapheme <- read-key-from-real-keyboard
compare c, 4 # ctrl-d
break-if-= $main:loop
process c, root, cursor
@ -81,7 +81,7 @@ $main:loop: {
# Tree mutations
#######################################################
fn process c: byte, root: (addr handle cell), cursor: (addr handle cell) {
fn process c: grapheme, root: (addr handle cell), cursor: (addr handle cell) {
var c1/ecx: (addr handle cell) <- copy cursor
var c2/eax: (addr cell) <- lookup *c1
create-child c2

9
prototypes/tile/9.mu generated
View File

@ -60,14 +60,15 @@ fn interactive -> exit-status/ebx: int {
$main:loop: {
# process key
{
var c/eax: byte <- read-key
var c/eax: grapheme <- read-key-from-real-keyboard
compare c, 4 # ctrl-d
break-if-= $main:loop
process c, root, cursor
}
# render tree
root-addr <- lookup root-handle
cursor-addr <- lookup *cursor
var _root-addr/eax: (addr cell) <- lookup root-handle
root-addr <- copy _root-addr
var cursor-addr/eax: (addr cell) <- lookup *cursor
render root-addr, cursor-addr
loop
}
@ -80,7 +81,7 @@ $main:loop: {
# Tree mutations
#######################################################
fn process c: byte, root: (addr handle cell), cursor: (addr handle cell) {
fn process c: grapheme, root: (addr handle cell), cursor: (addr handle cell) {
$process:body: {
# if c == 'h' move cursor to its parent if possible
{