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:
@@ -139,17 +139,15 @@ static const struct row rows[] = {
|
||||
" for (i < 3) { s += buf[i]: i32; i += 1; };\n"
|
||||
" return s;\n"
|
||||
"};", 198 },
|
||||
/* full stdlib stack: use os + strconv, slice-arg call, write
|
||||
/* full stdlib stack: use os + strconv, str return, write
|
||||
* the formatted number to stdout. exit code = number length. */
|
||||
{ "use os;\n"
|
||||
"use strconv;\n"
|
||||
"fn main() i32 = {\n"
|
||||
" let buf: [32]u8;\n"
|
||||
" let s: []u8 = buf[0:32];\n"
|
||||
" let n: i32 = strconv.i64tos(s, 12345);\n"
|
||||
" os.write(1, buf.ptr, n: u64);\n"
|
||||
" let s: str = strconv.i64tos(12345, strconv.DEC);\n"
|
||||
" os.write(1, s.ptr, s.len: u64);\n"
|
||||
" os.write(1, \"\\n\".ptr, 1u64);\n"
|
||||
" return n;\n"
|
||||
" return s.len;\n"
|
||||
"};", 5 },
|
||||
/* alloc + free via mmap-backed runtime — write through allocated
|
||||
* memory and free it. exit = 0 if the allocation succeeded. */
|
||||
@@ -195,12 +193,14 @@ static const struct row rows[] = {
|
||||
"fn main() i32 = {\n"
|
||||
" return classify(2) + classify(10) + classify(99);\n"
|
||||
"};", 159 }, /* 10+99+50=159 */
|
||||
/* fmt module: stdlib formatter for ints + strings */
|
||||
/* fmt module: stdlib formatter for strings; ints compose
|
||||
* via strconv.i64tos. */
|
||||
{ "use fmt;\n"
|
||||
"use strconv;\n"
|
||||
"fn main() i32 = {\n"
|
||||
" fmt.println(\"ww\");\n"
|
||||
" fmt.printlnint(42);\n"
|
||||
" fmt.printlnint(-7);\n"
|
||||
" fmt.println(strconv.i64tos(42, strconv.DEC));\n"
|
||||
" fmt.println(strconv.i64tos(-7, strconv.DEC));\n"
|
||||
" return 0;\n"
|
||||
"};", 0 },
|
||||
/* struct with i32 fields: MOVL/MOVSXD avoids clobbering neighbors */
|
||||
@@ -866,9 +866,9 @@ static const struct row rows[] = {
|
||||
{ "use strconv;\n"
|
||||
"type r_t = (i64 | strconv.invalid | strconv.overflow);\n"
|
||||
"fn main() i32 = {\n"
|
||||
" let r1: r_t = strconv.stoi64(\"42\");\n"
|
||||
" let r2: r_t = strconv.stoi64(\"-7\");\n"
|
||||
" let r3: r_t = strconv.stoi64(\"abc\");\n"
|
||||
" let r1: r_t = strconv.stoi64(\"42\", strconv.DEC);\n"
|
||||
" let r2: r_t = strconv.stoi64(\"-7\", strconv.DEC);\n"
|
||||
" let r3: r_t = strconv.stoi64(\"abc\", strconv.DEC);\n"
|
||||
" let acc: i32 = 0;\n"
|
||||
" match (r1) {\n"
|
||||
" case let v: i64 => acc += v: i32;\n"
|
||||
@@ -892,8 +892,8 @@ static const struct row rows[] = {
|
||||
{ "use strconv;\n"
|
||||
"type r_t = (u64 | strconv.invalid | strconv.overflow);\n"
|
||||
"fn main() i32 = {\n"
|
||||
" let r1: r_t = strconv.stou64(\"123\");\n"
|
||||
" let r2: r_t = strconv.stou64(\"-1\");\n"
|
||||
" let r1: r_t = strconv.stou64(\"123\", strconv.DEC);\n"
|
||||
" let r2: r_t = strconv.stou64(\"-1\", strconv.DEC);\n"
|
||||
" let acc: i32 = 0;\n"
|
||||
" match (r1) {\n"
|
||||
" case let v: u64 => acc += v: i32;\n"
|
||||
@@ -907,7 +907,7 @@ static const struct row rows[] = {
|
||||
" };\n"
|
||||
" return acc;\n"
|
||||
"};", 123 }, /* 123 + 0 (invalid at index 0 in \"-1\") */
|
||||
/* strings.byteindex and strings.index: now (i32 | void). */
|
||||
/* strings.indexbyte and strings.index: now (i32 | void). */
|
||||
{ "use strings;\n"
|
||||
"fn pick(r: (i32 | void), miss: i32) i32 = {\n"
|
||||
" match (r) {\n"
|
||||
@@ -918,8 +918,8 @@ static const struct row rows[] = {
|
||||
"};\n"
|
||||
"fn main() i32 = {\n"
|
||||
" let s: str = \"hello, world\";\n"
|
||||
" let i1: i32 = pick(strings.byteindex(s, 44u8), -1);\n"
|
||||
" let i2: i32 = pick(strings.byteindex(s, 122u8), -1);\n"
|
||||
" let i1: i32 = pick(strings.indexbyte(s, 44u8), -1);\n"
|
||||
" let i2: i32 = pick(strings.indexbyte(s, 122u8), -1);\n"
|
||||
" let i3: i32 = pick(strings.index(s, \"world\"), -1);\n"
|
||||
" let i4: i32 = pick(strings.index(s, \"nope\"), -1);\n"
|
||||
" return i1 + i2 + i3 + i4;\n"
|
||||
|
||||
Reference in New Issue
Block a user