diff options
-rw-r--r-- | 112read-byte.subx | 32 | ||||
-rw-r--r-- | 400.mu | 1 | ||||
-rw-r--r-- | browse_slack/main.mu | 71 |
3 files changed, 104 insertions, 0 deletions
diff --git a/112read-byte.subx b/112read-byte.subx index 93503d8b..5ffd4903 100644 --- a/112read-byte.subx +++ b/112read-byte.subx @@ -42,6 +42,38 @@ $read-byte:abort: (abort "read-byte: empty stream") # 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 _test-input-stream: # (stream byte) diff --git a/400.mu b/400.mu index 6640a524..d1143ea8 100644 --- a/400.mu +++ b/400.mu @@ -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-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 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 diff --git a/browse_slack/main.mu b/browse_slack/main.mu index dadf653c..f4a5abfb 100644 --- a/browse_slack/main.mu +++ b/browse_slack/main.mu @@ -86,6 +86,9 @@ fn parse in: (addr stream byte), users: (addr array user), channels: (addr array var done?/eax: boolean <- stream-empty? in compare done?, 0/false 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 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) { + 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 { + 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 } @@ -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 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 + } +} |