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:
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);