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:
@@ -269,14 +269,12 @@ fn pr(fd: i32, n: *node, d: i32) void = {
|
||||
|
||||
if (n.kind == nkind.N_INTLIT) {
|
||||
putc1(fd, 32u8);
|
||||
let buf: [32]u8;
|
||||
let m: i32 = strconv.u64tos(buf[0:32], n.uval);
|
||||
os.write(fd, buf.ptr, m: u64);
|
||||
let s: str = strconv.u64tos(n.uval, strconv.DEC);
|
||||
os.write(fd, s.ptr, s.len: u64);
|
||||
} else { if (n.kind == nkind.N_RUNELIT) {
|
||||
putc1(fd, 32u8);
|
||||
let buf: [32]u8;
|
||||
let m: i32 = strconv.u64tos(buf[0:32], n.uval);
|
||||
os.write(fd, buf.ptr, m: u64);
|
||||
let s: str = strconv.u64tos(n.uval, strconv.DEC);
|
||||
os.write(fd, s.ptr, s.len: u64);
|
||||
} else { if (
|
||||
n.kind == nkind.N_STRLIT ||
|
||||
n.kind == nkind.N_IDENT ||
|
||||
|
||||
@@ -382,12 +382,11 @@ export fn tokprint(fd: i32, t: *tok) void = {
|
||||
fputsstr(fd, "<none>");
|
||||
};
|
||||
fputcbyte(fd, 58u8); // ':'
|
||||
let buf: [32]u8;
|
||||
let n: i32 = strconv.i64tos(buf[0:32], t.line: i64);
|
||||
os.write(fd, buf.ptr, n: u64);
|
||||
let ls: str = strconv.i64tos(t.line: i64, strconv.DEC);
|
||||
os.write(fd, ls.ptr, ls.len: u64);
|
||||
fputcbyte(fd, 58u8);
|
||||
n = strconv.i64tos(buf[0:32], t.col: i64);
|
||||
os.write(fd, buf.ptr, n: u64);
|
||||
let cs: str = strconv.i64tos(t.col: i64, strconv.DEC);
|
||||
os.write(fd, cs.ptr, cs.len: u64);
|
||||
fputcbyte(fd, 32u8); // ' '
|
||||
fputsstr(fd, tokname(t.kind));
|
||||
|
||||
@@ -402,12 +401,12 @@ export fn tokprint(fd: i32, t: *tok) void = {
|
||||
fputq(fd, ttext.ptr, ttext.len);
|
||||
} else { if (t.kind == tkind.TK_INT) {
|
||||
fputcbyte(fd, 32u8);
|
||||
n = strconv.u64tos(buf[0:32], t.uval);
|
||||
os.write(fd, buf.ptr, n: u64);
|
||||
let us: str = strconv.u64tos(t.uval, strconv.DEC);
|
||||
os.write(fd, us.ptr, us.len: u64);
|
||||
} else { if (t.kind == tkind.TK_RUNE) {
|
||||
fputcbyte(fd, 32u8);
|
||||
n = strconv.u64tos(buf[0:32], t.uval);
|
||||
os.write(fd, buf.ptr, n: u64);
|
||||
let us: str = strconv.u64tos(t.uval, strconv.DEC);
|
||||
os.write(fd, us.ptr, us.len: u64);
|
||||
};};};};};
|
||||
// tkind.TK_FLOAT is intentionally not handled here — %g formatting
|
||||
// won't byte-match across implementations. Diff fixtures must
|
||||
|
||||
Reference in New Issue
Block a user