hare

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

commit ddd37553a0f56d3c568395bc63cb7ab356fab7c1
parent 72df240ff37e7e6aca7d43c712dc6391c9351cf8
Author: Eyal Sawady <ecs@d2evs.net>
Date:   Wed, 14 Apr 2021 13:25:53 -0400

strconv: add stoi*b

Diffstat:
Mstrconv/+test/stoi.ha | 7+++++++
Mstrconv/stoi.ha | 64+++++++++++++++++++++++++++++++++++++++++++++++-----------------
2 files changed, 54 insertions(+), 17 deletions(-)

diff --git a/strconv/+test/stoi.ha b/strconv/+test/stoi.ha @@ -18,3 +18,10 @@ assert(stoi32("2147483647") as i32 == 2147483647); 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); +}; diff --git a/strconv/stoi.ha b/strconv/stoi.ha @@ -1,11 +1,11 @@ use types; use strings; -// Converts a string to an i64 in base 10. If the string contains any +// Converts a string to an i64 in the given base. If the string contains any // non-numeric characters, except '-' at the start, or if it's empty, // [strconv::invalid] is returned. If the number is too large to be represented // by an i64, [strconv::overflow] is returned. -export fn stoi64(s: str) (i64 | invalid | overflow) = { +export fn stoi64b(s: str, base: uint) (i64 | invalid | overflow) = { if (len(s) == 0) return 0: invalid; let b = strings::toutf8(s); let sign = 1i64; @@ -14,8 +14,8 @@ export fn stoi64(s: str) (i64 | invalid | overflow) = { sign = -1; max += 1; }; - let u = if (sign < 0) stou64(strings::fromutf8_unsafe(b[1..])) - else stou64(s); + let u = if (sign < 0) stou64b(strings::fromutf8_unsafe(b[1..]), base) + else stou64b(s, base); let n = u?; if (n > max) { return overflow; @@ -23,49 +23,79 @@ export fn stoi64(s: str) (i64 | invalid | overflow) = { return n: i64 * sign; }; -// Converts a string to an i32 in base 10. If the string contains any +// Converts a string to an i32 in the given base. If the string contains any // non-numeric characters, except '-' at the start, or if it's empty, // [strconv::invalid] is returned. If the number is too large to be represented // by an i32, [strconv::overflow] is returned. -export fn stoi32(s: str) (i32 | invalid | overflow) = { - let n = stoi64(s)?; +export fn stoi32b(s: str, base: uint) (i32 | invalid | overflow) = { + let n = stoi64b(s, base)?; if (n >= types::I32_MIN: i64 && n <= types::I32_MAX: i64) { return n: i32; }; return overflow; }; -// Converts a string to an i16 in base 10. If the string contains any +// Converts a string to an i16 in the given base. If the string contains any // non-numeric characters, except '-' at the start, or if it's empty, // [strconv::invalid] is returned. If the number is too large to be represented // by an i16, [strconv::overflow] is returned. -export fn stoi16(s: str) (i16 | invalid | overflow) = { - let n = stoi64(s)?; +export fn stoi16b(s: str, base: uint) (i16 | invalid | overflow) = { + let n = stoi64b(s, base)?; if (n >= types::I16_MIN: i64 && n <= types::I16_MAX: i64) { return n: i16; }; return overflow; }; -// Converts a string to an i8 in base 10. If the string contains any +// Converts a string to an i8 in the given base. If the string contains any // non-numeric characters, except '-' at the start, or if it's empty, // [strconv::invalid] is returned. If the number is too large to be represented // by an i8, [strconv::overflow] is returned. -export fn stoi8(s: str) (i8 | invalid | overflow) = { - let n= stoi64(s)?; +export fn stoi8b(s: str, base: uint) (i8 | invalid | overflow) = { + let n= stoi64b(s, base)?; if (n >= types::I8_MIN: i64 && n <= types::I8_MAX: i64) { return n: i8; }; return overflow; }; -// Converts a string to an int in base 10. If the string contains any +// Converts a string to an int in the given base. If the string contains any // non-numeric characters, except '-' at the start, or if it's empty, // [strconv::invalid] is returned. If the number is too large to be represented // by an int, [strconv::overflow] is returned. -export fn stoi(s: str) (int | invalid | overflow) = { +export fn stoib(s: str, base: uint) (int | invalid | overflow) = { static assert(size(int) == size(i32) || size(int) == size(i64)); return - if (size(int) == size(i32)) stoi32(s)?: int - else stoi64(s)?: int; + if (size(int) == size(i32)) stoi32b(s, base)?: int + else stoi64b(s, base)?: int; }; + +// Converts a string to an i64 in base 10, If the string contains any +// non-numeric characters, or if it's empty, [strconv::invalid] is returned. If +// the number is too large to be represented by a u64, [strconv::overflow] is +// returned. +export fn stoi64(s: str) (i64 | invalid | overflow) = stoi64b(s, 10); + +// Converts a string to an i32 in base 10, If the string contains any +// non-numeric characters, or if it's empty, [strconv::invalid] is returned. If +// the number is too large to be represented by a u32, [strconv::overflow] is +// returned. +export fn stoi32(s: str) (i32 | invalid | overflow) = stoi32b(s, 10); + +// Converts a string to an i16 in base 10, If the string contains any +// non-numeric characters, or if it's empty, [strconv::invalid] is returned. If +// the number is too large to be represented by a u16, [strconv::overflow] is +// returned. +export fn stoi16(s: str) (i16 | invalid | overflow) = stoi16b(s, 10); + +// Converts a string to an i8 in base 10, If the string contains any +// non-numeric characters, or if it's empty, [strconv::invalid] is returned. If +// the number is too large to be represented by a u8, [strconv::overflow] is +// returned. +export fn stoi8(s: str) (i8 | invalid | overflow) = stoi8b(s, 10); + +// Converts a string to an int in base 10, If the string contains any +// non-numeric characters, or if it's empty, [strconv::invalid] is returned. If +// the number is too large to be represented by a uint, [strconv::overflow] is +// returned. +export fn stoi(s: str) (int | invalid | overflow) = stoib(s, 10);