lib: graduate utf8.runesz and bufio.readbyte to (i32 | void)

Both used the -1 sentinel return; both had no external callers, so
the graduation is purely the API-shape change. utf8.runesz uses void
for "rune outside legal range"; bufio.readbyte uses void for EOF
(empty buffer). The full Hare shapes ((size | invalid) and
(u8 | EOF | io::error)) are still richer than this — those richer
returns arrive when utf8 grows an explicit invalid type and bufio
wires through io::stream's error path.
This commit is contained in:
2026-05-12 02:12:33 +09:00
parent 2f385cec00
commit e9c3f75fd1
2 changed files with 11 additions and 9 deletions

View File

@@ -25,16 +25,17 @@ export fn init(b: *buf, s: streamp, data: *u8, cap: i32) void = {
b.w = 0;
};
// readbyte — pop one byte. -1 if empty. Hare name (transliterated
// from `read_byte`); the `-1`-for-EOF return is the sanctioned subset
// of Hare's `(u8 | EOF | error)`.
export fn readbyte(b: *buf) i32 = {
// readbyte — pop one byte. void variant signals EOF (empty buffer).
// Hare name; the (i32 | void) shape is a subset of Hare's full
// (u8 | EOF | io::error) — error reporting from the underlying
// stream will arrive when bufio actually wires up to io::stream.
export fn readbyte(b: *buf) (i32 | void) = {
if (b.r < b.w) {
let c: u8 = b.data[b.r];
b.r += 1;
return c: i32;
};
return -1;
return;
};
// Distinct alias so `(str | linerr)` has two variant types the

View File

@@ -2,13 +2,14 @@
// subset (no over-long encodings, no surrogates).
def MAX: rune = 1114111; // 0x10FFFF
def BAD: rune = -1;
export fn runesz(r: rune) i32 = {
if (r < 0) { return -1; };
// runesz — encoded byte length of `r` as UTF-8. void variant means
// `r` is outside the legal range (negative, > 0x10FFFF).
export fn runesz(r: rune) (i32 | void) = {
if (r < 0) { return; };
if (r < 128) { return 1; };
if (r < 2048) { return 2; };
if (r < 65536) { return 3; };
if (r <= MAX) { return 4; };
return -1;
return;
};