hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit 1228d3bf612bfe4cba70e1e7786617cdf1c58a31
parent 9a18b3d1b92e93aeea3e4572fd016444dc447fb3
Author: Alexey Yerin <yyp@disroot.org>
Date:   Wed, 10 Apr 2024 20:48:55 +0300

strconv: Merge functions with their -b versions

This is a breaking change: all calls to stoub and similar functions should drop
the -b suffix.

Signed-off-by: Alexey Yerin <yyp@disroot.org>

Diffstat:
Mencoding/hex/hex.ha | 4++--
Mfmt/print.ha | 7+++----
Mformat/tar/reader.ha | 4++--
Mhare/lex/lex.ha | 6+++---
Mnet/ip/ip.ha | 2+-
Mnet/uri/parse.ha | 2+-
Mstrconv/itos.ha | 93+++++++++++++++++++++++++++++--------------------------------------------------
Mstrconv/numeric.ha | 95+++++++++++++++++++++++++++++--------------------------------------------------
Mstrconv/stof.ha | 90+++++++++++++++++++++++++++++++++----------------------------------------------
Mstrconv/stoi.ha | 77++++++++++++++++++++++++++---------------------------------------------------
Mstrconv/stou.ha | 84++++++++++++++++++++++++++-----------------------------------------------------
Mstrconv/utos.ha | 119++++++++++++++++++++++++++++---------------------------------------------------
Muuid/uuid.ha | 2+-
13 files changed, 214 insertions(+), 371 deletions(-)

diff --git a/encoding/hex/hex.ha b/encoding/hex/hex.ha @@ -42,7 +42,7 @@ fn encode_writer(s: *io::stream, in: const []u8) (size | io::error) = { }; let z = 0z; for (let i = 0z; i < len(in); i += 1) { - const r = strconv::u8tosb(in[i], strconv::base::HEX_LOWER); + const r = strconv::u8tos(in[i], strconv::base::HEX_LOWER); if (len(r) == 1) { match(fmt::fprint(s.out, "0")) { case let b: size => @@ -151,7 +151,7 @@ fn decode_reader(s: *io::stream, out: []u8) (size | io::EOF | io::error) = { const l = nr / 2; for (let i = 0z; i < l; i += 1) { const oct = strings::fromutf8_unsafe(buf[i * 2..i * 2 + 2]); - const u = match (strconv::stou8b(oct, 16)) { + const u = match (strconv::stou8(oct, 16)) { case (strconv::invalid | strconv::overflow) => s.state = errors::invalid; return errors::invalid; diff --git a/fmt/print.ha b/fmt/print.ha @@ -90,14 +90,13 @@ case let s: str => case let b: bool => return io::write(out, strings::toutf8(if (b) "true" else "false")); case let p: uintptr => - const s = strconv::uptrtosb(p, mod.base); + const s = strconv::uptrtos(p, mod.base); return io::write(out, strings::toutf8(s)); case let v: nullable *opaque => match (v) { case let v: *opaque => let z = io::write(out, strings::toutf8("0x"))?; - const s = strconv::uptrtosb(v: uintptr, - strconv::base::HEX_LOWER); + const s = strconv::uptrtos(v: uintptr, strconv::base::HEX_LOWER); z += io::write(out, strings::toutf8(s))?; return z; case null => @@ -126,7 +125,7 @@ case let i: types::integer => }; }; - let i = strconv::integertosb(i, mod.base); + let i = strconv::integertos(i, mod.base); let pad = if (mod.prec < len(sign) + len(i)) { yield 0z; } else { diff --git a/format/tar/reader.ha b/format/tar/reader.ha @@ -187,7 +187,7 @@ fn readstr(rd: *memio::stream, ln: size) str = { fn readoct(rd: *memio::stream, ln: size) (uint | invalid) = { const string = readstr(rd, ln); - match (strconv::stoub(string, strconv::base::OCT)) { + match (strconv::stou(string, strconv::base::OCT)) { case let u: uint => return u; case => @@ -197,7 +197,7 @@ fn readoct(rd: *memio::stream, ln: size) (uint | invalid) = { fn readsize(rd: *memio::stream, ln: size) (size | invalid) = { const string = readstr(rd, ln); - match (strconv::stozb(string, strconv::base::OCT)) { + match (strconv::stoz(string, strconv::base::OCT)) { case let z: size => return z; case => diff --git a/hare/lex/lex.ha b/hare/lex/lex.ha @@ -171,7 +171,7 @@ fn lex_unicode(lex: *lexer, loc: location, n: size) (rune | error) = { buf[i] = r: u8; }; let s = strings::fromutf8_unsafe(buf[..n]); - return strconv::stou32b(s, strconv::base::HEX) as u32: rune; + return strconv::stou32(s, strconv::base::HEX) as u32: rune; }; fn lex_rune(lex: *lexer, loc: location) (rune | error) = { @@ -600,9 +600,9 @@ fn lex_literal(lex: *lexer) (token | error) = { let val = switch (suff) { case ltok::LIT_F32, ltok::LIT_F64, ltok::LIT_FCONST => val = strings::fromutf8(chars[..floatend])!; - yield strconv::stof64b(val, base); + yield strconv::stof64(val, base); case => - yield strconv::stou64b(val, base); + yield strconv::stou64(val, base); }; let val = match (val) { case let val: u64 => diff --git a/net/ip/ip.ha b/net/ip/ip.ha @@ -112,7 +112,7 @@ export fn parsev6(st: str) (addr6 | invalid) = { ells = i; continue; }; - match (strconv::stou16b(s, 16)) { + match (strconv::stou16(s, strconv::base::HEX)) { case let val: u16 => endian::beputu16(ret[i..], val); i += 2; diff --git a/net/uri/parse.ha b/net/uri/parse.ha @@ -318,7 +318,7 @@ fn percent_decode_static(out: io::handle, s: str) (void | invalid) = { memio::appendrune(&tmp, r)!; }; - match (strconv::stou8b(memio::string(&tmp)!, + match (strconv::stou8(memio::string(&tmp)!, strconv::base::HEX)) { case let ord: u8 => append(percent_data, ord); diff --git a/strconv/itos.ha b/strconv/itos.ha @@ -5,16 +5,16 @@ use bytes; use strings; use types; -// Converts an i64 to a string in the given base. The return value is statically -// allocated and will be overwritten on subsequent calls; see [[strings::dup]] to -// duplicate the result. -export fn i64tosb(i: i64, b: base) const str = { +// Converts an i64 to a string. The return value is statically allocated and +// will be overwritten on subsequent calls; see [[strings::dup]] to duplicate +// the result. +export fn i64tos(i: i64, b: base = base::DEC) const str = { static assert(types::I64_MAX == 9223372036854775807); if (b == base::DEFAULT) { b = base::DEC; }; - if (i >= 0) return u64tosb(i: u64, b); + if (i >= 0) return u64tos(i: u64, b); static let buf: [65]u8 = [0...]; // 64 binary digits plus - @@ -23,7 +23,7 @@ export fn i64tosb(i: i64, b: base) const str = { buf[0] = '-'; s.length = 1; - let u = strings::toutf8(u64tosb((-i): u64, b)); + let u = strings::toutf8(u64tos((-i): u64, b)); assert(len(u) < len(buf)); buf[1..len(u) + 1] = u[..]; @@ -32,60 +32,35 @@ export fn i64tosb(i: i64, b: base) const str = { return *(&s: *str); }; -// Converts an i32 to a string in the given base. The return value is statically -// allocated and will be overwritten on subsequent calls; see [[strings::dup]] to -// duplicate the result. -export fn i32tosb(i: i32, b: base) const str = i64tosb(i, b); - -// Converts an i16 to a string in the given base. The return value is statically -// allocated and will be overwritten on subsequent calls; see [[strings::dup]] to -// duplicate the result. -export fn i16tosb(i: i16, b: base) const str = i64tosb(i, b); - -// Converts an i8 to a string in the given base. The return value is statically -// allocated and will be overwritten on subsequent calls; see [[strings::dup]] to -// duplicate the result. -export fn i8tosb(i: i8, b: base) const str = i64tosb(i, b); - -// Converts an int to a string in the given base. The return value is -// statically allocated and will be overwritten on subsequent calls; see -// [[strings::dup]] to duplicate the result. -export fn itosb(i: int, b: base) const str = i64tosb(i, b); - -// Converts an i64 to a string in base 10. The return value is statically -// allocated and will be overwritten on subsequent calls; see [[strings::dup]] to -// duplicate the result. -export fn i64tos(i: i64) const str = i64tosb(i, base::DEC); - -// Converts an i32 to a string in base 10. The return value is statically -// allocated and will be overwritten on subsequent calls; see [[strings::dup]] to -// duplicate the result. -export fn i32tos(i: i32) const str = i64tos(i); - -// Converts an i16 to a string in base 10. The return value is statically -// allocated and will be overwritten on subsequent calls; see [[strings::dup]] to -// duplicate the result. -export fn i16tos(i: i16) const str = i64tos(i); - -// Converts an i8 to a string in base 10. The return value is statically -// allocated and will be overwritten on subsequent calls; see [[strings::dup]] to -// duplicate the result. -export fn i8tos(i: i8) const str = i64tos(i); - -// Converts an int to a string in base 10. The return value is statically -// allocated and will be overwritten on subsequent calls; see [[strings::dup]] to -// duplicate the result. -export fn itos(i: int) const str = i64tos(i); - -@test fn itosb() void = { - assert("11010" == i64tosb(0b11010, base::BIN)); - assert("1234567" == i64tosb(0o1234567, base::OCT)); - assert("123456789" == i64tosb(123456789, base::DEC)); - assert("123456789ABCDEF" == i64tosb(0x123456789ABCDEF, base::HEX)); - assert("123456789ABCDEF" == i64tosb(0x123456789ABCDEF, base::HEX_UPPER)); - assert("123456789abcdef" == i64tosb(0x123456789ABCDEF, base::HEX_LOWER)); +// Converts an i32 to a string. The return value is statically allocated and +// will be overwritten on subsequent calls; see [[strings::dup]] to duplicate +// the result. +export fn i32tos(i: i32, b: base = base::DEC) const str = i64tos(i, b); + +// Converts an i16 to a string. The return value is statically allocated and +// will be overwritten on subsequent calls; see [[strings::dup]] to duplicate +// the result. +export fn i16tos(i: i16, b: base = base::DEC) const str = i64tos(i, b); + +// Converts an i8 to a string. The return value is statically allocated and will +// be overwritten on subsequent calls; see [[strings::dup]] to duplicate the +// result. +export fn i8tos(i: i8, b: base = base::DEC) const str = i64tos(i, b); + +// Converts an int to a string. The return value is statically allocated and +// will be overwritten on subsequent calls; see [[strings::dup]] to duplicate +// the result. +export fn itos(i: int, b: base = base::DEC) const str = i64tos(i, b); + +@test fn itos_bases() void = { + assert("11010" == i64tos(0b11010, base::BIN)); + assert("1234567" == i64tos(0o1234567, base::OCT)); + assert("123456789" == i64tos(123456789, base::DEC)); + assert("123456789ABCDEF" == i64tos(0x123456789ABCDEF, base::HEX)); + assert("123456789ABCDEF" == i64tos(0x123456789ABCDEF, base::HEX_UPPER)); + assert("123456789abcdef" == i64tos(0x123456789ABCDEF, base::HEX_LOWER)); assert("-1000000000000000000000000000000000000000000000000000000000000000" - == i64tosb(types::I64_MIN, base::BIN)); + == i64tos(types::I64_MIN, base::BIN)); }; @test fn itos() void = { diff --git a/strconv/numeric.ha b/strconv/numeric.ha @@ -3,75 +3,60 @@ use types; -// Converts any [[types::signed]] to a string in a given base. The return value is -// statically allocated and will be overwritten on subsequent calls; see -// [[strings::dup]] to duplicate the result. -export fn signedtosb(n: types::signed, b: base) const str = { +// Converts any [[types::signed]] to a string. The return value is statically +// allocated and will be overwritten on subsequent calls; see [[strings::dup]] +// to duplicate the result. If base is not specified, base 10 is used. +export fn signedtos(n: types::signed, b: base = base::DEC) const str = { match (n) { case let i: int => - return itosb(i, b); + return itos(i, b); case let i: i8 => - return i8tosb(i, b); + return i8tos(i, b); case let i: i16 => - return i16tosb(i, b); + return i16tos(i, b); case let i: i32 => - return i32tosb(i, b); + return i32tos(i, b); case let i: i64 => - return i64tosb(i, b); + return i64tos(i, b); }; }; -// Converts any [[types::signed]] to a string in base 10. The return value is -// statically allocated and will be overwritten on subsequent calls; see -// [[strings::dup]] to duplicate the result. -export fn signedtos(n: types::signed) const str = signedtosb(n, base::DEC); - -// Converts any [[types::unsigned]] to a string in a given base. The return value -// is statically allocated and will be overwritten on subsequent calls; see -// [[strings::dup]] to duplicate the result. -export fn unsignedtosb(n: types::unsigned, b: base) const str = { +// Converts any [[types::unsigned]] to a string. The return value is statically +// allocated and will be overwritten on subsequent calls; see [[strings::dup]] +// to duplicate the result. If base is not specified, base 10 is used. +export fn unsignedtos(n: types::unsigned, b: base = base::DEC) const str = { match (n) { case let u: size => - return ztosb(u, b); + return ztos(u, b); case let u: uint => - return utosb(u, b); + return utos(u, b); case let u: u8 => - return u8tosb(u, b); + return u8tos(u, b); case let u: u16 => - return u16tosb(u, b); + return u16tos(u, b); case let u: u32 => - return u32tosb(u, b); + return u32tos(u, b); case let u: u64 => - return u64tosb(u, b); + return u64tos(u, b); }; }; -// Converts any [[types::unsigned]] to a string in base 10. The return value is -// statically allocated and will be overwritten on subsequent calls; see -// [[strings::dup]] to duplicate the result. -export fn unsignedtos(n: types::unsigned) const str = unsignedtosb(n, base::DEC); - -// Converts any [[types::integer]] to a string in a given base. The return value -// is statically allocated and will be overwritten on subsequent calls; see -// [[strings::dup]] to duplicate the result. -export fn integertosb(n: types::integer, b: base) const str = { +// Converts any [[types::integer]] to a string. The return value is statically +// allocated and will be overwritten on subsequent calls; see [[strings::dup]] +// to duplicate the result. If base is not specified, base 10 is used. +export fn integertos(n: types::integer, b: base = base::DEC) const str = { match (n) { case let s: types::signed => - return signedtosb(s, b); + return signedtos(s, b); case let u: types::unsigned => - return unsignedtosb(u, b); + return unsignedtos(u, b); }; }; -// Converts any [[types::integer]] to a string in base 10. The return value is -// statically allocated and will be overwritten on subsequent calls; see -// [[strings::dup]] to duplicate the result. -export fn integertos(n: types::integer) const str = integertosb(n, base::DEC); - -// Converts any [[types::floating]] to a string in a given base. The return value -// is statically allocated and will be overwritten on subsequent calls; see -// [[strings::dup]] to duplicate the result. -export fn floatingtosb(n: types::floating, b: base) const str = { +// Converts any [[types::floating]] to a string. The return value is statically +// allocated and will be overwritten on subsequent calls; see [[strings::dup]] +// to duplicate the result. If base is not specified, base 10 is used. +export fn floatingtos(n: types::floating, b: base = base::DEC) const str = { if (b == base::DEFAULT) { b = base::DEC; }; @@ -84,28 +69,18 @@ export fn floatingtosb(n: types::floating, b: base) const str = { }; }; -// Converts any [[types::floating]] to a string in base 10. The return value is -// statically allocated and will be overwritten on subsequent calls; see -// [[strings::dup]] to duplicate the result. -export fn floatingtos(n: types::floating) const str = floatingtosb(n, base::DEC); - -// Converts any [[types::numeric]] to a string in a given base. The return value -// is statically allocated and will be overwritten on subsequent calls; see -// [[strings::dup]] to duplicate the result. -export fn numerictosb(n: types::numeric, b: base) const str = { +// Converts any [[types::numeric]] to a string. The return value is statically +// allocated and will be overwritten on subsequent calls; see [[strings::dup]] +// to duplicate the result. If base is not specified, base 10 is used. +export fn numerictos(n: types::numeric, b: base = base::DEC) const str = { match (n) { case let i: types::integer => - return integertosb(i, b); + return integertos(i, b); case let f: types::floating => - return floatingtosb(f, b); + return floatingtos(f, b); }; }; -// Converts any [[types::numeric]] to a string in base 10. The return value is -// statically allocated and will be overwritten on subsequent calls; see -// [[strings::dup]] to duplicate the result. -export fn numerictos(n: types::numeric) const str = numerictosb(n, base::DEC); - @test fn numeric() void = { const cases: [_]types::numeric = [ 42u8, 1337u16, 1337u32, 1337u64, 42i8, -42i8, 1337i16, -1337i16, diff --git a/strconv/stof.ha b/strconv/stof.ha @@ -619,14 +619,15 @@ fn special(s: str) (f32 | void) = { }; }; -// Converts a string to a f64 in [[base::DEC]] or [[base::HEX]]. If the string -// is not a syntactically well-formed floating-point number, [[invalid]] is -// returned. If the string represents a floating-point number that is larger -// than the largest finite f64 number, [[overflow]] is returned. Zero is -// returned if the string represents a floating-point number that is smaller -// than the f64 number nearest to zero with respective sign. -// Recognizes "Infinity", "+Infinity", "-Infinity", and "NaN", case insensitive. -export fn stof64b(s: str, b: base) (f64 | invalid | overflow) = { +// Converts a string to a f64 in [[base::DEC]] or [[base::HEX]]. If base is not +// provided, [[base::DEC]] is used. If the string is not a syntactically +// well-formed floating-point number, [[invalid]] is returned. If the string +// represents a floating-point number that is larger than the largest finite +// f64 number, [[overflow]] is returned. Zero is returned if the string +// represents a floating-point number that is smaller than the f64 number +// nearest to zero with respective sign. Recognizes "Infinity", "+Infinity", +// "-Infinity", and "NaN", case insensitive. +export fn stof64(s: str, b: base = base::DEC) (f64 | invalid | overflow) = { if (b == base::DEFAULT) b = base::DEC; assert(b == base::DEC || b == base::HEX); @@ -660,14 +661,15 @@ export fn stof64b(s: str, b: base) (f64 | invalid | overflow) = { return math::f64frombits(n); }; -// Converts a string to a f32 in [[base::DEC]] or [[base::HEX]]. If the string -// is not a syntactically well-formed floating-point number, [[invalid]] is -// returned. If the string represents a floating-point number that is larger -// than the largest finite f32 number, [[overflow]] is returned. Zero is -// returned if the string represents a floating-point number that is smaller -// than the f32 number nearest to zero with respective sign. -// Recognizes "Infinity", "+Infinity", "-Infinity", and "NaN", case insensitive. -export fn stof32b(s: str, b: base) (f32 | invalid | overflow) = { +// Converts a string to a f32 in [[base::DEC]] or [[base::HEX]]. If base is not +// provided, [[base::DEC]] is used. If the string is not a syntactically +// well-formed floating-point number, [[invalid]] is returned. If the string +// represents a floating-point number that is larger than the largest finite +// f32 number, [[overflow]] is returned. Zero is returned if the string +// represents a floating-point number that is smaller than the f32 number +// nearest to zero with respective sign. Recognizes "Infinity", "+Infinity", +// "-Infinity", and "NaN", case insensitive. +export fn stof32(s: str, b: base = base::DEC) (f32 | invalid | overflow) = { if (b == base::DEFAULT) b = base::DEC; assert(b == base::DEC || b == base::HEX); @@ -702,24 +704,6 @@ export fn stof32b(s: str, b: base) (f32 | invalid | overflow) = { }; -// Converts a string to a f64. If the string is not a syntactically well-formed -// floating-point number in base 10, [[invalid]] is returned. If the string -// represents a floating-point number that is larger than the largest finite f64 -// number, [[overflow]] is returned. Zero is returned if the string represents a -// floating-point number that is smaller than the f64 number nearest to zero -// with respective sign. -// Recognizes "Infinity", "+Infinity", "-Infinity", and "NaN", case insensitive. -export fn stof64(s: str) (f64 | invalid | overflow) = stof64b(s, base::DEC); - -// Converts a string to a f32. If the string is not a syntactically well-formed -// floating-point number in base 10, [[invalid]] is returned. If the string -// represents a floating-point number that is larger than the largest finite f32 -// number, [[overflow]] is returned. Zero is returned if the string represents a -// floating-point number that is smaller than the f32 number nearest to zero -// with respective sign. -// Recognizes "Infinity", "+Infinity", "-Infinity", and "NaN", case insensitive. -export fn stof32(s: str) (f32 | invalid | overflow) = stof32b(s, base::DEC); - @test fn stof64() void = { assert(stof64("0"): f64 == 0.0); assert(stof64("200"): f64 == 200.0); @@ -781,27 +765,27 @@ export fn stof32(s: str) (f32 | invalid | overflow) = stof32b(s, base::DEC); }; @test fn stofhex() void = { - assert(stof64b("0p0", base::HEX)! == 0x0.0p0); - assert(stof64b("1p0", base::HEX)! == 0x1.0p0); - assert(stof64b("-1p0", base::HEX)! == -0x1.0p0); - assert(stof64b("1.fp-2", base::HEX)! == 0x1.fp-2); - assert(stof64b("1.fffffffffffffp+1023", base::HEX)! + assert(stof64("0p0", base::HEX)! == 0x0.0p0); + assert(stof64("1p0", base::HEX)! == 0x1.0p0); + assert(stof64("-1p0", base::HEX)! == -0x1.0p0); + assert(stof64("1.fp-2", base::HEX)! == 0x1.fp-2); + assert(stof64("1.fffffffffffffp+1023", base::HEX)! == math::F64_MAX_NORMAL); - assert(stof64b("1.0000000000000p-1022", base::HEX)! + assert(stof64("1.0000000000000p-1022", base::HEX)! == math::F64_MIN_NORMAL); - assert(stof64b("0.0000000000001p-1022", base::HEX)! + assert(stof64("0.0000000000001p-1022", base::HEX)! == math::F64_MIN); - assert(stof64b("1p+1024", base::HEX) is overflow); - assert(stof64b("0.00000000000001p-1022", base::HEX)! == 0.0); - - assert(stof32b("0p0", base::HEX)! == 0x0.0p0); - assert(stof32b("1p0", base::HEX)! == 0x1.0p0); - assert(stof32b("-1p0", base::HEX)! == -0x1.0p0); - assert(stof32b("1.fp-2", base::HEX)! == 0x1.fp-2); - assert(stof32b("1.fffffd586b834p+127", base::HEX)! + assert(stof64("1p+1024", base::HEX) is overflow); + assert(stof64("0.00000000000001p-1022", base::HEX)! == 0.0); + + assert(stof32("0p0", base::HEX)! == 0x0.0p0); + assert(stof32("1p0", base::HEX)! == 0x1.0p0); + assert(stof32("-1p0", base::HEX)! == -0x1.0p0); + assert(stof32("1.fp-2", base::HEX)! == 0x1.fp-2); + assert(stof32("1.fffffd586b834p+127", base::HEX)! == math::F32_MAX_NORMAL); - assert(stof32b("1.0p-126", base::HEX)! == math::F32_MIN_NORMAL); - assert(stof32b("1.6p-150", base::HEX)! == math::F32_MIN); - assert(stof32b("1.0p+128", base::HEX) is overflow); - assert(stof32b("1.0p-151", base::HEX)! == 0.0); + assert(stof32("1.0p-126", base::HEX)! == math::F32_MIN_NORMAL); + assert(stof32("1.6p-150", base::HEX)! == math::F32_MIN); + assert(stof32("1.0p+128", base::HEX) is overflow); + assert(stof32("1.0p-151", base::HEX)! == 0.0); }; diff --git a/strconv/stoi.ha b/strconv/stoi.ha @@ -4,10 +4,10 @@ use strings; use types; -// Converts a string to an i64 in the given base. Returns [[invalid]] if the -// string is empty or contains invalid characters. Returns [[overflow]] if the -// number is too large to be represented by an i64. -export fn stoi64b(s: str, base: base) (i64 | invalid | overflow) = { +// Converts a string to an i64. Returns [[invalid]] if the string is empty or +// contains invalid characters. Returns [[overflow]] if the number is too large +// to be represented by an i64. +export fn stoi64(s: str, base: base = base::DEC) (i64 | invalid | overflow) = { let (sign, u) = parseint(s, base)?; // Two's complement: I64_MIN = -I64_MAX - 1 let max = if (sign) types::I64_MAX: u64 + 1 else types::I64_MAX: u64; @@ -23,62 +23,37 @@ fn stoiminmax( min: i64, max: i64, ) (i64 | invalid | overflow) = { - const n = stoi64b(s, base)?; + const n = stoi64(s, base)?; if (n < min || n > max) { return overflow; }; return n; }; -// Converts a string to an i32 in the given base. Returns [[invalid]] if the -// string is empty or contains invalid characters. Returns [[overflow]] if the -// number is too large to be represented by an i32. -export fn stoi32b(s: str, base: base) (i32 | invalid | overflow) = +// Converts a string to an i32. Returns [[invalid]] if the string is empty or +// contains invalid characters. Returns [[overflow]] if the number is too large +// to be represented by an i32. +export fn stoi32(s: str, base: base = base::DEC) (i32 | invalid | overflow) = stoiminmax(s, base, types::I32_MIN, types::I32_MAX)?: i32; -// Converts a string to an i16 in the given base. Returns [[invalid]] if the -// string is empty or contains invalid characters. Returns [[overflow]] if the -// number is too large to be represented by an i16. -export fn stoi16b(s: str, base: base) (i16 | invalid | overflow) = +// Converts a string to an i16. Returns [[invalid]] if the string is empty or +// contains invalid characters. Returns [[overflow]] if the number is too large +// to be represented by an i16. +export fn stoi16(s: str, base: base = base::DEC) (i16 | invalid | overflow) = stoiminmax(s, base, types::I16_MIN, types::I16_MAX)?: i16; -// Converts a string to an i8 in the given base. Returns [[invalid]] if the -// string is empty or contains invalid characters. Returns [[overflow]] if the -// number is too large to be represented by an i8. -export fn stoi8b(s: str, base: base) (i8 | invalid | overflow) = +// Converts a string to an i8. Returns [[invalid]] if the string is empty or +// contains invalid characters. Returns [[overflow]] if the number is too large +// to be represented by an i8. +export fn stoi8(s: str, base: base = base::DEC) (i8 | invalid | overflow) = stoiminmax(s, base, types::I8_MIN, types::I8_MAX)?: i8; -// Converts a string to an int in the given base. Returns [[invalid]] if the -// string is empty or contains invalid characters. Returns [[overflow]] if the -// number is too large to be represented by an int. -export fn stoib(s: str, base: base) (int | invalid | overflow) = +// Converts a string to an int. Returns [[invalid]] if the string is empty or +// contains invalid characters. Returns [[overflow]] if the number is too large +// to be represented by an int. +export fn stoi(s: str, base: base = base::DEC) (int | invalid | overflow) = stoiminmax(s, base, types::INT_MIN, types::INT_MAX)?: int; -// Converts a string to an i64 in base 10. Returns [[invalid]] if the string is -// empty or contains invalid characters. Returns [[overflow]] if the number is -// too large to be represented by an i64. -export fn stoi64(s: str) (i64 | invalid | overflow) = stoi64b(s, base::DEC); - -// Converts a string to an i32 in base 10. Returns [[invalid]] if the string is -// empty or contains invalid characters. Returns [[overflow]] if the number is -// too large to be represented by an i32. -export fn stoi32(s: str) (i32 | invalid | overflow) = stoi32b(s, base::DEC); - -// Converts a string to an i16 in base 10. Returns [[invalid]] if the string is -// empty or contains invalid characters. Returns [[overflow]] if the number is -// too large to be represented by an i16. -export fn stoi16(s: str) (i16 | invalid | overflow) = stoi16b(s, base::DEC); - -// Converts a string to an i8 in base 10. Returns [[invalid]] if the string is -// empty or contains invalid characters. Returns [[overflow]] if the number is -// too large to be represented by an i8. -export fn stoi8(s: str) (i8 | invalid | overflow) = stoi8b(s, base::DEC); - -// Converts a string to an int in base 10. Returns [[invalid]] if the string is -// empty or contains invalid characters. Returns [[overflow]] if the number is -// too large to be represented by an int. -export fn stoi(s: str) (int | invalid | overflow) = stoib(s, base::DEC); - @test fn stoi() void = { assert(stoi64("") as invalid == 0); assert(stoi64("abc") as invalid == 0); @@ -104,9 +79,9 @@ export fn stoi(s: str) (int | invalid | overflow) = stoib(s, base::DEC); assert(stoi32("-2147483648") as i32 == -2147483648); }; -@test fn stoib() void = { - assert(stoi64b("-7f", 16) as i64 == -0x7f); - assert(stoi64b("7F", 16) as i64 == 0x7f); - assert(stoi64b("37", 8) as i64 == 0o37); - assert(stoi64b("-110101", 2) as i64 == -0b110101); +@test fn stoi_bases() void = { + assert(stoi64("-7f", 16) as i64 == -0x7f); + assert(stoi64("7F", 16) as i64 == 0x7f); + assert(stoi64("37", 8) as i64 == 0o37); + assert(stoi64("-110101", 2) as i64 == -0b110101); }; diff --git a/strconv/stou.ha b/strconv/stou.ha @@ -63,10 +63,10 @@ fn parseint(s: str, base: base) ((bool, u64) | invalid | overflow) = { return (sign, n); }; -// Converts a string to a u64 in the given base. Returns [[invalid]] if the -// string is empty or contains invalid characters. Returns [[overflow]] if the -// number is too large to be represented by a u64. -export fn stou64b(s: str, base: base) (u64 | invalid | overflow) = { +// Converts a string to a u64. Returns [[invalid]] if the string is empty or +// contains invalid characters. Returns [[overflow]] if the number is too large +// to be represented by a u64. +export fn stou64(s: str, base: base = base::DEC) (u64 | invalid | overflow) = { let (sign, u) = parseint(s, base)?; if (sign) { return overflow; @@ -75,73 +75,43 @@ export fn stou64b(s: str, base: base) (u64 | invalid | overflow) = { }; fn stoumax(s: str, base: base, max: u64) (u64 | invalid | overflow) = { - const n = stou64b(s, base)?; + const n = stou64(s, base)?; if (n > max) { return overflow; }; return n; }; -// Converts a string to a u32 in the given base. Returns [[invalid]] if the -// string is empty or contains invalid characters. Returns [[overflow]] if the -// number is too large to be represented by a u32. -export fn stou32b(s: str, base: base) (u32 | invalid | overflow) = +// Converts a string to a u32. Returns [[invalid]] if the string is empty or +// contains invalid characters. Returns [[overflow]] if the number is too large +// to be represented by a u32. +export fn stou32(s: str, base: base = base::DEC) (u32 | invalid | overflow) = stoumax(s, base, types::U32_MAX)?: u32; -// Converts a string to a u16 in the given base. Returns [[invalid]] if the -// string is empty or contains invalid characters. Returns [[overflow]] if the -// number is too large to be represented by a u16. -export fn stou16b(s: str, base: base) (u16 | invalid | overflow) = +// Converts a string to a u16. Returns [[invalid]] if the string is empty or +// contains invalid characters. Returns [[overflow]] if the number is too large +// to be represented by a u16. +export fn stou16(s: str, base: base = base::DEC) (u16 | invalid | overflow) = stoumax(s, base, types::U16_MAX)?: u16; -// Converts a string to a u8 in the given base. Returns [[invalid]] if the -// string is empty or contains invalid characters. Returns [[overflow]] if the -// number is too large to be represented by a u8. -export fn stou8b(s: str, base: base) (u8 | invalid | overflow) = +// Converts a string to a u8. Returns [[invalid]] if the string is empty or +// contains invalid characters. Returns [[overflow]] if the number is too large +// to be represented by a u8. +export fn stou8(s: str, base: base = base::DEC) (u8 | invalid | overflow) = stoumax(s, base, types::U8_MAX)?: u8; // Converts a string to a uint in the given base. Returns [[invalid]] if the // string is empty or contains invalid characters. Returns [[overflow]] if the // number is too large to be represented by a uint. -export fn stoub(s: str, base: base) (uint | invalid | overflow) = +export fn stou(s: str, base: base = base::DEC) (uint | invalid | overflow) = stoumax(s, base, types::UINT_MAX)?: uint; -// Converts a string to a size in the given base. Returns [[invalid]] if the -// string is empty or contains invalid characters. Returns [[overflow]] if the -// number is too large to be represented by a size. -export fn stozb(s: str, base: base) (size | invalid | overflow) = +// Converts a string to a size. Returns [[invalid]] if the string is empty or +// contains invalid characters. Returns [[overflow]] if the number is too large +// to be represented by a size. +export fn stoz(s: str, base: base = base::DEC) (size | invalid | overflow) = stoumax(s, base, types::SIZE_MAX)?: size; -// Converts a string to a u64 in base 10. Returns [[invalid]] if the string is -// empty or contains invalid characters. Returns [[overflow]] if the number is -// too large to be represented by a u64. -export fn stou64(s: str) (u64 | invalid | overflow) = stou64b(s, base::DEC); - -// Converts a string to a u32 in base 10. Returns [[invalid]] if the string is -// empty or contains invalid characters. Returns [[overflow]] if the number is -// too large to be represented by a u32. -export fn stou32(s: str) (u32 | invalid | overflow) = stou32b(s, base::DEC); - -// Converts a string to a u16 in base 10. Returns [[invalid]] if the string is -// empty or contains invalid characters. Returns [[overflow]] if the number is -// too large to be represented by a u16. -export fn stou16(s: str) (u16 | invalid | overflow) = stou16b(s, base::DEC); - -// Converts a string to a u8 in base 10. Returns [[invalid]] if the string is -// empty or contains invalid characters. Returns [[overflow]] if the number is -// too large to be represented by a u8. -export fn stou8(s: str) (u8 | invalid | overflow) = stou8b(s, base::DEC); - -// Converts a string to a uint in base 10. Returns [[invalid]] if the string is -// empty or contains invalid characters. Returns [[overflow]] if the number is -// too large to be represented by a uint. -export fn stou(s: str) (uint | invalid | overflow) = stoub(s, base::DEC); - -// Converts a string to a size in base 10. Returns [[invalid]] if the string is -// empty or contains invalid characters. Returns [[overflow]] if the number is -// too large to be represented by a size. -export fn stoz(s: str) (size | invalid | overflow) = stozb(s, base::DEC); - @test fn stou() void = { assert(stou64("") as invalid == 0); assert(stou64("+") as invalid == 1); @@ -158,9 +128,9 @@ export fn stoz(s: str) (size | invalid | overflow) = stozb(s, base::DEC); assert(stou64("18446744073709551615") as u64 == 18446744073709551615); }; -@test fn stoub() void = { - assert(stou64b("7f", 16) as u64 == 0x7f); - assert(stou64b("7F", 16) as u64 == 0x7f); - assert(stou64b("37", 8) as u64 == 0o37); - assert(stou64b("110101", 2) as u64 == 0b110101); +@test fn stou_bases() void = { + assert(stou64("7f", 16) as u64 == 0x7f); + assert(stou64("7F", 16) as u64 == 0x7f); + assert(stou64("37", 8) as u64 == 0o37); + assert(stou64("110101", 2) as u64 == 0b110101); }; diff --git a/strconv/utos.ha b/strconv/utos.ha @@ -4,10 +4,10 @@ use bytes; use types; -// Converts a u64 to a string in the given base. The return value is statically -// allocated and will be overwritten on subsequent calls; see [[strings::dup]] to -// duplicate the result. -export fn u64tosb(u: u64, b: base) const str = { +// Converts a u64 to a string. The return value is statically allocated and will +// be overwritten on subsequent calls; see [[strings::dup]] to duplicate the +// result. +export fn u64tos(u: u64, b: base = base::DEC) const str = { static assert(types::U64_MAX == 18446744073709551615); static let buf: [64]u8 = [0...]; // 64 binary digits @@ -41,80 +41,45 @@ export fn u64tosb(u: u64, b: base) const str = { return *(&s: *str); }; -// Converts a u32 to a string in the given base. The return value is statically -// allocated and will be overwritten on subsequent calls; see [[strings::dup]] to -// duplicate the result. -export fn u32tosb(u: u32, b: base) const str = u64tosb(u, b); - -// Converts a u16 to a string in the given base. The return value is statically -// allocated and will be overwritten on subsequent calls; see [[strings::dup]] to -// duplicate the result. -export fn u16tosb(u: u16, b: base) const str = u64tosb(u, b); - -// Converts a u8 to a string in the given base. The return value is statically -// allocated and will be overwritten on subsequent calls; see [[strings::dup]] to -// duplicate the result. -export fn u8tosb(u: u8, b: base) const str = u64tosb(u, b); - -// Converts a uint to a string in the given base. The return value is -// statically allocated and will be overwritten on subsequent calls; see -// [[strings::dup]] to duplicate the result. -export fn utosb(u: uint, b: base) const str = u64tosb(u, b); - -// Converts a size to a string in the given base. The return value is -// statically allocated and will be overwritten on subsequent calls; see -// [[strings::dup]] to duplicate the result. -export fn ztosb(u: size, b: base) const str = u64tosb(u, b); - -// Converts a uintptr to a string in the given base. The return value is -// statically allocated and will be overwritten on subsequent calls; see -// [[strings::dup]] to duplicate the result. -export fn uptrtosb(uptr: uintptr, b: base) const str = u64tosb(uptr: u64, b); - -// Converts a u64 to a string in base 10. The return value is statically -// allocated and will be overwritten on subsequent calls; see [[strings::dup]] to -// duplicate the result. -export fn u64tos(u: u64) const str = u64tosb(u, base::DEC); - -// Converts a u32 to a string in base 10. The return value is statically -// allocated and will be overwritten on subsequent calls; see [[strings::dup]] to -// duplicate the result. -export fn u32tos(u: u32) const str = u64tos(u); - -// Converts a u16 to a string in base 10. The return value is statically -// allocated and will be overwritten on subsequent calls; see [[strings::dup]] to -// duplicate the result. -export fn u16tos(u: u16) const str = u64tos(u); - -// Converts a u8 to a string in base 10. The return value is statically -// allocated and will be overwritten on subsequent calls; see [[strings::dup]] to -// duplicate the result. -export fn u8tos(u: u8) const str = u64tos(u); - -// Converts a uint to a string in base 10. The return value is statically -// allocated and will be overwritten on subsequent calls; see [[strings::dup]] to -// duplicate the result. -export fn utos(u: uint) const str = u64tos(u); - -// Converts a size to a string in base 10. The return value is statically -// allocated and will be overwritten on subsequent calls; see [[strings::dup]] to -// duplicate the result. -export fn ztos(z: size) const str = u64tos(z); - -// Converts a uintptr to a string in base 10. The return value is statically -// allocated and will be overwritten on subsequent calls; see [[strings::dup]] to -// duplicate the result. -export fn uptrtos(uptr: uintptr) const str = u64tos(uptr: u64); - -@test fn utosb() void = { - assert("11010" == u64tosb(0b11010, base::BIN)); - assert("1234567" == u64tosb(0o1234567, base::OCT)); - assert("123456789" == u64tosb(123456789, base::DEC)); - assert("123456789ABCDEF" == u64tosb(0x123456789ABCDEF, base::HEX)); - assert("123456789ABCDEF" == u64tosb(0x123456789ABCDEF, base::HEX_UPPER)); - assert("123456789abcdef" == u64tosb(0x123456789ABCDEF, base::HEX_LOWER)); +// Converts a u32 to a string. The return value is statically allocated and will +// be overwritten on subsequent calls; see [[strings::dup]] to duplicate the +// result. +export fn u32tos(u: u32, b: base = base::DEC) const str = u64tos(u, b); + +// Converts a u16 to a string. The return value is statically allocated and will +// be overwritten on subsequent calls; see [[strings::dup]] to duplicate the +// result. +export fn u16tos(u: u16, b: base = base::DEC) const str = u64tos(u, b); + +// Converts a u8 to a string. The return value is statically allocated and will +// be overwritten on subsequent calls; see [[strings::dup]] to duplicate the +// result. +export fn u8tos(u: u8, b: base = base::DEC) const str = u64tos(u, b); + +// Converts a uint to a string. The return value is statically allocated and +// will be overwritten on subsequent calls; see [[strings::dup]] to duplicate +// the result. +export fn utos(u: uint, b: base = base::DEC) const str = u64tos(u, b); + +// Converts a size to a string. The return value is statically allocated and +// will be overwritten on subsequent calls; see [[strings::dup]] to duplicate +// the result. +export fn ztos(u: size, b: base = base::DEC) const str = u64tos(u, b); + +// Converts a uintptr to a string. The return value is statically allocated and +// will be overwritten on subsequent calls; see [[strings::dup]] to duplicate +// the result. +export fn uptrtos(uptr: uintptr, b: base = base::DEC) const str = u64tos(uptr: u64, b); + +@test fn utos_bases() void = { + assert("11010" == u64tos(0b11010, base::BIN)); + assert("1234567" == u64tos(0o1234567, base::OCT)); + assert("123456789" == u64tos(123456789, base::DEC)); + assert("123456789ABCDEF" == u64tos(0x123456789ABCDEF, base::HEX)); + assert("123456789ABCDEF" == u64tos(0x123456789ABCDEF, base::HEX_UPPER)); + assert("123456789abcdef" == u64tos(0x123456789ABCDEF, base::HEX_LOWER)); assert("1111111111111111111111111111111111111111111111111111111111111111" - == u64tosb(types::U64_MAX, base::BIN)); + == u64tos(types::U64_MAX, base::BIN)); }; @test fn utos() void = { diff --git a/uuid/uuid.ha b/uuid/uuid.ha @@ -115,7 +115,7 @@ export fn decode(in: io::handle) (uuid | invalid | io::error) = { return invalid; case let z: size => void; }; - u[i] = match (strconv::stou8b( + u[i] = match (strconv::stou8( strings::fromutf8_unsafe(buf), strconv::base::HEX)) { case strconv::overflow =>