ascii: valid, validstr, ispunct, isprint, iscntrl, isgraph, isblank, strcasecmp. bytes: hasprefix, hassuffix, rindex, rindexbyte, contains, reverse, zero. strings: rindex, sub, trimprefix, trimsuffix, ltrimbyte, rtrimbyte, trimbyte. The byte-set trim is a single-byte subset of Hare's `trim(input, exclude: rune...)`; no variadic ABI yet. path: dirname, basename, extension, join. Owned-str returns where the result isn't a borrowed view of the input (join). endian: full Hare table — be/le get/put for u16/u32/u64 plus the network-order htonu/ntohu pair extended to 32/64. lib/CLAUDE.md rewritten to reflect the post-graduation policy (tagged-union returns, owned-str returns, plan9 names, documented deviations for non-graduating modules). Makefile picks up lib/ascii and lib/fmt as wwdump_ww / w6c_ww deps so lib-only edits regenerate the affected binaries.
3.0 KiB
lib/ — Hare-shaped standard library.
Scope: every lib/* directory except lib/ww/, which is the compiler
frontend port and has its own rules (see lib/ww/CLAUDE.md).
Names mirror Hare. Before adding a function, find its counterpart in
ref/hare/<module>/ and copy the name — drop Hare's underscores per
plan 9 style (trim_prefix → trimprefix, next_token → nexttoken).
Don't invent. Don't shorten further. Don't reorder parameters.
Signatures mirror Hare too, modulo:
-
Tagged-union returns are spelled with the ww
!error tag where Hare uses!void/!T, and indices use the underlying length type (i32today, sincestr.len: i32). Example:strconv.stoi64(s: str, b: i32) (i64 | invalid | overflow)— same shape as Hare's; the base parameter is plaini32rather than abaseenum because cross-modulemod.enumtype.VALUEchains miscompile in the cstage cgen.strconvexportsdef DEC: i32 = 10;etc. so callers saystrconv.DECand the Sdef path lowers to an immediate. -
Owned-
strreturns. Where Hare returnsconst strinto a thread-local static buffer (strconv.i64tos,strings.dup,strings.concat), ww allocates per call and the caller frees viaos.free(r.ptr, r.len: u64). Mutating a module-level*u8doesn't yet round-trip through the wwstage cgen, so the static- buffer shape isn't expressible today. -
Variadic ABI doesn't land yet, so callers that Hare writes as
fmt::println(42)are spelledfmt.println(strconv.i64tos(42, strconv.DEC))for now.lib/fmtis intentionally print-string- only — noprintf-family. -
(str | rune)-style sum-typed parameters are split into typed pairs (strings.indexbytefor the byte case,strings.indexfor the slice case, etc.). The Hare public namebyteindexwill come back once the sum-typed parameter ABI lands.
Don't ship a richer surface than Hare has. A documented subset is fine; an extension, rename, or convenience-wrapper is not — callers should not bake the current subset shape into themselves.
Modules with intentional divergence:
lib/osandlib/netstay below the Hare abstraction — they are syscall wrappers, not the high-levelio::handle/net::socketAPI. Use them as the foundation thatlib/ioand the buffered layers build on.lib/iokeeps the ww-specificstreamstruct (vtable of fn pointers, no closures, no methods). The Hareio::handlefamily needs language features we don't have yet.lib/bufioandlib/sortwill be redesigned to Hare'sscanner/cmpfuncshapes; the present minimal forms are placeholders until then.lib/timeandlib/mathship only what callers need today; they're not aiming for parity yet.
When the compiler can express a Hare signature that's still in the
ww-specific shape (e.g., once a module-level *u8 is mutable, the
strconv *tos family graduates to static-buffer returns), graduate
the module in one go — replace the current shape with the Hare shape
and fix the callers. Don't keep both around.