diff --git a/115write-byte.subx b/115write-byte.subx index 67516731..0df1b85e 100644 --- a/115write-byte.subx +++ b/115write-byte.subx @@ -76,4 +76,29 @@ test-append-byte-single: # . end c3/return +undo-append-byte: # f: (addr stream byte) + # . prologue + 55/push-ebp + 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp + # . save registers + 50/push-eax + # eax = f + 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 8/disp8 . # copy *(ebp+8) to eax + # if (f->write <= 0) abort + 81 7/subop/compare 0/mod/indirect 0/rm32/eax . . . . . 0/imm32 # compare *eax + 7e/jump-if-<= $undo-append-byte:abort/disp8 + # --f->write + ff 1/subop/decrement 0/mod/indirect 0/rm32/eax . . . . . . # decrement *eax +$undo-append-byte:end: + # . restore registers + 58/pop-to-eax + # . epilogue + 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp + 5d/pop-to-ebp + c3/return + +$undo-append-byte:abort: + (abort "undo-append-byte: empty stream") + # never gets here + # . . vim:nowrap:textwidth=0 diff --git a/400.mu b/400.mu index 539093b8..9baad977 100644 --- a/400.mu +++ b/400.mu @@ -65,6 +65,7 @@ sig write-stream-immutable f: (addr stream byte), s: (addr stream byte) sig read-byte s: (addr stream byte) -> _/eax: byte sig peek-byte s: (addr stream byte) -> _/eax: byte sig append-byte f: (addr stream byte), n: int # really just a byte, but I want to pass in literal numbers +sig undo-append-byte f: (addr stream byte) # take most recent append back out #sig to-hex-char in/eax: int -> out/eax: int sig append-byte-hex f: (addr stream byte), n: int # really just a byte, but I want to pass in literal numbers sig write-int32-hex f: (addr stream byte), n: int diff --git a/516read-line.mu b/516read-line.mu index 1bb79c5a..5c96a832 100644 --- a/516read-line.mu +++ b/516read-line.mu @@ -2,13 +2,24 @@ # abort on stream overflow fn read-line-from-keyboard keyboard: (addr keyboard), out: (addr stream byte), screen: (addr screen), fg: int, bg: int { clear-stream out - { + $read-line-from-keyboard:loop: { draw-cursor screen, 0x20/space var key/eax: byte <- read-key keyboard compare key, 0xa/newline break-if-= compare key, 0 loop-if-= + compare key, 8/backspace + { + break-if-!= + undo-append-byte out + draw-code-point-at-cursor-over-full-screen screen, 0x20/space, fg 0/bg # clear cursor + move-cursor-left screen + move-cursor-left screen + draw-code-point-at-cursor-over-full-screen screen, 0x20/space, fg 0/bg # clear old cursor + move-cursor-left screen + loop $read-line-from-keyboard:loop + } var key2/eax: int <- copy key append-byte out, key2 var c/eax: code-point <- copy key2