type environment {
screen: (handle screen)
buf: gap-buffer
cursor-row: int
cursor-col: int
}
fn initialize-environment _env: (addr environment) {
var env/esi: (addr environment) <- copy _env
var screen-ah/edi: (addr handle screen) <- get env, screen
var _screen/eax: (addr screen) <- lookup *screen-ah
var screen/edi: (addr screen) <- copy _screen
{
var cursor-col/eax: (addr int) <- get env, cursor-col
copy-to *cursor-col, 3
}
{
var cursor-row/eax: (addr int) <- get env, cursor-row
copy-to *cursor-row, 3
}
# buf
var gap/eax: (addr gap-buffer) <- get env, buf
initialize-gap-buffer gap
}
fn initialize-environment-with-fake-screen _self: (addr environment), nrows: int, ncols: int {
var self/esi: (addr environment) <- copy _self
var screen-ah/eax: (addr handle screen) <- get self, screen
allocate screen-ah
var screen-addr/eax: (addr screen) <- lookup *screen-ah
initialize-screen screen-addr, nrows, ncols
initialize-environment self
}
fn render-loop _self: (addr environment) {
var self/esi: (addr environment) <- copy _self
render self
#
$interactive:loop: {
var key/eax: grapheme <- read-key-from-real-keyboard
compare key, 0x71 # 'q'
break-if-=
process self, key
loop
}
}
fn process _self: (addr environment), key: grapheme {
$process:body: {
var self/esi: (addr environment) <- copy _self
var screen-ah/edi: (addr handle screen) <- get self, screen
var _screen/eax: (addr screen) <- lookup *screen-ah
var screen/edi: (addr screen) <- copy _screen
var buf/ebx: (addr gap-buffer) <- get self, buf
compare key, 0x445b1b # left-arrow
{
break-if-!=
var char-skipped/eax: grapheme <- gap-left buf
compare char-skipped, -1
{
break-if-=
var cursor-row/eax: (addr int) <- get self, cursor-row
var cursor-col/ecx: (addr int) <- get self, cursor-col
decrement *cursor-col
move-cursor screen, *cursor-row, *cursor-col
}
break $process:body
}
compare key, 0x435b1b # right-arrow
{
break-if-!=
var char-skipped/eax: grapheme <- gap-right buf
compare char-skipped, -1
{
break-if-=
var cursor-row/eax: (addr int) <- get self, cursor-row
var cursor-col/ecx: (addr int) <- get self, cursor-col
increment *cursor-col
move-cursor screen, *cursor-row, *cursor-col
}
break $process:body
}
var g/ecx: grapheme <- copy key
var print?/eax: boolean <- real-grapheme? key
{
compare print?, 0 # false
break-if-=
add-grapheme-at-gap buf, g
var cursor-col/eax: (addr int) <- get self, cursor-col
increment *cursor-col
render self
break $process:body
}
# silently ignore other hotkeys
}
}
fn render _env: (addr environment) {
var env/esi: (addr environment) <- copy _env
var screen-ah/edi: (addr handle screen) <- get env, screen
var _screen/eax: (addr screen) <- lookup *screen-ah
var screen/edi: (addr screen) <- copy _screen
# prepare screen
clear-screen screen
move-cursor screen, 3, 3
# render input area
var buf/ecx: (addr gap-buffer) <- get env, buf
render-gap-buffer screen, buf
#? # render stacks
#? render-all-stacks screen
# update cursor
var cursor-row/eax: (addr int) <- get env, cursor-row
var cursor-col/ecx: (addr int) <- get env, cursor-col
move-cursor screen, *cursor-row, *cursor-col
}