lib/strconv: add itos/utos integer format (strconv-int fold-2)
Graduates the integer FORMAT side to verbatim Hare ports, completing the
round-trip whose parse half landed in fold-1, and adds the machine-word
entry points.
- u64tos: ref/hare/strconv/utos.ha:10-42. Replaces the pre-graduation
basedigit() helper with Hare's rune LUT (lut_upper/lut_lower), single
static buffer + bytes.reverse, and strings.frombytes for the
`*(&s: *str)` reinterpret (rule-9 carve-out; ww's lib/types has no
`string` struct). basedigit deleted (now dead).
- i64tos: ref/hare/strconv/itos.ha:10-32. Now `if (i >= 0) u64tos(i)`
else negate-and-prefix via `u64tos((-i): u64)`. This fixes the
i64tos-on-I64_MIN bug (cgen.ww #144): the old `n = -n; for (n > 0)`
left n at the I64_MIN bit pattern (still negative), emitting just
"-". The `(-i): u64` two's-complement reinterpret yields the true
magnitude 9223372036854775808.
- itos/utos/ztos/uptrtos: int/uint/size/uintptr 8B machine-word
wrappers (itos.ha:52, utos.ha:62/67/72), parallel to fold-1's
stoi/stou/stoz. The existing iN/uN width wrappers are unchanged.
Divergences documented at-site: no static assert; LUT-select + base
normalize via the existing basenum() (ww has no if-expression); explicit
copy loop for Hare's slice-assign.
Probes (drew PROBE-BEFORE-COMMIT, all green on BOTH stages):
- i64tos(I64_MIN) == "-9223372036854775808": cstage `ww run` exit 0 +
wwstage-compiled binary exit 0; cs==ww .s byte-identical on the real
combined (30190 lines).
- static `[0...]` fill + rune LUT static-init emit byte-identically
cross-stage (isolated smoke probe + the combined byte-id).
- frombytes (not a types::string mirror) per rule 9.
Tests: extend inttest.ww with test_u64tos[_bases] / test_i64tos[_bases]
(verbatim utos.ha:74-103 / itos.ha:54-87, flat assert sequences;
feedback_test_match_hare_source) + test_word_wrappers. I64_MIN inputs
spelled -I64_MAX-1 (proj #245: wwstage mis-lexes the 2^63 literal).
combined.ww regen: strconv is compiler-imported via fmt, so w6c +
wwdump main.combined.ww + smoke.combined.ww are regenerated.
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
package strconv;
|
||||
|
||||
import ascii;
|
||||
import bytes;
|
||||
import os;
|
||||
import strings;
|
||||
|
||||
@@ -49,83 +50,122 @@ fn basenum(b: base) i64 = {
|
||||
return 10; // DEC and DEFAULT
|
||||
};
|
||||
|
||||
fn basedigit(d: i64, b: base) u8 = {
|
||||
if (d < 10) { return (d + 48): u8; };
|
||||
let off: i64 = d - 10;
|
||||
if (b == base.HEX_LOWER) { return (off + 97): u8; };
|
||||
return (off + 65): u8;
|
||||
};
|
||||
// lut_upper / lut_lower — digit→glyph tables. Verbatim port of the
|
||||
// `static const lut_upper`/`lut_lower` rune arrays in
|
||||
// ref/hare/strconv/utos.ha:14-20. Module-level `let` (ww has no module
|
||||
// `const`; never written) following the ftos_data.ww table convention.
|
||||
// Declared [16]rune (faithful to Hare's inferred rune element type);
|
||||
// u64tos casts the indexed glyph to u8 at the store, as Hare does
|
||||
// (utos.ha:35).
|
||||
let lut_upper: [16]rune = [
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
|
||||
];
|
||||
let lut_lower: [16]rune = [
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||
];
|
||||
|
||||
// u64tos — convert v to a base-b numeric string. Returns a view into
|
||||
// `u64tos_buf` which is overwritten on the next call. Matches Hare's
|
||||
// strconv::u64tos.
|
||||
let u64tos_buf: [65]u8;
|
||||
// u64tos_buf — overwritten on each u64tos call (Hare's `static let buf`,
|
||||
// utos.ha:12). 64 = the widest u64 rendering (binary). `[0...]` kept for
|
||||
// fidelity; the initial value is irrelevant (only the freshly-written
|
||||
// prefix is ever read) but the fill form is exercised (probed: emits
|
||||
// byte-identically cross-stage).
|
||||
let u64tos_buf: [64]u8 = [0...]; // 64 binary digits
|
||||
|
||||
export fn u64tos(v: u64, b: base) str = {
|
||||
// u64tos — convert u to a base-b numeric string. Returns a view into
|
||||
// `u64tos_buf`, overwritten on the next call; copy via strings.dup to
|
||||
// outlive it. Verbatim port of ref/hare/strconv/utos.ha:10-42.
|
||||
// Divergences:
|
||||
// - Hare's `static assert(types::U64_MAX == ...)` dropped (ww has no
|
||||
// static assert; the bound lives in lib/types/types.ww:20).
|
||||
// - Hare selects the LUT via an if-EXPRESSION and reassigns `b` to
|
||||
// HEX_UPPER / DEC inline (utos.ha:21-26). ww has no if-expression
|
||||
// (standing divergence, stof.ww:31), so the glyph case is a `lower`
|
||||
// bool branch and the divisor is basenum(b) — the file's existing
|
||||
// normalize helper, which maps DEFAULT→10 and HEX_LOWER→16 exactly
|
||||
// as Hare's reassignment does.
|
||||
// - Hare's `types::string { data = &buf, ... }` + `*(&s: *str)`
|
||||
// reinterpret (utos.ha:28,41) → strings.frombytes (CLAUDE.md rule 9
|
||||
// carve-out: ww's lib/types has no `string` struct; frombytes is the
|
||||
// honest ww idiom, cf. ascii/strings).
|
||||
export fn u64tos(u: u64, b: base) str = {
|
||||
let nb: u64 = basenum(b): u64;
|
||||
let tmp: [65]u8;
|
||||
let i: i32 = 0;
|
||||
let n: u64 = v;
|
||||
if (n == 0u64) { tmp[0] = 48u8; i = 1; };
|
||||
let lower: bool = (b == base.HEX_LOWER);
|
||||
|
||||
let length: i32 = 0;
|
||||
let n: u64 = u;
|
||||
if (n == 0u64) {
|
||||
u64tos_buf[length] = lut_upper[0]: u8;
|
||||
length += 1;
|
||||
};
|
||||
for (n > 0u64) {
|
||||
let d: i64 = (n % nb): i64;
|
||||
tmp[i] = basedigit(d, b);
|
||||
if (lower) { u64tos_buf[length] = lut_lower[d]: u8; }
|
||||
else { u64tos_buf[length] = lut_upper[d]: u8; };
|
||||
length += 1;
|
||||
n = n / nb;
|
||||
i += 1;
|
||||
};
|
||||
let out: i32 = 0;
|
||||
for (i > 0) {
|
||||
i -= 1;
|
||||
u64tos_buf[out] = tmp[i];
|
||||
out += 1;
|
||||
};
|
||||
let r: str;
|
||||
r.ptr = &u64tos_buf[0];
|
||||
r.len = out;
|
||||
return r;
|
||||
|
||||
bytes.reverse(u64tos_buf[0:length]);
|
||||
return strings.frombytes(u64tos_buf[0:length]);
|
||||
};
|
||||
|
||||
// i64tos — convert v to a base-b numeric string. Returns a view into
|
||||
// `i64tos_buf` which is overwritten on the next call. Independent
|
||||
// buffer from u64tos so i64tos's own call to u64tos doesn't clobber
|
||||
// the in-flight result. Matches Hare's strconv::i64tos.
|
||||
let i64tos_buf: [66]u8;
|
||||
// i64tos_buf — independent from u64tos_buf so i64tos's own u64tos call
|
||||
// (the magnitude) doesn't clobber the in-flight result. 65 = 64 digits
|
||||
// plus the leading '-'. Hare's `static let buf: [65]u8` (itos.ha:18).
|
||||
let i64tos_buf: [65]u8 = [0...]; // 64 binary digits plus '-'
|
||||
|
||||
export fn i64tos(v: i64, b: base) str = {
|
||||
let neg: bool = false;
|
||||
let n: i64 = v;
|
||||
if (n < 0) { neg = true; n = -n; };
|
||||
let nb: i64 = basenum(b);
|
||||
let tmp: [65]u8;
|
||||
let i: i32 = 0;
|
||||
if (n == 0) { tmp[0] = 48u8; i = 1; };
|
||||
for (n > 0) {
|
||||
let d: i64 = n % nb;
|
||||
tmp[i] = basedigit(d, b);
|
||||
n = n / nb;
|
||||
i += 1;
|
||||
// i64tos — convert i to a base-b numeric string. Returns a view into
|
||||
// `i64tos_buf`. Verbatim port of ref/hare/strconv/itos.ha:10-32.
|
||||
// Divergences:
|
||||
// - `static assert` dropped (see u64tos); the DEFAULT→DEC normalize
|
||||
// rides basenum(b) inside the u64tos call (itos.ha:12-14).
|
||||
// - Hare's slice-assign `buf[1..len(u)+1] = u[..]` + the bounds assert
|
||||
// (itos.ha:26-28) → explicit copy loop (existing-file convention;
|
||||
// the [65] buffer holds the 64-digit max + sign exactly, so the
|
||||
// bound is structural).
|
||||
// - `*(&s: *str)` → strings.frombytes (see u64tos).
|
||||
export fn i64tos(i: i64, b: base) str = {
|
||||
if (i >= 0) { return u64tos(i: u64, b); };
|
||||
|
||||
i64tos_buf[0] = 45u8; // '-'
|
||||
// `(-i): u64`: for I64_MIN, -i wraps (two's complement) back to the
|
||||
// I64_MIN bit pattern; reinterpreting to u64 yields the true
|
||||
// magnitude 9223372036854775808. ref/hare/strconv/itos.ha:25. Probed
|
||||
// on both stages (NEG then i64→u64 reinterpret byte-identical);
|
||||
// closes the i64tos-on-I64_MIN bug noted at cgen.ww #144.
|
||||
let u: str = u64tos((-i): u64, b);
|
||||
let k: i32 = 0;
|
||||
for (k < u.len) {
|
||||
i64tos_buf[k + 1] = u[k];
|
||||
k += 1;
|
||||
};
|
||||
let out: i32 = 0;
|
||||
if (neg) { i64tos_buf[out] = 45u8; out += 1; }; // '-'
|
||||
for (i > 0) {
|
||||
i -= 1;
|
||||
i64tos_buf[out] = tmp[i];
|
||||
out += 1;
|
||||
};
|
||||
let r: str;
|
||||
r.ptr = &i64tos_buf[0];
|
||||
r.len = out;
|
||||
return r;
|
||||
return strings.frombytes(i64tos_buf[0 : u.len + 1]);
|
||||
};
|
||||
|
||||
export fn i32tos(v: i32, b: base) str = { return i64tos(v: i64, b); };
|
||||
export fn i16tos(v: i16, b: base) str = { return i64tos(v: i64, b); };
|
||||
export fn i8tos(v: i8, b: base) str = { return i64tos(v: i64, b); };
|
||||
|
||||
// itos — int (ww machine-word, 8B → i64-width) → string.
|
||||
// ref/hare/strconv/itos.ha:52.
|
||||
export fn itos(i: int, b: base) str = { return i64tos(i: i64, b); };
|
||||
|
||||
export fn u32tos(v: u32, b: base) str = { return u64tos(v: u64, b); };
|
||||
export fn u16tos(v: u16, b: base) str = { return u64tos(v: u64, b); };
|
||||
export fn u8tos(v: u8, b: base) str = { return u64tos(v: u64, b); };
|
||||
|
||||
// utos — uint (8B → u64-width) → string. ref/hare/strconv/utos.ha:62.
|
||||
export fn utos(u: uint, b: base) str = { return u64tos(u: u64, b); };
|
||||
|
||||
// ztos — size (8B → u64-width) → string. ref/hare/strconv/utos.ha:67.
|
||||
export fn ztos(u: size, b: base) str = { return u64tos(u: u64, b); };
|
||||
|
||||
// uptrtos — uintptr → string. ref/hare/strconv/utos.ha:72 (param `uptr`
|
||||
// cast `uptr: u64`).
|
||||
export fn uptrtos(uptr: uintptr, b: base) str = { return u64tos(uptr: u64, b); };
|
||||
|
||||
// rune_to_integer — digit value of r (0-9 → 0-9; a-z/A-Z → 10-35),
|
||||
// or void if r is not alphanumeric. Verbatim port of
|
||||
// ref/hare/strconv/stou.ha:8-15 (ww yields the void variant with a
|
||||
|
||||
@@ -233,11 +233,98 @@ fn ck_uint_ovf(id: i32, s: str, b: base) void = {
|
||||
ck_uint(62, "110101", base.BIN, 53u64: uint); // 0b110101
|
||||
};
|
||||
|
||||
// ---- format side: u64tos / i64tos / machine-word wrappers ------------
|
||||
// Verbatim ports of ref/hare/strconv/utos.ha:74-103 (utos/utos_bases) and
|
||||
// itos.ha:54-87 (itos/itos_bases) — Hare's format tests are flat assert
|
||||
// sequences too. Radix-literal inputs are written in DECIMAL (ww value
|
||||
// side has no 0b/0o/0x form): 0b11010=26, 0o1234567=342391,
|
||||
// 0x123456789ABCDEF=81985529216486895; the original radix is noted inline.
|
||||
|
||||
fn streq(a: str, b: str) bool = {
|
||||
if (a.len != b.len) { return false; };
|
||||
let k: i32 = 0;
|
||||
for (k < a.len) {
|
||||
if (a[k] != b[k]) { return false; };
|
||||
k += 1;
|
||||
};
|
||||
return true;
|
||||
};
|
||||
|
||||
fn cks(id: i32, got: str, want: str) void = {
|
||||
signalled = id;
|
||||
if (!streq(got, want)) { fail(); };
|
||||
};
|
||||
|
||||
// ref/hare/strconv/utos.ha:74-83.
|
||||
@test fn test_u64tos_bases() void = {
|
||||
cks(70, u64tos(26u64, base.BIN), "11010"); // 0b11010
|
||||
cks(71, u64tos(342391u64, base.OCT), "1234567"); // 0o1234567
|
||||
cks(72, u64tos(123456789u64, base.DEC), "123456789");
|
||||
cks(73, u64tos(81985529216486895u64, base.HEX), "123456789ABCDEF"); // 0x123456789ABCDEF
|
||||
cks(74, u64tos(81985529216486895u64, base.HEX_UPPER), "123456789ABCDEF");
|
||||
cks(75, u64tos(81985529216486895u64, base.HEX_LOWER), "123456789abcdef");
|
||||
cks(76, u64tos(18446744073709551615u64, base.BIN), // U64_MAX
|
||||
"1111111111111111111111111111111111111111111111111111111111111111");
|
||||
};
|
||||
|
||||
// ref/hare/strconv/utos.ha:85-103.
|
||||
@test fn test_u64tos() void = {
|
||||
cks(77, u64tos(1234u64, base.DEC), "1234");
|
||||
cks(78, u64tos(4321u64, base.DEC), "4321");
|
||||
cks(79, u64tos(0u64, base.DEC), "0"); // U64_MIN
|
||||
cks(80, u64tos(18446744073709551615u64, base.DEC), "18446744073709551615"); // U64_MAX
|
||||
};
|
||||
|
||||
// ref/hare/strconv/itos.ha:54-63.
|
||||
@test fn test_i64tos_bases() void = {
|
||||
cks(81, i64tos(26i64, base.BIN), "11010");
|
||||
cks(82, i64tos(342391i64, base.OCT), "1234567");
|
||||
cks(83, i64tos(123456789i64, base.DEC), "123456789");
|
||||
cks(84, i64tos(81985529216486895i64, base.HEX), "123456789ABCDEF");
|
||||
cks(85, i64tos(81985529216486895i64, base.HEX_UPPER), "123456789ABCDEF");
|
||||
cks(86, i64tos(81985529216486895i64, base.HEX_LOWER), "123456789abcdef");
|
||||
// I64_MIN binary = '1' + 63 zeros, prefixed '-'. Spelled -I64_MAX-1
|
||||
// (proj #245: wwstage mis-lexes the direct 2^63 / types.I64_MIN literal).
|
||||
cks(87, i64tos(-9223372036854775807i64 - 1i64, base.BIN),
|
||||
"-1000000000000000000000000000000000000000000000000000000000000000");
|
||||
};
|
||||
|
||||
// ref/hare/strconv/itos.ha:65-87.
|
||||
@test fn test_i64tos() void = {
|
||||
cks(88, i64tos(1234i64, base.DEC), "1234");
|
||||
cks(89, i64tos(4321i64, base.DEC), "4321");
|
||||
cks(90, i64tos(-1337i64, base.DEC), "-1337");
|
||||
cks(91, i64tos(0i64, base.DEC), "0");
|
||||
cks(92, i64tos(9223372036854775807i64, base.DEC), "9223372036854775807"); // I64_MAX
|
||||
// drew probe-1: NEG-of-I64_MIN + i64→u64 reinterpret preserves the
|
||||
// two's-complement bit pattern. I64_MIN spelled -I64_MAX-1 (proj #245).
|
||||
cks(93, i64tos(-9223372036854775807i64 - 1i64, base.DEC),
|
||||
"-9223372036854775808");
|
||||
};
|
||||
|
||||
// machine-word wrappers + width wrappers. ww int/uint/size/uintptr are
|
||||
// all 8B, so the full i64/u64 range renders untruncated. ww-authored
|
||||
// (Hare's wrappers are trivial aliases): itos.ha:37-52, utos.ha:44-72.
|
||||
@test fn test_word_wrappers() void = {
|
||||
cks(94, itos(-1337, base.DEC), "-1337");
|
||||
cks(95, itos(9223372036854775807i64: int, base.DEC), "9223372036854775807");
|
||||
cks(96, utos(18446744073709551615u64: uint, base.DEC), "18446744073709551615");
|
||||
cks(97, ztos(255u64: size, base.HEX), "FF");
|
||||
cks(98, uptrtos(4096u64: uintptr, base.DEC), "4096");
|
||||
cks(99, i32tos(-2147483648i32, base.DEC), "-2147483648");
|
||||
cks(100, u8tos(255u8, base.HEX_LOWER), "ff");
|
||||
};
|
||||
|
||||
export fn main() i32 = {
|
||||
test_stoi64();
|
||||
test_stoi64_bases();
|
||||
test_stou64();
|
||||
test_stou64_bases();
|
||||
test_stoi_stou_stoz();
|
||||
test_u64tos_bases();
|
||||
test_u64tos();
|
||||
test_i64tos_bases();
|
||||
test_i64tos();
|
||||
test_word_wrappers();
|
||||
return 0;
|
||||
};
|
||||
|
||||
@@ -5969,6 +5969,7 @@ let powers_of_ten: [596][2]u64 = [
|
||||
package strconv;
|
||||
|
||||
import ascii;
|
||||
import bytes;
|
||||
import os;
|
||||
import strings;
|
||||
|
||||
@@ -6009,83 +6010,122 @@ fn basenum(b: base) i64 = {
|
||||
return 10; // DEC and DEFAULT
|
||||
};
|
||||
|
||||
fn basedigit(d: i64, b: base) u8 = {
|
||||
if (d < 10) { return (d + 48): u8; };
|
||||
let off: i64 = d - 10;
|
||||
if (b == base.HEX_LOWER) { return (off + 97): u8; };
|
||||
return (off + 65): u8;
|
||||
};
|
||||
// lut_upper / lut_lower — digit→glyph tables. Verbatim port of the
|
||||
// `static const lut_upper`/`lut_lower` rune arrays in
|
||||
// ref/hare/strconv/utos.ha:14-20. Module-level `let` (ww has no module
|
||||
// `const`; never written) following the ftos_data.ww table convention.
|
||||
// Declared [16]rune (faithful to Hare's inferred rune element type);
|
||||
// u64tos casts the indexed glyph to u8 at the store, as Hare does
|
||||
// (utos.ha:35).
|
||||
let lut_upper: [16]rune = [
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
|
||||
];
|
||||
let lut_lower: [16]rune = [
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||
];
|
||||
|
||||
// u64tos — convert v to a base-b numeric string. Returns a view into
|
||||
// `u64tos_buf` which is overwritten on the next call. Matches Hare's
|
||||
// strconv::u64tos.
|
||||
let u64tos_buf: [65]u8;
|
||||
// u64tos_buf — overwritten on each u64tos call (Hare's `static let buf`,
|
||||
// utos.ha:12). 64 = the widest u64 rendering (binary). `[0...]` kept for
|
||||
// fidelity; the initial value is irrelevant (only the freshly-written
|
||||
// prefix is ever read) but the fill form is exercised (probed: emits
|
||||
// byte-identically cross-stage).
|
||||
let u64tos_buf: [64]u8 = [0...]; // 64 binary digits
|
||||
|
||||
export fn u64tos(v: u64, b: base) str = {
|
||||
// u64tos — convert u to a base-b numeric string. Returns a view into
|
||||
// `u64tos_buf`, overwritten on the next call; copy via strings.dup to
|
||||
// outlive it. Verbatim port of ref/hare/strconv/utos.ha:10-42.
|
||||
// Divergences:
|
||||
// - Hare's `static assert(types::U64_MAX == ...)` dropped (ww has no
|
||||
// static assert; the bound lives in lib/types/types.ww:20).
|
||||
// - Hare selects the LUT via an if-EXPRESSION and reassigns `b` to
|
||||
// HEX_UPPER / DEC inline (utos.ha:21-26). ww has no if-expression
|
||||
// (standing divergence, stof.ww:31), so the glyph case is a `lower`
|
||||
// bool branch and the divisor is basenum(b) — the file's existing
|
||||
// normalize helper, which maps DEFAULT→10 and HEX_LOWER→16 exactly
|
||||
// as Hare's reassignment does.
|
||||
// - Hare's `types::string { data = &buf, ... }` + `*(&s: *str)`
|
||||
// reinterpret (utos.ha:28,41) → strings.frombytes (CLAUDE.md rule 9
|
||||
// carve-out: ww's lib/types has no `string` struct; frombytes is the
|
||||
// honest ww idiom, cf. ascii/strings).
|
||||
export fn u64tos(u: u64, b: base) str = {
|
||||
let nb: u64 = basenum(b): u64;
|
||||
let tmp: [65]u8;
|
||||
let i: i32 = 0;
|
||||
let n: u64 = v;
|
||||
if (n == 0u64) { tmp[0] = 48u8; i = 1; };
|
||||
let lower: bool = (b == base.HEX_LOWER);
|
||||
|
||||
let length: i32 = 0;
|
||||
let n: u64 = u;
|
||||
if (n == 0u64) {
|
||||
u64tos_buf[length] = lut_upper[0]: u8;
|
||||
length += 1;
|
||||
};
|
||||
for (n > 0u64) {
|
||||
let d: i64 = (n % nb): i64;
|
||||
tmp[i] = basedigit(d, b);
|
||||
if (lower) { u64tos_buf[length] = lut_lower[d]: u8; }
|
||||
else { u64tos_buf[length] = lut_upper[d]: u8; };
|
||||
length += 1;
|
||||
n = n / nb;
|
||||
i += 1;
|
||||
};
|
||||
let out: i32 = 0;
|
||||
for (i > 0) {
|
||||
i -= 1;
|
||||
u64tos_buf[out] = tmp[i];
|
||||
out += 1;
|
||||
};
|
||||
let r: str;
|
||||
r.ptr = &u64tos_buf[0];
|
||||
r.len = out;
|
||||
return r;
|
||||
|
||||
bytes.reverse(u64tos_buf[0:length]);
|
||||
return strings.frombytes(u64tos_buf[0:length]);
|
||||
};
|
||||
|
||||
// i64tos — convert v to a base-b numeric string. Returns a view into
|
||||
// `i64tos_buf` which is overwritten on the next call. Independent
|
||||
// buffer from u64tos so i64tos's own call to u64tos doesn't clobber
|
||||
// the in-flight result. Matches Hare's strconv::i64tos.
|
||||
let i64tos_buf: [66]u8;
|
||||
// i64tos_buf — independent from u64tos_buf so i64tos's own u64tos call
|
||||
// (the magnitude) doesn't clobber the in-flight result. 65 = 64 digits
|
||||
// plus the leading '-'. Hare's `static let buf: [65]u8` (itos.ha:18).
|
||||
let i64tos_buf: [65]u8 = [0...]; // 64 binary digits plus '-'
|
||||
|
||||
export fn i64tos(v: i64, b: base) str = {
|
||||
let neg: bool = false;
|
||||
let n: i64 = v;
|
||||
if (n < 0) { neg = true; n = -n; };
|
||||
let nb: i64 = basenum(b);
|
||||
let tmp: [65]u8;
|
||||
let i: i32 = 0;
|
||||
if (n == 0) { tmp[0] = 48u8; i = 1; };
|
||||
for (n > 0) {
|
||||
let d: i64 = n % nb;
|
||||
tmp[i] = basedigit(d, b);
|
||||
n = n / nb;
|
||||
i += 1;
|
||||
// i64tos — convert i to a base-b numeric string. Returns a view into
|
||||
// `i64tos_buf`. Verbatim port of ref/hare/strconv/itos.ha:10-32.
|
||||
// Divergences:
|
||||
// - `static assert` dropped (see u64tos); the DEFAULT→DEC normalize
|
||||
// rides basenum(b) inside the u64tos call (itos.ha:12-14).
|
||||
// - Hare's slice-assign `buf[1..len(u)+1] = u[..]` + the bounds assert
|
||||
// (itos.ha:26-28) → explicit copy loop (existing-file convention;
|
||||
// the [65] buffer holds the 64-digit max + sign exactly, so the
|
||||
// bound is structural).
|
||||
// - `*(&s: *str)` → strings.frombytes (see u64tos).
|
||||
export fn i64tos(i: i64, b: base) str = {
|
||||
if (i >= 0) { return u64tos(i: u64, b); };
|
||||
|
||||
i64tos_buf[0] = 45u8; // '-'
|
||||
// `(-i): u64`: for I64_MIN, -i wraps (two's complement) back to the
|
||||
// I64_MIN bit pattern; reinterpreting to u64 yields the true
|
||||
// magnitude 9223372036854775808. ref/hare/strconv/itos.ha:25. Probed
|
||||
// on both stages (NEG then i64→u64 reinterpret byte-identical);
|
||||
// closes the i64tos-on-I64_MIN bug noted at cgen.ww #144.
|
||||
let u: str = u64tos((-i): u64, b);
|
||||
let k: i32 = 0;
|
||||
for (k < u.len) {
|
||||
i64tos_buf[k + 1] = u[k];
|
||||
k += 1;
|
||||
};
|
||||
let out: i32 = 0;
|
||||
if (neg) { i64tos_buf[out] = 45u8; out += 1; }; // '-'
|
||||
for (i > 0) {
|
||||
i -= 1;
|
||||
i64tos_buf[out] = tmp[i];
|
||||
out += 1;
|
||||
};
|
||||
let r: str;
|
||||
r.ptr = &i64tos_buf[0];
|
||||
r.len = out;
|
||||
return r;
|
||||
return strings.frombytes(i64tos_buf[0 : u.len + 1]);
|
||||
};
|
||||
|
||||
export fn i32tos(v: i32, b: base) str = { return i64tos(v: i64, b); };
|
||||
export fn i16tos(v: i16, b: base) str = { return i64tos(v: i64, b); };
|
||||
export fn i8tos(v: i8, b: base) str = { return i64tos(v: i64, b); };
|
||||
|
||||
// itos — int (ww machine-word, 8B → i64-width) → string.
|
||||
// ref/hare/strconv/itos.ha:52.
|
||||
export fn itos(i: int, b: base) str = { return i64tos(i: i64, b); };
|
||||
|
||||
export fn u32tos(v: u32, b: base) str = { return u64tos(v: u64, b); };
|
||||
export fn u16tos(v: u16, b: base) str = { return u64tos(v: u64, b); };
|
||||
export fn u8tos(v: u8, b: base) str = { return u64tos(v: u64, b); };
|
||||
|
||||
// utos — uint (8B → u64-width) → string. ref/hare/strconv/utos.ha:62.
|
||||
export fn utos(u: uint, b: base) str = { return u64tos(u: u64, b); };
|
||||
|
||||
// ztos — size (8B → u64-width) → string. ref/hare/strconv/utos.ha:67.
|
||||
export fn ztos(u: size, b: base) str = { return u64tos(u: u64, b); };
|
||||
|
||||
// uptrtos — uintptr → string. ref/hare/strconv/utos.ha:72 (param `uptr`
|
||||
// cast `uptr: u64`).
|
||||
export fn uptrtos(uptr: uintptr, b: base) str = { return u64tos(uptr: u64, b); };
|
||||
|
||||
// rune_to_integer — digit value of r (0-9 → 0-9; a-z/A-Z → 10-35),
|
||||
// or void if r is not alphanumeric. Verbatim port of
|
||||
// ref/hare/strconv/stou.ha:8-15 (ww yields the void variant with a
|
||||
|
||||
@@ -5969,6 +5969,7 @@ let powers_of_ten: [596][2]u64 = [
|
||||
package strconv;
|
||||
|
||||
import ascii;
|
||||
import bytes;
|
||||
import os;
|
||||
import strings;
|
||||
|
||||
@@ -6009,83 +6010,122 @@ fn basenum(b: base) i64 = {
|
||||
return 10; // DEC and DEFAULT
|
||||
};
|
||||
|
||||
fn basedigit(d: i64, b: base) u8 = {
|
||||
if (d < 10) { return (d + 48): u8; };
|
||||
let off: i64 = d - 10;
|
||||
if (b == base.HEX_LOWER) { return (off + 97): u8; };
|
||||
return (off + 65): u8;
|
||||
};
|
||||
// lut_upper / lut_lower — digit→glyph tables. Verbatim port of the
|
||||
// `static const lut_upper`/`lut_lower` rune arrays in
|
||||
// ref/hare/strconv/utos.ha:14-20. Module-level `let` (ww has no module
|
||||
// `const`; never written) following the ftos_data.ww table convention.
|
||||
// Declared [16]rune (faithful to Hare's inferred rune element type);
|
||||
// u64tos casts the indexed glyph to u8 at the store, as Hare does
|
||||
// (utos.ha:35).
|
||||
let lut_upper: [16]rune = [
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
|
||||
];
|
||||
let lut_lower: [16]rune = [
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||
];
|
||||
|
||||
// u64tos — convert v to a base-b numeric string. Returns a view into
|
||||
// `u64tos_buf` which is overwritten on the next call. Matches Hare's
|
||||
// strconv::u64tos.
|
||||
let u64tos_buf: [65]u8;
|
||||
// u64tos_buf — overwritten on each u64tos call (Hare's `static let buf`,
|
||||
// utos.ha:12). 64 = the widest u64 rendering (binary). `[0...]` kept for
|
||||
// fidelity; the initial value is irrelevant (only the freshly-written
|
||||
// prefix is ever read) but the fill form is exercised (probed: emits
|
||||
// byte-identically cross-stage).
|
||||
let u64tos_buf: [64]u8 = [0...]; // 64 binary digits
|
||||
|
||||
export fn u64tos(v: u64, b: base) str = {
|
||||
// u64tos — convert u to a base-b numeric string. Returns a view into
|
||||
// `u64tos_buf`, overwritten on the next call; copy via strings.dup to
|
||||
// outlive it. Verbatim port of ref/hare/strconv/utos.ha:10-42.
|
||||
// Divergences:
|
||||
// - Hare's `static assert(types::U64_MAX == ...)` dropped (ww has no
|
||||
// static assert; the bound lives in lib/types/types.ww:20).
|
||||
// - Hare selects the LUT via an if-EXPRESSION and reassigns `b` to
|
||||
// HEX_UPPER / DEC inline (utos.ha:21-26). ww has no if-expression
|
||||
// (standing divergence, stof.ww:31), so the glyph case is a `lower`
|
||||
// bool branch and the divisor is basenum(b) — the file's existing
|
||||
// normalize helper, which maps DEFAULT→10 and HEX_LOWER→16 exactly
|
||||
// as Hare's reassignment does.
|
||||
// - Hare's `types::string { data = &buf, ... }` + `*(&s: *str)`
|
||||
// reinterpret (utos.ha:28,41) → strings.frombytes (CLAUDE.md rule 9
|
||||
// carve-out: ww's lib/types has no `string` struct; frombytes is the
|
||||
// honest ww idiom, cf. ascii/strings).
|
||||
export fn u64tos(u: u64, b: base) str = {
|
||||
let nb: u64 = basenum(b): u64;
|
||||
let tmp: [65]u8;
|
||||
let i: i32 = 0;
|
||||
let n: u64 = v;
|
||||
if (n == 0u64) { tmp[0] = 48u8; i = 1; };
|
||||
let lower: bool = (b == base.HEX_LOWER);
|
||||
|
||||
let length: i32 = 0;
|
||||
let n: u64 = u;
|
||||
if (n == 0u64) {
|
||||
u64tos_buf[length] = lut_upper[0]: u8;
|
||||
length += 1;
|
||||
};
|
||||
for (n > 0u64) {
|
||||
let d: i64 = (n % nb): i64;
|
||||
tmp[i] = basedigit(d, b);
|
||||
if (lower) { u64tos_buf[length] = lut_lower[d]: u8; }
|
||||
else { u64tos_buf[length] = lut_upper[d]: u8; };
|
||||
length += 1;
|
||||
n = n / nb;
|
||||
i += 1;
|
||||
};
|
||||
let out: i32 = 0;
|
||||
for (i > 0) {
|
||||
i -= 1;
|
||||
u64tos_buf[out] = tmp[i];
|
||||
out += 1;
|
||||
};
|
||||
let r: str;
|
||||
r.ptr = &u64tos_buf[0];
|
||||
r.len = out;
|
||||
return r;
|
||||
|
||||
bytes.reverse(u64tos_buf[0:length]);
|
||||
return strings.frombytes(u64tos_buf[0:length]);
|
||||
};
|
||||
|
||||
// i64tos — convert v to a base-b numeric string. Returns a view into
|
||||
// `i64tos_buf` which is overwritten on the next call. Independent
|
||||
// buffer from u64tos so i64tos's own call to u64tos doesn't clobber
|
||||
// the in-flight result. Matches Hare's strconv::i64tos.
|
||||
let i64tos_buf: [66]u8;
|
||||
// i64tos_buf — independent from u64tos_buf so i64tos's own u64tos call
|
||||
// (the magnitude) doesn't clobber the in-flight result. 65 = 64 digits
|
||||
// plus the leading '-'. Hare's `static let buf: [65]u8` (itos.ha:18).
|
||||
let i64tos_buf: [65]u8 = [0...]; // 64 binary digits plus '-'
|
||||
|
||||
export fn i64tos(v: i64, b: base) str = {
|
||||
let neg: bool = false;
|
||||
let n: i64 = v;
|
||||
if (n < 0) { neg = true; n = -n; };
|
||||
let nb: i64 = basenum(b);
|
||||
let tmp: [65]u8;
|
||||
let i: i32 = 0;
|
||||
if (n == 0) { tmp[0] = 48u8; i = 1; };
|
||||
for (n > 0) {
|
||||
let d: i64 = n % nb;
|
||||
tmp[i] = basedigit(d, b);
|
||||
n = n / nb;
|
||||
i += 1;
|
||||
// i64tos — convert i to a base-b numeric string. Returns a view into
|
||||
// `i64tos_buf`. Verbatim port of ref/hare/strconv/itos.ha:10-32.
|
||||
// Divergences:
|
||||
// - `static assert` dropped (see u64tos); the DEFAULT→DEC normalize
|
||||
// rides basenum(b) inside the u64tos call (itos.ha:12-14).
|
||||
// - Hare's slice-assign `buf[1..len(u)+1] = u[..]` + the bounds assert
|
||||
// (itos.ha:26-28) → explicit copy loop (existing-file convention;
|
||||
// the [65] buffer holds the 64-digit max + sign exactly, so the
|
||||
// bound is structural).
|
||||
// - `*(&s: *str)` → strings.frombytes (see u64tos).
|
||||
export fn i64tos(i: i64, b: base) str = {
|
||||
if (i >= 0) { return u64tos(i: u64, b); };
|
||||
|
||||
i64tos_buf[0] = 45u8; // '-'
|
||||
// `(-i): u64`: for I64_MIN, -i wraps (two's complement) back to the
|
||||
// I64_MIN bit pattern; reinterpreting to u64 yields the true
|
||||
// magnitude 9223372036854775808. ref/hare/strconv/itos.ha:25. Probed
|
||||
// on both stages (NEG then i64→u64 reinterpret byte-identical);
|
||||
// closes the i64tos-on-I64_MIN bug noted at cgen.ww #144.
|
||||
let u: str = u64tos((-i): u64, b);
|
||||
let k: i32 = 0;
|
||||
for (k < u.len) {
|
||||
i64tos_buf[k + 1] = u[k];
|
||||
k += 1;
|
||||
};
|
||||
let out: i32 = 0;
|
||||
if (neg) { i64tos_buf[out] = 45u8; out += 1; }; // '-'
|
||||
for (i > 0) {
|
||||
i -= 1;
|
||||
i64tos_buf[out] = tmp[i];
|
||||
out += 1;
|
||||
};
|
||||
let r: str;
|
||||
r.ptr = &i64tos_buf[0];
|
||||
r.len = out;
|
||||
return r;
|
||||
return strings.frombytes(i64tos_buf[0 : u.len + 1]);
|
||||
};
|
||||
|
||||
export fn i32tos(v: i32, b: base) str = { return i64tos(v: i64, b); };
|
||||
export fn i16tos(v: i16, b: base) str = { return i64tos(v: i64, b); };
|
||||
export fn i8tos(v: i8, b: base) str = { return i64tos(v: i64, b); };
|
||||
|
||||
// itos — int (ww machine-word, 8B → i64-width) → string.
|
||||
// ref/hare/strconv/itos.ha:52.
|
||||
export fn itos(i: int, b: base) str = { return i64tos(i: i64, b); };
|
||||
|
||||
export fn u32tos(v: u32, b: base) str = { return u64tos(v: u64, b); };
|
||||
export fn u16tos(v: u16, b: base) str = { return u64tos(v: u64, b); };
|
||||
export fn u8tos(v: u8, b: base) str = { return u64tos(v: u64, b); };
|
||||
|
||||
// utos — uint (8B → u64-width) → string. ref/hare/strconv/utos.ha:62.
|
||||
export fn utos(u: uint, b: base) str = { return u64tos(u: u64, b); };
|
||||
|
||||
// ztos — size (8B → u64-width) → string. ref/hare/strconv/utos.ha:67.
|
||||
export fn ztos(u: size, b: base) str = { return u64tos(u: u64, b); };
|
||||
|
||||
// uptrtos — uintptr → string. ref/hare/strconv/utos.ha:72 (param `uptr`
|
||||
// cast `uptr: u64`).
|
||||
export fn uptrtos(uptr: uintptr, b: base) str = { return u64tos(uptr: u64, b); };
|
||||
|
||||
// rune_to_integer — digit value of r (0-9 → 0-9; a-z/A-Z → 10-35),
|
||||
// or void if r is not alphanumeric. Verbatim port of
|
||||
// ref/hare/strconv/stou.ha:8-15 (ww yields the void variant with a
|
||||
|
||||
@@ -5969,6 +5969,7 @@ let powers_of_ten: [596][2]u64 = [
|
||||
package strconv;
|
||||
|
||||
import ascii;
|
||||
import bytes;
|
||||
import os;
|
||||
import strings;
|
||||
|
||||
@@ -6009,83 +6010,122 @@ fn basenum(b: base) i64 = {
|
||||
return 10; // DEC and DEFAULT
|
||||
};
|
||||
|
||||
fn basedigit(d: i64, b: base) u8 = {
|
||||
if (d < 10) { return (d + 48): u8; };
|
||||
let off: i64 = d - 10;
|
||||
if (b == base.HEX_LOWER) { return (off + 97): u8; };
|
||||
return (off + 65): u8;
|
||||
};
|
||||
// lut_upper / lut_lower — digit→glyph tables. Verbatim port of the
|
||||
// `static const lut_upper`/`lut_lower` rune arrays in
|
||||
// ref/hare/strconv/utos.ha:14-20. Module-level `let` (ww has no module
|
||||
// `const`; never written) following the ftos_data.ww table convention.
|
||||
// Declared [16]rune (faithful to Hare's inferred rune element type);
|
||||
// u64tos casts the indexed glyph to u8 at the store, as Hare does
|
||||
// (utos.ha:35).
|
||||
let lut_upper: [16]rune = [
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
|
||||
];
|
||||
let lut_lower: [16]rune = [
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||
];
|
||||
|
||||
// u64tos — convert v to a base-b numeric string. Returns a view into
|
||||
// `u64tos_buf` which is overwritten on the next call. Matches Hare's
|
||||
// strconv::u64tos.
|
||||
let u64tos_buf: [65]u8;
|
||||
// u64tos_buf — overwritten on each u64tos call (Hare's `static let buf`,
|
||||
// utos.ha:12). 64 = the widest u64 rendering (binary). `[0...]` kept for
|
||||
// fidelity; the initial value is irrelevant (only the freshly-written
|
||||
// prefix is ever read) but the fill form is exercised (probed: emits
|
||||
// byte-identically cross-stage).
|
||||
let u64tos_buf: [64]u8 = [0...]; // 64 binary digits
|
||||
|
||||
export fn u64tos(v: u64, b: base) str = {
|
||||
// u64tos — convert u to a base-b numeric string. Returns a view into
|
||||
// `u64tos_buf`, overwritten on the next call; copy via strings.dup to
|
||||
// outlive it. Verbatim port of ref/hare/strconv/utos.ha:10-42.
|
||||
// Divergences:
|
||||
// - Hare's `static assert(types::U64_MAX == ...)` dropped (ww has no
|
||||
// static assert; the bound lives in lib/types/types.ww:20).
|
||||
// - Hare selects the LUT via an if-EXPRESSION and reassigns `b` to
|
||||
// HEX_UPPER / DEC inline (utos.ha:21-26). ww has no if-expression
|
||||
// (standing divergence, stof.ww:31), so the glyph case is a `lower`
|
||||
// bool branch and the divisor is basenum(b) — the file's existing
|
||||
// normalize helper, which maps DEFAULT→10 and HEX_LOWER→16 exactly
|
||||
// as Hare's reassignment does.
|
||||
// - Hare's `types::string { data = &buf, ... }` + `*(&s: *str)`
|
||||
// reinterpret (utos.ha:28,41) → strings.frombytes (CLAUDE.md rule 9
|
||||
// carve-out: ww's lib/types has no `string` struct; frombytes is the
|
||||
// honest ww idiom, cf. ascii/strings).
|
||||
export fn u64tos(u: u64, b: base) str = {
|
||||
let nb: u64 = basenum(b): u64;
|
||||
let tmp: [65]u8;
|
||||
let i: i32 = 0;
|
||||
let n: u64 = v;
|
||||
if (n == 0u64) { tmp[0] = 48u8; i = 1; };
|
||||
let lower: bool = (b == base.HEX_LOWER);
|
||||
|
||||
let length: i32 = 0;
|
||||
let n: u64 = u;
|
||||
if (n == 0u64) {
|
||||
u64tos_buf[length] = lut_upper[0]: u8;
|
||||
length += 1;
|
||||
};
|
||||
for (n > 0u64) {
|
||||
let d: i64 = (n % nb): i64;
|
||||
tmp[i] = basedigit(d, b);
|
||||
if (lower) { u64tos_buf[length] = lut_lower[d]: u8; }
|
||||
else { u64tos_buf[length] = lut_upper[d]: u8; };
|
||||
length += 1;
|
||||
n = n / nb;
|
||||
i += 1;
|
||||
};
|
||||
let out: i32 = 0;
|
||||
for (i > 0) {
|
||||
i -= 1;
|
||||
u64tos_buf[out] = tmp[i];
|
||||
out += 1;
|
||||
};
|
||||
let r: str;
|
||||
r.ptr = &u64tos_buf[0];
|
||||
r.len = out;
|
||||
return r;
|
||||
|
||||
bytes.reverse(u64tos_buf[0:length]);
|
||||
return strings.frombytes(u64tos_buf[0:length]);
|
||||
};
|
||||
|
||||
// i64tos — convert v to a base-b numeric string. Returns a view into
|
||||
// `i64tos_buf` which is overwritten on the next call. Independent
|
||||
// buffer from u64tos so i64tos's own call to u64tos doesn't clobber
|
||||
// the in-flight result. Matches Hare's strconv::i64tos.
|
||||
let i64tos_buf: [66]u8;
|
||||
// i64tos_buf — independent from u64tos_buf so i64tos's own u64tos call
|
||||
// (the magnitude) doesn't clobber the in-flight result. 65 = 64 digits
|
||||
// plus the leading '-'. Hare's `static let buf: [65]u8` (itos.ha:18).
|
||||
let i64tos_buf: [65]u8 = [0...]; // 64 binary digits plus '-'
|
||||
|
||||
export fn i64tos(v: i64, b: base) str = {
|
||||
let neg: bool = false;
|
||||
let n: i64 = v;
|
||||
if (n < 0) { neg = true; n = -n; };
|
||||
let nb: i64 = basenum(b);
|
||||
let tmp: [65]u8;
|
||||
let i: i32 = 0;
|
||||
if (n == 0) { tmp[0] = 48u8; i = 1; };
|
||||
for (n > 0) {
|
||||
let d: i64 = n % nb;
|
||||
tmp[i] = basedigit(d, b);
|
||||
n = n / nb;
|
||||
i += 1;
|
||||
// i64tos — convert i to a base-b numeric string. Returns a view into
|
||||
// `i64tos_buf`. Verbatim port of ref/hare/strconv/itos.ha:10-32.
|
||||
// Divergences:
|
||||
// - `static assert` dropped (see u64tos); the DEFAULT→DEC normalize
|
||||
// rides basenum(b) inside the u64tos call (itos.ha:12-14).
|
||||
// - Hare's slice-assign `buf[1..len(u)+1] = u[..]` + the bounds assert
|
||||
// (itos.ha:26-28) → explicit copy loop (existing-file convention;
|
||||
// the [65] buffer holds the 64-digit max + sign exactly, so the
|
||||
// bound is structural).
|
||||
// - `*(&s: *str)` → strings.frombytes (see u64tos).
|
||||
export fn i64tos(i: i64, b: base) str = {
|
||||
if (i >= 0) { return u64tos(i: u64, b); };
|
||||
|
||||
i64tos_buf[0] = 45u8; // '-'
|
||||
// `(-i): u64`: for I64_MIN, -i wraps (two's complement) back to the
|
||||
// I64_MIN bit pattern; reinterpreting to u64 yields the true
|
||||
// magnitude 9223372036854775808. ref/hare/strconv/itos.ha:25. Probed
|
||||
// on both stages (NEG then i64→u64 reinterpret byte-identical);
|
||||
// closes the i64tos-on-I64_MIN bug noted at cgen.ww #144.
|
||||
let u: str = u64tos((-i): u64, b);
|
||||
let k: i32 = 0;
|
||||
for (k < u.len) {
|
||||
i64tos_buf[k + 1] = u[k];
|
||||
k += 1;
|
||||
};
|
||||
let out: i32 = 0;
|
||||
if (neg) { i64tos_buf[out] = 45u8; out += 1; }; // '-'
|
||||
for (i > 0) {
|
||||
i -= 1;
|
||||
i64tos_buf[out] = tmp[i];
|
||||
out += 1;
|
||||
};
|
||||
let r: str;
|
||||
r.ptr = &i64tos_buf[0];
|
||||
r.len = out;
|
||||
return r;
|
||||
return strings.frombytes(i64tos_buf[0 : u.len + 1]);
|
||||
};
|
||||
|
||||
export fn i32tos(v: i32, b: base) str = { return i64tos(v: i64, b); };
|
||||
export fn i16tos(v: i16, b: base) str = { return i64tos(v: i64, b); };
|
||||
export fn i8tos(v: i8, b: base) str = { return i64tos(v: i64, b); };
|
||||
|
||||
// itos — int (ww machine-word, 8B → i64-width) → string.
|
||||
// ref/hare/strconv/itos.ha:52.
|
||||
export fn itos(i: int, b: base) str = { return i64tos(i: i64, b); };
|
||||
|
||||
export fn u32tos(v: u32, b: base) str = { return u64tos(v: u64, b); };
|
||||
export fn u16tos(v: u16, b: base) str = { return u64tos(v: u64, b); };
|
||||
export fn u8tos(v: u8, b: base) str = { return u64tos(v: u64, b); };
|
||||
|
||||
// utos — uint (8B → u64-width) → string. ref/hare/strconv/utos.ha:62.
|
||||
export fn utos(u: uint, b: base) str = { return u64tos(u: u64, b); };
|
||||
|
||||
// ztos — size (8B → u64-width) → string. ref/hare/strconv/utos.ha:67.
|
||||
export fn ztos(u: size, b: base) str = { return u64tos(u: u64, b); };
|
||||
|
||||
// uptrtos — uintptr → string. ref/hare/strconv/utos.ha:72 (param `uptr`
|
||||
// cast `uptr: u64`).
|
||||
export fn uptrtos(uptr: uintptr, b: base) str = { return u64tos(uptr: u64, b); };
|
||||
|
||||
// rune_to_integer — digit value of r (0-9 → 0-9; a-z/A-Z → 10-35),
|
||||
// or void if r is not alphanumeric. Verbatim port of
|
||||
// ref/hare/strconv/stou.ha:8-15 (ww yields the void variant with a
|
||||
|
||||
Reference in New Issue
Block a user