lib/strconv: graduate to owned-str returns with Hare-shape base param

i64tos / u64tos / f64tos return a fresh owned str (caller frees via
os.free) instead of writing into a caller-supplied [N]u8. Adds typed
variants (i32tos / i16tos / i8tos and u32 / u16 / u8) and the missing
base parameter on stoi64 / stou64 + typed parse wrappers.

Base values are exported as plain-i32 `def`s (strconv.DEC,
strconv.HEX_UPPER, ...) rather than a `base` enum: cross-module
`strconv.base.DEC` chains miscompile in the cstage cgen — it emits a
memory load through `base(SB)` rather than inlining the constant.
The Sdef path resolves correctly, so callers say `strconv.DEC` and
both cgens lower to an immediate.

Also renames strings.byteindex / rbyteindex to strings.indexbyte /
rindexbyte, matching bytes.indexbyte and reserving the Hare name
`byteindex` for the future `(str | rune)`-needle shape.

fmt drops printint / printlnint / fprintint — those were stand-ins
for variadic `fmt::println(42)`; with the owned-str graduation the
substitute is one call: `fmt.println(strconv.i64tos(42, strconv.DEC))`.

strerror is sketched in a comment but not shipped — match arms over
the wider `error = !(invalid | overflow)` union still expose a
cstage-vs-wwstage spill divergence.
This commit is contained in:
2026-05-13 03:55:16 +09:00
parent 9bc973dc96
commit be8a662f15
14 changed files with 1192 additions and 520 deletions

View File

@@ -1,10 +1,11 @@
// fmt — minimal formatting writers. All output goes through os.write
// to fd 1 (stdout). No printf-family yet — we don't have varargs in
// the language proper — but the typed entry points cover the common
// cases.
// to a file descriptor. No printf-family yet — we don't have varargs
// in the language proper — so callers compose with strconv.i64tos /
// strings.concat to build the message and then call print / println.
// Hare's `fmt::println(42)` becomes `fmt.println(strconv.i64tos(42,
// strconv.DEC))`.
use os;
use strconv;
export fn print(s: str) i64 = {
return os.write(1, s.ptr, s.len: u64);
@@ -18,17 +19,6 @@ export fn println(s: str) i64 = {
return n + m;
};
export fn printint(v: i64) void = {
let buf: [32]u8;
let n: i32 = strconv.i64tos(buf[0:32], v);
os.write(1, buf.ptr, n: u64);
};
export fn printlnint(v: i64) void = {
printint(v);
os.write(1, "\n".ptr, 1u64);
};
// errorln — write a message to stderr with a trailing newline.
export fn errorln(s: str) i64 = {
let n: i64 = os.write(2, s.ptr, s.len: u64);
@@ -51,10 +41,3 @@ export fn fprintln(fd: i32, s: str) i64 = {
if (m < 0) { return m; };
return n + m;
};
export fn fprintint(fd: i32, v: i64) void = {
let buf: [32]u8;
let n: i32 = strconv.i64tos(buf[0:32], v);
os.write(fd, buf.ptr, n: u64);
};