// bytes — slice operations over []u8. export fn equal(a: []u8, b: []u8) bool = { let i: i32 = 0; for (i < a.len) { if (i >= b.len) { return false; }; if (a[i] != b[i]) { return false; }; i += 1; }; return i == b.len; }; // indexbyte — first index of byte `c` in `s`. Hare-shaped optional: // (i32 | void). void variant indicates "not found". export fn indexbyte(s: []u8, c: u8) (i32 | void) = { let i: i32 = 0; for (i < s.len) { if (s[i] == c) { return i; }; i += 1; }; return; }; export fn copy(dst: []u8, src: []u8) i32 = { let n: i32 = dst.len; if (src.len < n) { n = src.len; }; let i: i32 = 0; for (i < n) { dst[i] = src[i]; i += 1; }; return n; }; // index — first index of `sub` in `s`. Mirrors Hare's bytes::index // (the []u8 needle variant; the u8 needle stays as indexbyte until we // have union-arg dispatch). Empty `sub` matches at 0. export fn index(s: []u8, sub: []u8) (i32 | void) = { if (sub.len == 0) { return 0; }; if (sub.len > s.len) { return; }; let last: i32 = s.len - sub.len; let i: i32 = 0; for (i <= last) { let j: i32 = 0; let ok: bool = true; for (j < sub.len) { if (s[i + j] != sub[j]) { ok = false; j = sub.len; } else { j += 1; }; }; if (ok) { return i; }; i += 1; }; return; };