hare

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

commit 6f9b6114b7f61041823924dfcfea6fa05907b985
parent cd735b6bc01ca06f6a9878fa102c9ad8cc77de16
Author: Alexey Yerin <yyp@disroot.org>
Date:   Fri,  2 Jun 2023 20:35:48 +0300

Correctly convert strconv::base::DEC -> 10

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

Diffstat:
Mhare/lex/lex.ha | 25++++++++++++++-----------
Mstrconv/itos.ha | 4++++
Mstrconv/stoi.ha | 13++++++++-----
Mstrconv/stou.ha | 33+++++++++++++++------------------
4 files changed, 41 insertions(+), 34 deletions(-)

diff --git a/hare/lex/lex.ha b/hare/lex/lex.ha @@ -410,7 +410,7 @@ fn lex_literal(lex: *lexer) (token | error) = { }; let started = false; - let base = 10u; + let base = strconv::base::DEC; if (r.0 == '0') { append(chars, utf8::encoderune(r.0)...); r = match (next(lex)?) { @@ -421,11 +421,11 @@ fn lex_literal(lex: *lexer) (token | error) = { }; switch (r.0) { case 'b' => - base = 2; + base = strconv::base::BIN; case 'o' => - base = 8; + base = strconv::base::OCT; case 'x' => - base = 16; + base = strconv::base::HEX; case => if (ascii::isdigit(r.0)) { return syntaxerr(loc, @@ -436,13 +436,13 @@ fn lex_literal(lex: *lexer) (token | error) = { }; } else unget(lex, r); let basechrs = switch (base) { - case 2 => + case strconv::base::BIN => yield "01"; - case 8 => + case strconv::base::OCT => yield "01234567"; - case 10 => + case strconv::base::DEC => yield "0123456789"; - case 16 => + case strconv::base::HEX => yield "0123456789ABCDEFabcdef"; }; @@ -464,7 +464,8 @@ fn lex_literal(lex: *lexer) (token | error) = { "Expected integer literal"); }; if (float || exp is size || suff is size - || base != 10 || lex.require_int) { + || base != strconv::base::DEC + || lex.require_int) { unget(lex, r); break; } else { @@ -492,7 +493,8 @@ fn lex_literal(lex: *lexer) (token | error) = { return syntaxerr(loc, "Expected integer literal"); }; - if (exp is size || suff is size || base != 10) { + if (exp is size || suff is size + || base != strconv::base::DEC) { unget(lex, r); break; } else { @@ -519,7 +521,8 @@ fn lex_literal(lex: *lexer) (token | error) = { "Expected integer literal"); }; if (suff is size || r.0 != 'f' && float - || r.0 == 'f' && base != 10) { + || r.0 == 'f' + && base != strconv::base::DEC) { unget(lex, r); break; } else { diff --git a/strconv/itos.ha b/strconv/itos.ha @@ -11,6 +11,10 @@ use strings; // duplicate the result. export fn i64tosb(i: i64, b: base) const str = { static assert(types::I64_MAX == 9223372036854775807); + if (b == base::DEC) { + b = 10; + }; + if (i >= 0) return u64tosb(i: u64, b); static let buf: [65]u8 = [0...]; // 64 binary digits plus - diff --git a/strconv/stoi.ha b/strconv/stoi.ha @@ -10,7 +10,7 @@ use strings; // non-numeric characters, except '-' or '+' at the start, or if it's empty, // [[invalid]] is returned. If the number is too large to be represented by an // i64, [[overflow]] is returned. -export fn stoi64b(s: str, base: uint) (i64 | invalid | overflow) = { +export fn stoi64b(s: str, base: base) (i64 | invalid | overflow) = { if (len(s) == 0) return 0: invalid; let b = strings::toutf8(s); let sign = 1i64; @@ -23,6 +23,9 @@ export fn stoi64b(s: str, base: uint) (i64 | invalid | overflow) = { } else if (b[0] == '+') { start = 1; }; + if (base == base::DEC) { + base = 10; + }; let u = stou64b(strings::fromutf8_unsafe(b[start..]), base); let n = u?; if (n > max) { @@ -35,7 +38,7 @@ export fn stoi64b(s: str, base: uint) (i64 | invalid | overflow) = { // non-numeric characters, except '-' or '+' at the start, or if it's empty, // [[invalid]] is returned. If the number is too large to be represented by an // i32, [[overflow]] is returned. -export fn stoi32b(s: str, base: uint) (i32 | invalid | overflow) = { +export fn stoi32b(s: str, base: base) (i32 | invalid | overflow) = { let n = stoi64b(s, base)?; if (n >= types::I32_MIN: i64 && n <= types::I32_MAX: i64) { return n: i32; @@ -47,7 +50,7 @@ export fn stoi32b(s: str, base: uint) (i32 | invalid | overflow) = { // non-numeric characters, except '-' or '+' at the start, or if it's empty, // [[invalid]] is returned. If the number is too large to be represented by an // i16, [[overflow]] is returned. -export fn stoi16b(s: str, base: uint) (i16 | invalid | overflow) = { +export fn stoi16b(s: str, base: base) (i16 | invalid | overflow) = { let n = stoi64b(s, base)?; if (n >= types::I16_MIN: i64 && n <= types::I16_MAX: i64) { return n: i16; @@ -59,7 +62,7 @@ export fn stoi16b(s: str, base: uint) (i16 | invalid | overflow) = { // non-numeric characters, except '-' or '+' at the start, or if it's empty, // [[invalid]] is returned. If the number is too large to be represented by an // i8, [[overflow]] is returned. -export fn stoi8b(s: str, base: uint) (i8 | invalid | overflow) = { +export fn stoi8b(s: str, base: base) (i8 | invalid | overflow) = { let n= stoi64b(s, base)?; if (n >= types::I8_MIN: i64 && n <= types::I8_MAX: i64) { return n: i8; @@ -71,7 +74,7 @@ export fn stoi8b(s: str, base: uint) (i8 | invalid | overflow) = { // non-numeric characters, except '-' or '+' at the start, or if it's empty, // [[invalid]] is returned. If the number is too large to be represented by an // int, [[overflow]] is returned. -export fn stoib(s: str, base: uint) (int | invalid | overflow) = { +export fn stoib(s: str, base: base) (int | invalid | overflow) = { static assert(size(int) == size(i32) || size(int) == size(i64)); return if (size(int) == size(i32)) stoi32b(s, base)?: int diff --git a/strconv/stou.ha b/strconv/stou.ha @@ -19,8 +19,10 @@ fn rune_to_integer(r: rune) (u64 | void) = { // Converts a string to a u64 in the given base, If the string contains any // non-numeric characters, or if it's empty, [[invalid]] is returned. If the // number is too large to be represented by a u64, [[overflow]] is returned. -// Supported bases are 2, 8, 10 and 16. -export fn stou64b(s: str, base: uint) (u64 | invalid | overflow) = { +export fn stou64b(s: str, base: base) (u64 | invalid | overflow) = { + if (base == base::DEC) { + base = 10; + }; assert(base == 2 || base == 8 || base == 10 || base == 16); if (len(s) == 0) { @@ -63,8 +65,7 @@ export fn stou64b(s: str, base: uint) (u64 | invalid | overflow) = { // Converts a string to a u32 in the given base, If the string contains any // non-numeric characters, or if it's empty, [[invalid]] is returned. If the // number is too large to be represented by a u32, [[overflow]] is returned. -// Supported bases are 2, 8, 10 and 16. -export fn stou32b(s: str, base: uint) (u32 | invalid | overflow) = { +export fn stou32b(s: str, base: base) (u32 | invalid | overflow) = { let n = stou64b(s, base)?; if (n <= types::U32_MAX: u64) { return n: u32; @@ -75,8 +76,7 @@ export fn stou32b(s: str, base: uint) (u32 | invalid | overflow) = { // Converts a string to a u16 in the given base, If the string contains any // non-numeric characters, or if it's empty, [[invalid]] is returned. If the // number is too large to be represented by a u16, [[overflow]] is returned. -// Supported bases are 2, 8, 10 and 16. -export fn stou16b(s: str, base: uint) (u16 | invalid | overflow) = { +export fn stou16b(s: str, base: base) (u16 | invalid | overflow) = { let n = stou64b(s, base)?; if (n <= types::U16_MAX: u64) { return n: u16; @@ -87,8 +87,7 @@ export fn stou16b(s: str, base: uint) (u16 | invalid | overflow) = { // Converts a string to a u8 in the given base, If the string contains any // non-numeric characters, or if it's empty, [[invalid]] is returned. If the // number is too large to be represented by a u8, [[overflow]] is returned. -// Supported bases are 2, 8, 10 and 16. -export fn stou8b(s: str, base: uint) (u8 | invalid | overflow) = { +export fn stou8b(s: str, base: base) (u8 | invalid | overflow) = { let n = stou64b(s, base)?; if (n <= types::U8_MAX: u64) { return n: u8; @@ -99,8 +98,7 @@ export fn stou8b(s: str, base: uint) (u8 | invalid | overflow) = { // Converts a string to a uint in the given base, If the string contains any // non-numeric characters, or if it's empty, [[invalid]] is returned. If the // number is too large to be represented by a uint, [[overflow]] is returned. -// Supported bases are 2, 8, 10 and 16. -export fn stoub(s: str, base: uint) (uint | invalid | overflow) = { +export fn stoub(s: str, base: base) (uint | invalid | overflow) = { static assert(size(uint) == size(u32) || size(uint) == size(u64)); return if (size(uint) == size(u32)) stou32b(s, base)?: uint @@ -110,8 +108,7 @@ export fn stoub(s: str, base: uint) (uint | invalid | overflow) = { // Converts a string to a size in the given base, If the string contains any // non-numeric characters, or if it's empty, [[invalid]] is returned. If the // number is too large to be represented by a size, [[overflow]] is returned. -// Supported bases are 2, 8, 10 and 16. -export fn stozb(s: str, base: uint) (size | invalid | overflow) = { +export fn stozb(s: str, base: base) (size | invalid | overflow) = { static assert(size(size) == size(u32) || size(size) == size(u64)); if (size(size) == size(u32)) { match (stou32b(s, base)) { @@ -133,29 +130,29 @@ export fn stozb(s: str, base: uint) (size | invalid | overflow) = { // Converts a string to a u64 in base 10, If the string contains any // non-numeric characters, or if it's empty, [[invalid]] is returned. If the // number is too large to be represented by a u64, [[overflow]] is returned. -export fn stou64(s: str) (u64 | invalid | overflow) = stou64b(s, 10); +export fn stou64(s: str) (u64 | invalid | overflow) = stou64b(s, base::DEC); // Converts a string to a u32 in base 10, If the string contains any // non-numeric characters, or if it's empty, [[invalid]] is returned. If the // number is too large to be represented by a u32, [[overflow]] is returned. -export fn stou32(s: str) (u32 | invalid | overflow) = stou32b(s, 10); +export fn stou32(s: str) (u32 | invalid | overflow) = stou32b(s, base::DEC); // Converts a string to a u16 in base 10, If the string contains any // non-numeric characters, or if it's empty, [[invalid]] is returned. If the // number is too large to be represented by a u16, [[overflow]] is returned. -export fn stou16(s: str) (u16 | invalid | overflow) = stou16b(s, 10); +export fn stou16(s: str) (u16 | invalid | overflow) = stou16b(s, base::DEC); // Converts a string to a u8 in base 10, If the string contains any // non-numeric characters, or if it's empty, [[invalid]] is returned. If the // number is too large to be represented by a u8, [[overflow]] is returned. -export fn stou8(s: str) (u8 | invalid | overflow) = stou8b(s, 10); +export fn stou8(s: str) (u8 | invalid | overflow) = stou8b(s, base::DEC); // Converts a string to a uint in base 10, If the string contains any // non-numeric characters, or if it's empty, [[invalid]] is returned. If the // number is too large to be represented by a uint, [[overflow]] is returned. -export fn stou(s: str) (uint | invalid | overflow) = stoub(s, 10); +export fn stou(s: str) (uint | invalid | overflow) = stoub(s, base::DEC); // Converts a string to a size in base 10, If the string contains any // non-numeric characters, or if it's empty, [[invalid]] is returned. If the // number is too large to be represented by a size, [[overflow]] is returned. -export fn stoz(s: str) (size | invalid | overflow) = stozb(s, 10); +export fn stoz(s: str) (size | invalid | overflow) = stozb(s, base::DEC);