lib: banner purge + WHY-only comment sweep (rule 8)
Every // ---- section banner dies (132 -> 0): names carry the WHAT. Narration deleted (filename restatements, run-with lines, what-the- next-line-does); every ref/hare cite, task cite, divergence, ABI/ layout contract, and ownership qualifier kept (borrowed-view lines restored where the sweep over-cut). Comment-only proven: all 442 walk-workdir .s and 32 import-probe .s byte-identical before/after; libbyteid 56-roster all-ID.
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
// strings — operations over str ({ptr,len}). Hare port; see
|
||||
// ref/hare/strings/.
|
||||
// Hare port; see ref/hare/strings/.
|
||||
//
|
||||
// Documented divergences from Hare:
|
||||
//
|
||||
@@ -30,8 +29,8 @@ import os;
|
||||
import rt;
|
||||
import types;
|
||||
|
||||
// toutf8 — borrowed []u8 view of `s`. ref/hare/strings/utf8.ha:29.
|
||||
// `cap` equals `len`; the slice does not own a separate allocation.
|
||||
// ref/hare/strings/utf8.ha:29. `cap` equals `len`; the slice does
|
||||
// not own a separate allocation.
|
||||
export fn toutf8(s: str) []u8 = {
|
||||
let r: []u8;
|
||||
r.ptr = s.ptr;
|
||||
@@ -40,8 +39,8 @@ export fn toutf8(s: str) []u8 = {
|
||||
return r;
|
||||
};
|
||||
|
||||
// frombytes — borrowed str view of `in`. Pure reinterpret per
|
||||
// CLAUDE.md rule 9 carve-out; ref/hare/strings/utf8.ha:10.
|
||||
// Pure reinterpret per CLAUDE.md rule 9 carve-out;
|
||||
// ref/hare/strings/utf8.ha:10.
|
||||
export fn frombytes(in: []u8) str = {
|
||||
let r: str;
|
||||
r.ptr = in.ptr;
|
||||
@@ -49,9 +48,8 @@ export fn frombytes(in: []u8) str = {
|
||||
return r;
|
||||
};
|
||||
|
||||
// compare — three-way bytewise codepoint-order comparison. Return is
|
||||
// a sign (neg/zero/pos), not an index, so it tracks Hare's `int`
|
||||
// rather than the str-index i32 (#8). ref/hare/strings/compare.ha:12.
|
||||
// Return is a sign (neg/zero/pos), not an index, so it tracks Hare's
|
||||
// `int` rather than the str-index i32 (#8). ref/hare/strings/compare.ha:12.
|
||||
export fn compare(a: str, b: str) int = {
|
||||
let n: i32 = a.len;
|
||||
if (b.len < n) { n = b.len; };
|
||||
@@ -63,8 +61,8 @@ export fn compare(a: str, b: str) int = {
|
||||
return (a.len: int) - (b.len: int);
|
||||
};
|
||||
|
||||
// dup — allocate a fresh copy of `s`. Caller releases with
|
||||
// `os.free(r.ptr, r.len: u64)`. ref/hare/strings/dup.ha:7.
|
||||
// Caller releases with `os.free(r.ptr, r.len: u64)`.
|
||||
// ref/hare/strings/dup.ha:7.
|
||||
export fn dup(s: str) str = {
|
||||
let r: str;
|
||||
r.ptr = nil;
|
||||
@@ -77,9 +75,7 @@ export fn dup(s: str) str = {
|
||||
return frombytes(buf);
|
||||
};
|
||||
|
||||
// dupall — fresh `[]str` whose elements are independent copies of
|
||||
// `s`'s elements. Caller releases via [[freeall]].
|
||||
// ref/hare/strings/dup.ha:26 (#6).
|
||||
// Caller releases via [[freeall]]. ref/hare/strings/dup.ha:26 (#6).
|
||||
//
|
||||
// Hare gates the per-element dup behind `?` and rolls back via
|
||||
// `defer if (!ok) freeall(newsl)`. ww has no `defer if`; more
|
||||
@@ -113,8 +109,6 @@ export fn dupall(s: []str) ([]str | nomem) = {
|
||||
return newsl;
|
||||
};
|
||||
|
||||
// freeall — release each element + the slice header. The natural
|
||||
// disposer for any `[]str` of dup'd elements (e.g. shlex.split).
|
||||
// ref/hare/strings/dup.ha:38.
|
||||
//
|
||||
// Empty elements (`{nil, 0}` from a zero-length dup) are skipped:
|
||||
@@ -135,8 +129,7 @@ export fn freeall(s: []str) void = {
|
||||
};
|
||||
};
|
||||
|
||||
// concat — fresh allocation containing each element of `strs` in
|
||||
// order. Caller releases with `os.free(r.ptr, r.len: u64)`.
|
||||
// Caller releases with `os.free(r.ptr, r.len: u64)`.
|
||||
// ref/hare/strings/concat.ha:5. Hare's `nomem` return is dropped:
|
||||
// `os.alloc` aborts on OOM.
|
||||
export fn concat(strs: str...) str = {
|
||||
@@ -163,8 +156,7 @@ export fn concat(strs: str...) str = {
|
||||
return frombytes(buf);
|
||||
};
|
||||
|
||||
// join — fresh allocation with `delim` placed between each element of
|
||||
// `strs`. Caller releases with `os.free(r.ptr, r.len: u64)`.
|
||||
// Caller releases with `os.free(r.ptr, r.len: u64)`.
|
||||
// ref/hare/strings/concat.ha:46. Hare's `nomem` return is dropped:
|
||||
// `os.alloc` aborts on OOM.
|
||||
export fn join(delim: str, strs: str...) str = {
|
||||
@@ -203,9 +195,8 @@ export fn join(delim: str, strs: str...) str = {
|
||||
return frombytes(buf);
|
||||
};
|
||||
|
||||
// utf8bytelenbounded — walk `it` forward `end` runes and return the
|
||||
// resulting byte offset. ref/hare/strings/sub.ha:10. Aborts on
|
||||
// short input per Hare's contract for the rune-wise [[sub]].
|
||||
// ref/hare/strings/sub.ha:10. Aborts on short input per Hare's
|
||||
// contract for the rune-wise [[sub]].
|
||||
fn utf8bytelenbounded(it: *iterator, end: i32) i32 = {
|
||||
let i: i32 = 0;
|
||||
for (i < end) {
|
||||
@@ -218,10 +209,11 @@ fn utf8bytelenbounded(it: *iterator, end: i32) i32 = {
|
||||
return it.offs;
|
||||
};
|
||||
|
||||
// sub — borrowed substring [start, end) where start/end are rune
|
||||
// indices. ref/hare/strings/sub.ha:30. Hare's 2-arg `sub(s, start)`
|
||||
// Borrowed substring; start/end are rune indices; byte-indexed
|
||||
// counterpart [[bytesub]].
|
||||
// ref/hare/strings/sub.ha:30. Hare's 2-arg `sub(s, start)`
|
||||
// defaulting end=END is omitted: ww has no default-parameter syntax
|
||||
// (filed as #37). Byte-indexed counterpart: [[bytesub]].
|
||||
// (filed as #37).
|
||||
export fn sub(s: str, start: i32, end: i32) str = {
|
||||
assert(start <= end, "strings.sub: start is higher than end");
|
||||
let it: iterator = iter(s);
|
||||
@@ -233,8 +225,9 @@ export fn sub(s: str, start: i32, end: i32) str = {
|
||||
return r;
|
||||
};
|
||||
|
||||
// bytesub — borrowed substring [start, end) where start/end are byte
|
||||
// offsets. ref/hare/strings/sub.ha:59 (#7). Returns `utf8.invalid` if
|
||||
// Borrowed substring; start/end are byte offsets, unlike the
|
||||
// rune-wise [[sub]].
|
||||
// ref/hare/strings/sub.ha:59 (#7). Returns `utf8.invalid` if
|
||||
// either endpoint lands on a continuation byte (would split a
|
||||
// codepoint); the equivalent Hare predicate is `s[i] & 0xc0 == 0x80`
|
||||
// at ref/hare/strings/sub.ha:72-73.
|
||||
@@ -253,9 +246,8 @@ export fn bytesub(s: str, start: i32, end: i32) (str | utf8.invalid) = {
|
||||
return r;
|
||||
};
|
||||
|
||||
// runebytes — encode `r` into caller's `scratch` (must hold 4 bytes)
|
||||
// and return the borrowed slice trimmed to the encoded length. Hare
|
||||
// inlines the same shape at ref/hare/strings/index.ha:132.
|
||||
// `scratch` must hold 4 bytes; the return borrows it. Hare inlines
|
||||
// the same shape at ref/hare/strings/index.ha:132.
|
||||
fn runebytes(scratch: []u8, r: rune) []u8 = {
|
||||
let n: i32 = utf8.encoderune(scratch, r);
|
||||
let s: []u8;
|
||||
@@ -265,7 +257,6 @@ fn runebytes(scratch: []u8, r: rune) []u8 = {
|
||||
return s;
|
||||
};
|
||||
|
||||
// hasprefix — true iff `in` begins with `prefix`.
|
||||
// ref/hare/strings/suffix.ha:8.
|
||||
export fn hasprefix(in: str, prefix: (str | rune)) bool = {
|
||||
let scratch: [4]u8;
|
||||
@@ -276,7 +267,6 @@ export fn hasprefix(in: str, prefix: (str | rune)) bool = {
|
||||
return bytes.hasprefix(toutf8(in), p);
|
||||
};
|
||||
|
||||
// hassuffix — true iff `in` ends with `suff`.
|
||||
// ref/hare/strings/suffix.ha:26.
|
||||
export fn hassuffix(in: str, suff: (str | rune)) bool = {
|
||||
let scratch: [4]u8;
|
||||
@@ -287,8 +277,7 @@ export fn hassuffix(in: str, suff: (str | rune)) bool = {
|
||||
return bytes.hassuffix(toutf8(in), s);
|
||||
};
|
||||
|
||||
// byteindex — byte-wise offset of `needle` in `haystack`, or void if
|
||||
// absent. ref/hare/strings/index.ha:127. Rune arm encodes via
|
||||
// ref/hare/strings/index.ha:127. Rune arm encodes via
|
||||
// utf8.encoderune (Hare passes the encoded slice straight to
|
||||
// bytes::index).
|
||||
export fn byteindex(haystack: str, needle: (str | rune)) (i32 | void) = {
|
||||
@@ -300,7 +289,6 @@ export fn byteindex(haystack: str, needle: (str | rune)) (i32 | void) = {
|
||||
return bytes.index(toutf8(haystack), n);
|
||||
};
|
||||
|
||||
// rbyteindex — byte-wise offset of the last `needle` in `haystack`.
|
||||
// ref/hare/strings/index.ha:138.
|
||||
export fn rbyteindex(haystack: str, needle: (str | rune)) (i32 | void) = {
|
||||
let scratch: [4]u8;
|
||||
@@ -311,15 +299,12 @@ export fn rbyteindex(haystack: str, needle: (str | rune)) (i32 | void) = {
|
||||
return bytes.rindex(toutf8(haystack), n);
|
||||
};
|
||||
|
||||
// indexstring — str-arm of [[index]]. Dual-rune-iterator walk: at each
|
||||
// candidate rune index `i`, compare `haystack` from that position
|
||||
// against `needle` rune-by-rune until needle is exhausted (match) or
|
||||
// a mismatch / haystack-exhaustion breaks the inner loop. Mirrors
|
||||
// ref/hare/strings/index.ha:59 (#10). Hare copies `rest_iter = s_iter`
|
||||
// directly via struct assignment; ww re-seats `rest_iter` field-wise
|
||||
// because the let-init struct-copy form diverges between cstage and
|
||||
// wwstage on this iterator type (993_ww_ww + 995_self_rebuild fail,
|
||||
// filed as #41) and rule #10 (CLAUDE.md) forbids stage asymmetry.
|
||||
// Mirrors ref/hare/strings/index.ha:59 (#10). Hare copies
|
||||
// `rest_iter = s_iter` directly via struct assignment; ww re-seats
|
||||
// `rest_iter` field-wise because the let-init struct-copy form
|
||||
// diverges between cstage and wwstage on this iterator type
|
||||
// (993_ww_ww + 995_self_rebuild fail, filed as #41) and rule #10
|
||||
// (CLAUDE.md) forbids stage asymmetry.
|
||||
fn indexstring(haystack: str, needle: str) (i32 | void) = {
|
||||
let s_iter: iterator = iter(haystack);
|
||||
let i: i32 = 0;
|
||||
@@ -356,11 +341,10 @@ fn indexstring(haystack: str, needle: str) (i32 | void) = {
|
||||
return;
|
||||
};
|
||||
|
||||
// index — rune-wise offset of `needle`'s first occurrence in
|
||||
// `haystack`, or void if absent. ref/hare/strings/index.ha:10. The
|
||||
// str-arm delegates to [[indexstring]] (dual-iterator rune-by-rune
|
||||
// walk per Hare's `index_string`, #10); the rune-arm mirrors Hare's
|
||||
// `index_rune` (ref/hare/strings/index.ha:31).
|
||||
// Rune-wise offset, not byte-wise ([[byteindex]]).
|
||||
// ref/hare/strings/index.ha:10. The str-arm delegates to
|
||||
// [[indexstring]] (per Hare's `index_string`, #10); the rune-arm
|
||||
// mirrors Hare's `index_rune` (ref/hare/strings/index.ha:31).
|
||||
export fn index(haystack: str, needle: (str | rune)) (i32 | void) = {
|
||||
match (needle) {
|
||||
case let s: str => return indexstring(haystack, s);
|
||||
@@ -381,8 +365,7 @@ export fn index(haystack: str, needle: (str | rune)) (i32 | void) = {
|
||||
return;
|
||||
};
|
||||
|
||||
// rindex — rune-wise offset of `needle`'s last occurrence in
|
||||
// `haystack`, or void if absent. ref/hare/strings/index.ha:22. The
|
||||
// Rune-wise offset. ref/hare/strings/index.ha:22. The
|
||||
// str-arm reuses `rbyteindex`; the rune-arm walks forward tracking
|
||||
// the most recent matching rune index (Hare's `rindex_rune` with
|
||||
// `riter` returns a byte-offset value for multibyte strings, which
|
||||
@@ -426,7 +409,6 @@ export fn rindex(haystack: str, needle: (str | rune)) (i32 | void) = {
|
||||
return;
|
||||
};
|
||||
|
||||
// contains — true iff any of `needles` occurs in `haystack`.
|
||||
// ref/hare/strings/contains.ha:9.
|
||||
export fn contains(haystack: str, needles: (str | rune)...) bool = {
|
||||
let i: i32 = 0;
|
||||
@@ -450,9 +432,7 @@ export fn contains(haystack: str, needles: (str | rune)...) bool = {
|
||||
return false;
|
||||
};
|
||||
|
||||
// trimprefix — `s` with `prefix` stripped from the front, or `s`
|
||||
// unchanged if it doesn't start with `prefix`. Borrowed view.
|
||||
// ref/hare/strings/trim.ha:60.
|
||||
// ref/hare/strings/trim.ha:60. Borrowed view.
|
||||
export fn trimprefix(input: str, prefix: str) str = {
|
||||
if (!hasprefix(input, prefix)) { return input; };
|
||||
let r: str;
|
||||
@@ -461,7 +441,7 @@ export fn trimprefix(input: str, prefix: str) str = {
|
||||
return r;
|
||||
};
|
||||
|
||||
// trimsuffix — symmetric. ref/hare/strings/trim.ha:69.
|
||||
// ref/hare/strings/trim.ha:69.
|
||||
export fn trimsuffix(input: str, suffix: str) str = {
|
||||
if (!hassuffix(input, suffix)) { return input; };
|
||||
let r: str;
|
||||
@@ -470,12 +450,11 @@ export fn trimsuffix(input: str, suffix: str) str = {
|
||||
return r;
|
||||
};
|
||||
|
||||
// whitespace — ASCII whitespace set used by the 0-arg ltrim/rtrim/trim
|
||||
// branches (#9). ref/hare/strings/trim.ha:6.
|
||||
// ASCII set for the 0-arg ltrim/rtrim/trim branches (#9).
|
||||
// ref/hare/strings/trim.ha:6.
|
||||
let whitespace: [4]u8 = [0x20u8, 0x0Au8, 0x09u8, 0x0Du8];
|
||||
|
||||
// ltrim — strip leading runes that occur in `trim`. Borrowed view.
|
||||
// 0-arg strips ASCII whitespace via [[bytes.ltrim]] (#9).
|
||||
// Borrowed view. 0-arg strips ASCII whitespace via [[bytes.ltrim]] (#9).
|
||||
// ref/hare/strings/trim.ha:11. The spread expression is inlined
|
||||
// because `let ws: []u8 = whitespace[0:4]` produces a slice whose
|
||||
// ptr doesn't track the module-level array storage (filed as #40);
|
||||
@@ -509,9 +488,8 @@ export fn ltrim(input: str, trim: rune...) str = {
|
||||
return iterstr(&it);
|
||||
};
|
||||
|
||||
// rtrim — strip trailing runes that occur in `trim`. Borrowed view.
|
||||
// 0-arg strips ASCII whitespace via [[bytes.rtrim]] (#9). Spread is
|
||||
// inlined to dodge #40 — see [[ltrim]].
|
||||
// Borrowed view; inlined to dodge #40 — see [[ltrim]].
|
||||
// ref/hare/strings/trim.ha:32.
|
||||
export fn rtrim(input: str, trim: rune...) str = {
|
||||
if (trim.len == 0) {
|
||||
@@ -541,23 +519,22 @@ export fn rtrim(input: str, trim: rune...) str = {
|
||||
return iterstr(&it);
|
||||
};
|
||||
|
||||
// trim — strip from both ends. ref/hare/strings/trim.ha:54.
|
||||
// ref/hare/strings/trim.ha:54.
|
||||
export fn trim(input: str, trim: rune...) str = {
|
||||
return ltrim(rtrim(input, trim...), trim...);
|
||||
};
|
||||
|
||||
// iterator — UTF-8 rune cursor over a `str`. Layout flattens Hare's
|
||||
// anonymous-embedded `utf8::decoder` (ref/hare/strings/iter.ha:6-9) to
|
||||
// explicit fields. `reverse` selects walk direction: forward iterators
|
||||
// (`iter`) advance through utf8.next; reverse iterators (`riter`) advance
|
||||
// through utf8.prev. May be copied to save state.
|
||||
// Layout flattens Hare's anonymous-embedded `utf8::decoder`
|
||||
// (ref/hare/strings/iter.ha:6-9) to explicit fields. `reverse` selects
|
||||
// walk direction: forward iterators (`iter`) advance through utf8.next;
|
||||
// reverse iterators (`riter`) advance through utf8.prev. May be copied
|
||||
// to save state.
|
||||
export type iterator = struct {
|
||||
offs: i32,
|
||||
src: []u8,
|
||||
reverse: bool,
|
||||
};
|
||||
|
||||
// iter — initialize a forward iterator at the start of `src`.
|
||||
// ref/hare/strings/iter.ha:24.
|
||||
export fn iter(src: str) iterator = {
|
||||
let r: iterator;
|
||||
@@ -567,8 +544,6 @@ export fn iter(src: str) iterator = {
|
||||
return r;
|
||||
};
|
||||
|
||||
// riter — initialize a reverse iterator at the end of `src`. `next`
|
||||
// on a reverse iterator walks back through the string.
|
||||
// ref/hare/strings/iter.ha:32.
|
||||
export fn riter(src: str) iterator = {
|
||||
let r: iterator;
|
||||
@@ -578,8 +553,7 @@ export fn riter(src: str) iterator = {
|
||||
return r;
|
||||
};
|
||||
|
||||
// move — private dispatch shared by next/prev. `forward` selects
|
||||
// utf8.next vs utf8.prev. Aborts on more/invalid per Hare's
|
||||
// Aborts on more/invalid per Hare's
|
||||
// ref/hare/strings/iter.ha:51-58 ("Invalid UTF-8 string (this should
|
||||
// not happen)"). Hare picks the utf8 function via a fn-pointer; ww
|
||||
// branches on `forward` at each call site instead.
|
||||
@@ -607,22 +581,17 @@ fn move(forward: bool, it: *iterator) (rune | utf8.done) = {
|
||||
};
|
||||
};
|
||||
|
||||
// next — advance the iterator one rune. Forward iterators step
|
||||
// through utf8.next; reverse iterators (riter) step backward through
|
||||
// utf8.prev. Returns utf8.done at end-of-walk. ref/hare/strings/iter.ha:45.
|
||||
// ref/hare/strings/iter.ha:45.
|
||||
export fn next(it: *iterator) (rune | utf8.done) = {
|
||||
return move(!it.reverse, it);
|
||||
};
|
||||
|
||||
// prev — step back one rune. Dual to next: on a forward iterator
|
||||
// this walks utf8.prev; on a reverse iterator (riter) it walks
|
||||
// utf8.next. ref/hare/strings/iter.ha:49.
|
||||
// ref/hare/strings/iter.ha:49.
|
||||
export fn prev(it: *iterator) (rune | utf8.done) = {
|
||||
return move(it.reverse, it);
|
||||
};
|
||||
|
||||
// iterstr — borrowed view of the bytes remaining in the iterator's
|
||||
// walk direction. Forward iter: bytes from offs to end; reverse iter:
|
||||
// Borrowed view. Forward iter: bytes from offs to end; reverse iter:
|
||||
// bytes from start to offs. ref/hare/strings/iter.ha:63.
|
||||
export fn iterstr(it: *iterator) str = {
|
||||
let r: []u8;
|
||||
@@ -634,7 +603,6 @@ export fn iterstr(it: *iterator) str = {
|
||||
return frombytes(r);
|
||||
};
|
||||
|
||||
// slice — borrowed substring between two iterator positions.
|
||||
// ref/hare/strings/iter.ha:75. Hare passes `*iterator` directly where
|
||||
// `*utf8::decoder` is expected via anonymous-embed coercion; ww has
|
||||
// no anonymous embed, so we reconstruct a local utf8.decoder for each
|
||||
@@ -649,22 +617,19 @@ export fn slice(begin: *iterator, end: *iterator) str = {
|
||||
return frombytes(utf8.slice(&b, &e));
|
||||
};
|
||||
|
||||
// position — byte-wise offset of the iterator in its source.
|
||||
// ref/hare/strings/iter.ha:82.
|
||||
export fn position(it: *iterator) i32 = {
|
||||
return it.offs;
|
||||
};
|
||||
|
||||
// tokenizer — re-export of bytes.tokenizer. ref/hare/strings/tokenize.ha:7.
|
||||
// ref/hare/strings/tokenize.ha:7.
|
||||
// First cross-module type alias in tree; needs #22's transitive
|
||||
// alias-chain unwrap (cstage type_chase_named + wwstage
|
||||
// structlookupchain) to walk struct fields through the chain.
|
||||
export type tokenizer = bytes.tokenizer;
|
||||
|
||||
// tokenize — yield substrings of `s` split on any byte in `delim`.
|
||||
// Leading / trailing / adjacent delims yield empty tokens. `s` and
|
||||
// `delim` are borrowed; caller keeps them live for the tokenizer's
|
||||
// lifetime. ref/hare/strings/tokenize.ha:32. ASCII-only delim
|
||||
// `s` and `delim` are borrowed; caller keeps them live for the
|
||||
// tokenizer's lifetime. ref/hare/strings/tokenize.ha:32. ASCII-only delim
|
||||
// asserted per Hare lines 35-37: a multibyte rune in delim would
|
||||
// split on a single continuation byte and yield invalid UTF-8.
|
||||
export fn tokenize(s: str, delim: str) tokenizer = {
|
||||
@@ -678,8 +643,6 @@ export fn tokenize(s: str, delim: str) tokenizer = {
|
||||
return bytes.tokenize(toutf8(s), d...);
|
||||
};
|
||||
|
||||
// rtokenize — reverse-direction counterpart to [[tokenize]]. First
|
||||
// nexttoken yields the last token, last yields the first.
|
||||
// ref/hare/strings/tokenize.ha:44.
|
||||
export fn rtokenize(s: str, delim: str) tokenizer = {
|
||||
let d: []u8 = toutf8(delim);
|
||||
@@ -692,7 +655,6 @@ export fn rtokenize(s: str, delim: str) tokenizer = {
|
||||
return bytes.rtokenize(toutf8(s), d...);
|
||||
};
|
||||
|
||||
// nexttoken — current token, advancing the cursor.
|
||||
// ref/hare/strings/tokenize.ha:62.
|
||||
export fn nexttoken(s: *tokenizer) (str | bytes.done) = {
|
||||
let b: *bytes.tokenizer = s: *bytes.tokenizer;
|
||||
@@ -702,7 +664,6 @@ export fn nexttoken(s: *tokenizer) (str | bytes.done) = {
|
||||
};
|
||||
};
|
||||
|
||||
// peektoken — current token without advancing.
|
||||
// ref/hare/strings/tokenize.ha:71.
|
||||
export fn peektoken(s: *tokenizer) (str | bytes.done) = {
|
||||
let b: *bytes.tokenizer = s: *bytes.tokenizer;
|
||||
@@ -712,34 +673,29 @@ export fn peektoken(s: *tokenizer) (str | bytes.done) = {
|
||||
};
|
||||
};
|
||||
|
||||
// remainingtokens — unconsumed portion of the input ahead of the
|
||||
// cursor. ref/hare/strings/tokenize.ha:79.
|
||||
// ref/hare/strings/tokenize.ha:79.
|
||||
export fn remainingtokens(s: *tokenizer) str = {
|
||||
let b: *bytes.tokenizer = s: *bytes.tokenizer;
|
||||
return frombytes(bytes.remainingtokens(b));
|
||||
};
|
||||
|
||||
// cut — split `in` along the first instance of `delim`, returning the
|
||||
// portions before and after it. When `delim` is absent the whole input
|
||||
// is the first half and the second is empty. Both halves are borrowed
|
||||
// from `in`; caller ensures `delim` is non-empty.
|
||||
// ref/hare/strings/tokenize.ha:288.
|
||||
// When `delim` is absent the whole input is the first half and the
|
||||
// second is empty. Both halves are borrowed from `in`; caller
|
||||
// ensures `delim` is non-empty. ref/hare/strings/tokenize.ha:288.
|
||||
export fn cut(in: str, delim: str) (str, str) = {
|
||||
let (a, b) = bytes.cut(toutf8(in), toutf8(delim));
|
||||
return (frombytes(a), frombytes(b));
|
||||
};
|
||||
|
||||
// rcut — like [[cut]] but split along the LAST instance of `delim`.
|
||||
// ref/hare/strings/tokenize.ha:302.
|
||||
export fn rcut(in: str, delim: str) (str, str) = {
|
||||
let (a, b) = bytes.rcut(toutf8(in), toutf8(delim));
|
||||
return (frombytes(a), frombytes(b));
|
||||
};
|
||||
|
||||
// splitn — split `in` on any byte in `delim`, returning up to `n`
|
||||
// tokens via forward iteration. The trailing slot (when more than
|
||||
// `n - 1` tokens exist) holds the unconsumed remainder. Strings
|
||||
// within the result are borrowed from `in`.
|
||||
// The trailing slot (when more than `n - 1` tokens exist) holds the
|
||||
// unconsumed remainder. Strings within the result are borrowed
|
||||
// from `in`.
|
||||
//
|
||||
// The caller frees the returned slice via
|
||||
// `os.free(r.ptr: *void, (r.cap: u64) * size(str): u64)`.
|
||||
@@ -773,9 +729,8 @@ export fn splitn(in: str, delim: str, n: i32) []str = {
|
||||
return toks;
|
||||
};
|
||||
|
||||
// rsplitn — reverse-direction counterpart to [[splitn]]: tokens are
|
||||
// collected from the end of `in`. The trailing slot holds the
|
||||
// unconsumed prefix (everything before the n-th-from-last delim hit).
|
||||
// The trailing slot holds the unconsumed prefix (everything before
|
||||
// the n-th-from-last delim hit).
|
||||
//
|
||||
// When the input has fewer than n tokens, the `done` short-circuit
|
||||
// returns toks UN-reversed (in last-token-first order). Mirrors Hare
|
||||
@@ -826,8 +781,7 @@ export fn rsplitn(in: str, delim: str, n: i32) []str = {
|
||||
return toks;
|
||||
};
|
||||
|
||||
// split — full split of `in` on `delim` (no token cap). Mirrors
|
||||
// `splitn(in, delim, types::SIZE_MAX)`. ww uses `types.I32_MAX`
|
||||
// Mirrors `splitn(in, delim, types::SIZE_MAX)`. ww uses `types.I32_MAX`
|
||||
// because the index type is i32 (lib/CLAUDE.md).
|
||||
//
|
||||
// ref/hare/strings/tokenize.ha:242.
|
||||
@@ -835,8 +789,7 @@ export fn split(in: str, delim: str) []str = {
|
||||
return splitn(in, delim, types.I32_MAX);
|
||||
};
|
||||
|
||||
// lpad — left-pad `s` with `p` rune until the result reaches `maxlen`
|
||||
// bytes. Length comparison is BYTES, mirroring Hare's `len(s) >= maxlen`
|
||||
// Length comparison is BYTES, mirroring Hare's `len(s) >= maxlen`
|
||||
// at ref/hare/strings/pad.ha:9. A multibyte `p` whose encoded width
|
||||
// doesn't divide `maxlen - s.len` evenly leaves a trailing pad byte
|
||||
// pair sliced mid-codepoint at byte `maxlen-1`, exactly as Hare's
|
||||
@@ -872,9 +825,9 @@ export fn lpad(s: str, p: rune, maxlen: i32) str = {
|
||||
return frombytes(buf);
|
||||
};
|
||||
|
||||
// replace — fresh allocation of `s` with every non-overlapping
|
||||
// occurrence of `needle` replaced by `target`. Caller releases with
|
||||
// `os.free(r.ptr, r.len: u64)`. ref/hare/strings/replace.ha:8 (#4).
|
||||
// Replaces every non-overlapping occurrence of `needle`. Caller
|
||||
// releases with `os.free(r.ptr, r.len: u64)`.
|
||||
// ref/hare/strings/replace.ha:8 (#4).
|
||||
//
|
||||
// Hare delegates to [[multireplace]] with a single pair; ww has no
|
||||
// `(str, str)` variadic shape today (#39), so this is a standalone
|
||||
@@ -928,8 +881,7 @@ export fn replace(s: str, needle: str, target: str) (str | nomem) = {
|
||||
return frombytes(res);
|
||||
};
|
||||
|
||||
// rpad — right-pad `s` with `p` rune until the result reaches `maxlen`
|
||||
// bytes. Symmetric with [[lpad]]. ref/hare/strings/pad.ha:39.
|
||||
// Symmetric with [[lpad]]. ref/hare/strings/pad.ha:39.
|
||||
export fn rpad(s: str, p: rune, maxlen: i32) str = {
|
||||
if (s.len >= maxlen) { return dup(s); };
|
||||
let scratch: [4]u8;
|
||||
|
||||
Reference in New Issue
Block a user