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:
@@ -472,15 +472,13 @@ fn localfind(c: *cgen, name: str) i32 = {
|
||||
fn emitline(s: str) void = { os.write(1, s.ptr, s.len: u64); };
|
||||
|
||||
fn emitint(v: i64) void = {
|
||||
let buf: [32]u8;
|
||||
let n: i32 = strconv.i64tos(buf[0:32], v);
|
||||
os.write(1, buf.ptr, n: u64);
|
||||
let s: str = strconv.i64tos(v, strconv.DEC);
|
||||
os.write(1, s.ptr, s.len: u64);
|
||||
};
|
||||
|
||||
fn emituint(v: u64) void = {
|
||||
let buf: [32]u8;
|
||||
let n: i32 = strconv.u64tos(buf[0:32], v);
|
||||
os.write(1, buf.ptr, n: u64);
|
||||
let s: str = strconv.u64tos(v, strconv.DEC);
|
||||
os.write(1, s.ptr, s.len: u64);
|
||||
};
|
||||
|
||||
// emitdispreg — print "disp(reg)" or "(reg)" when disp == 0, the
|
||||
@@ -499,9 +497,9 @@ fn emitoff(v: i64) void = {
|
||||
if (v != 0i64) { emitint(v); };
|
||||
};
|
||||
|
||||
// mklabel — fresh label "<fnname>_<base>_<seq>". Returns an
|
||||
// mklabel — fresh label "<fnname>_<prefix>_<seq>". Returns an
|
||||
// arena-owned str. Mirrors C cgen's mklabel so diffs match.
|
||||
fn mklabel(c: *cgen, base: str) str = {
|
||||
fn mklabel(c: *cgen, prefix: str) str = {
|
||||
let buf: [128]u8;
|
||||
let i: i32 = 0;
|
||||
let fname: str = c.fnname;
|
||||
@@ -512,12 +510,15 @@ fn mklabel(c: *cgen, base: str) str = {
|
||||
};
|
||||
buf[i] = 95u8; i += 1; // '_'
|
||||
j = 0;
|
||||
for (j < base.len) {
|
||||
buf[i] = base[j];
|
||||
for (j < prefix.len) {
|
||||
buf[i] = prefix[j];
|
||||
i += 1; j += 1;
|
||||
};
|
||||
buf[i] = 95u8; i += 1; // '_'
|
||||
let n: i32 = strconv.i64tos(buf[i:128], c.labelseq: i64);
|
||||
let ns: str = strconv.i64tos(c.labelseq: i64, strconv.DEC);
|
||||
let n: i32 = ns.len;
|
||||
let dk: i32 = 0;
|
||||
for (dk < n) { buf[i + dk] = ns.ptr[dk]; dk += 1; };
|
||||
c.labelseq += 1;
|
||||
let total: i32 = i + n;
|
||||
let p: *u8 = amalloc(c.a, (total: u64) + 1u64): *u8;
|
||||
@@ -538,22 +539,25 @@ fn emitlabel(s: str) void = {
|
||||
emitline(":\n");
|
||||
};
|
||||
|
||||
// mkscratchname — fresh local-slot name ".<base>_<labelseq>". Used for
|
||||
// mkscratchname — fresh local-slot name ".<prefix>_<labelseq>". Used for
|
||||
// compiler-synthesised slots (switch scrutinee, forrange index/len)
|
||||
// that need to be unique per use site but are never referenced by user
|
||||
// code. Increments labelseq so the same source position lines up with
|
||||
// C cgen's labelseq stream.
|
||||
fn mkscratchname(c: *cgen, base: str) str = {
|
||||
fn mkscratchname(c: *cgen, prefix: str) str = {
|
||||
let buf: [128]u8;
|
||||
let i: i32 = 0;
|
||||
buf[i] = 46u8; i += 1; // '.'
|
||||
let j: i32 = 0;
|
||||
for (j < base.len) {
|
||||
buf[i] = base[j];
|
||||
for (j < prefix.len) {
|
||||
buf[i] = prefix[j];
|
||||
i += 1; j += 1;
|
||||
};
|
||||
buf[i] = 95u8; i += 1; // '_'
|
||||
let n: i32 = strconv.i64tos(buf[i:128], c.labelseq: i64);
|
||||
let ns: str = strconv.i64tos(c.labelseq: i64, strconv.DEC);
|
||||
let n: i32 = ns.len;
|
||||
let dk: i32 = 0;
|
||||
for (dk < n) { buf[i + dk] = ns.ptr[dk]; dk += 1; };
|
||||
c.labelseq += 1;
|
||||
let total: i32 = i + n;
|
||||
let p: *u8 = amalloc(c.a, (total: u64) + 1u64): *u8;
|
||||
@@ -587,7 +591,10 @@ fn internstrlit(c: *cgen, bytes: str) str = {
|
||||
// New label "_S_<seq>".
|
||||
let buf: [32]u8;
|
||||
buf[0] = 95u8; buf[1] = 83u8; buf[2] = 95u8; // "_S_"
|
||||
let n: i32 = strconv.i64tos(buf[3:32], c.strlitseq: i64);
|
||||
let ns: str = strconv.i64tos(c.strlitseq: i64, strconv.DEC);
|
||||
let n: i32 = ns.len;
|
||||
let dk: i32 = 0;
|
||||
for (dk < n) { buf[3 + dk] = ns.ptr[dk]; dk += 1; };
|
||||
c.strlitseq += 1;
|
||||
let total: i32 = 3 + n;
|
||||
let p: *u8 = amalloc(c.a, (total: u64) + 1u64): *u8;
|
||||
|
||||
Reference in New Issue
Block a user