This commit is contained in:
Kartik K. Agaram 2021-08-10 05:52:48 -07:00
parent ed068e859d
commit e72e5ad297
3 changed files with 104 additions and 0 deletions

View File

@ -42,6 +42,38 @@ $read-byte:abort:
(abort "read-byte: empty stream") (abort "read-byte: empty stream")
# never gets here # never gets here
# Return next byte value in eax, with top 3 bytes cleared.
# Abort on reaching end of stream.
peek-byte: # s: (addr stream byte) -> result/eax: byte
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
# . save registers
51/push-ecx
56/push-esi
# esi = s
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
# ecx = s->read
8b/copy 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 4/disp8 . # copy *(esi+4) to ecx
# if (f->read >= f->write) abort
3b/compare 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # compare ecx with *esi
0f 8d/jump-if->= $peek-byte:abort/disp32
# result = f->data[f->read]
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
8a/copy-byte 1/mod/*+disp8 4/rm32/sib 6/base/esi 1/index/ecx . 0/r32/AL 0xc/disp8 . # copy byte at *(esi+ecx+12) to AL
$peek-byte:end:
# . restore registers
5e/pop-to-esi
59/pop-to-ecx
# . epilogue
89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp
5d/pop-to-ebp
c3/return
$peek-byte:abort:
(abort "peek-byte: empty stream")
# never gets here
== data == data
_test-input-stream: # (stream byte) _test-input-stream: # (stream byte)

1
400.mu
View File

@ -59,6 +59,7 @@ sig space-remaining-in-stream f: (addr stream byte) -> _/eax: int
sig write-stream f: (addr stream byte), s: (addr stream byte) sig write-stream f: (addr stream byte), s: (addr stream byte)
sig write-stream-immutable f: (addr stream byte), s: (addr stream byte) sig write-stream-immutable f: (addr stream byte), s: (addr stream byte)
sig read-byte s: (addr stream byte) -> _/eax: 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 append-byte f: (addr stream byte), n: int # really just a byte, but I want to pass in literal numbers
#sig to-hex-char in/eax: int -> out/eax: int #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 append-byte-hex f: (addr stream byte), n: int # really just a byte, but I want to pass in literal numbers

View File

@ -86,6 +86,9 @@ fn parse in: (addr stream byte), users: (addr array user), channels: (addr array
var done?/eax: boolean <- stream-empty? in var done?/eax: boolean <- stream-empty? in
compare done?, 0/false compare done?, 0/false
break-if-!= break-if-!=
set-cursor-position 0/screen, 0 0
draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, user-idx, 3/fg 0/bg
draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, item-idx, 4/fg 0/bg
parse-record in, record parse-record in, record
var user?/eax: boolean <- user-record? record var user?/eax: boolean <- user-record? record
{ {
@ -105,9 +108,49 @@ fn parse in: (addr stream byte), users: (addr array user), channels: (addr array
} }
fn parse-record in: (addr stream byte), out: (addr stream byte) { fn parse-record in: (addr stream byte), out: (addr stream byte) {
var paren/eax: byte <- read-byte in
compare paren, 0x28/open-paren
{
break-if-=
abort "parse-record: ("
}
var paren-int/eax: int <- copy paren
append-byte out, paren-int
{
{
var eof?/eax: boolean <- stream-empty? in
compare eof?, 0/false
break-if-=
abort "parse-record: truncated"
}
var c/eax: byte <- read-byte in
{
var c-int/eax: int <- copy c
append-byte out, c-int
}
compare c, 0x29/close-paren
break-if-=
compare c, 0x22/double-quote
{
break-if-!=
slurp-json-string in, out
}
loop
}
skip-chars-matching-whitespace in
} }
fn user-record? record: (addr stream byte) -> _/eax: boolean { fn user-record? record: (addr stream byte) -> _/eax: boolean {
rewind-stream record
var c/eax: byte <- read-byte record # skip paren
var c/eax: byte <- read-byte record # skip double quote
var c/eax: byte <- read-byte record
compare c, 0x55/U
{
break-if-!=
return 1/true
}
rewind-stream record
return 0/false return 0/false
} }
@ -116,3 +159,31 @@ fn parse-user record: (addr stream byte), users: (addr array user), user-idx: in
fn parse-item record: (addr stream byte), channels: (addr array channel), items: (addr array item), item-idx: int { fn parse-item record: (addr stream byte), channels: (addr array channel), items: (addr array item), item-idx: int {
} }
fn slurp-json-string in: (addr stream byte), out: (addr stream byte) {
# open quote is already slurped
{
{
var eof?/eax: boolean <- stream-empty? in
compare eof?, 0/false
break-if-=
abort "slurp-json-string: truncated"
}
var c/eax: byte <- read-byte in
{
var c-int/eax: int <- copy c
append-byte out, c-int
}
compare c, 0x22/double-quote
break-if-=
compare c, 0x5c/backslash
{
break-if-!=
# read next byte raw
c <- read-byte in
var c-int/eax: int <- copy c
append-byte out, c-int
}
loop
}
}