commit 1e369813f4a7d3e0a43c7c9cd6007918bfc23425
parent b973201ced3b33705b90e07a0f4a45276655a655
Author: Eyal Sawady <ecs@d2evs.net>
Date: Wed, 17 Mar 2021 14:17:37 -0400
strconv::*tos: return index of first nondigit
Also rework strconv+test::*tos to use type assertions/tests
Diffstat:
5 files changed, 36 insertions(+), 91 deletions(-)
diff --git a/strconv/+test/stoi.ha b/strconv/+test/stoi.ha
@@ -1,55 +1,20 @@
-fn is_invalid_i64(value: (i64 | invalid | overflow)) bool = {
- return match (value) {
- invalid => true,
- * => false,
- };
-};
-
-fn is_overflow_i64(value: (i64 | invalid | overflow)) bool = {
- return match (value) {
- overflow => true,
- * => false,
- };
-};
-
-fn is_number_i64(n: i64, value: (i64 | invalid | overflow)) bool = {
- return match (value) {
- v: i64 => v == n,
- * => false,
- };
-};
-
-fn is_overflow_i32(value: (i32 | invalid | overflow)) bool = {
- return match (value) {
- overflow => true,
- * => false,
- };
-};
-
-fn is_number_i32(n: i32, value: (i32 | invalid | overflow)) bool = {
- return match (value) {
- v: i32 => v == n,
- * => false,
- };
-};
-
@test fn stoi() void = {
- assert(is_invalid_i64(stoi64("")));
- assert(is_invalid_i64(stoi64("abc")));
- assert(is_invalid_i64(stoi64("1a")));
+ assert(stoi64("") as invalid == 0: strconv::invalid);
+ assert(stoi64("abc") as invalid == 0: strconv::invalid);
+ assert(stoi64("1a") as invalid == 1: strconv::invalid);
- assert(is_overflow_i64(stoi64("9223372036854775808")));
- assert(is_overflow_i64(stoi64("-9223372036854775809")));
+ assert(stoi64("9223372036854775808") is overflow);
+ assert(stoi64("-9223372036854775809") is overflow);
- assert(is_number_i64(0i64, stoi64("0")));
- assert(is_number_i64(1i64, stoi64("1")));
- assert(is_number_i64(-1i64, stoi64("-1")));
- assert(is_number_i64(9223372036854775807i64, stoi64("9223372036854775807")));
- assert(is_number_i64(-9223372036854775808i64, stoi64("-9223372036854775808")));
+ assert(stoi64("0") as i64 == 0);
+ assert(stoi64("1") as i64 == 1);
+ assert(stoi64("-1") as i64 == -1);
+ assert(stoi64("9223372036854775807") as i64 == 9223372036854775807);
+ assert(stoi64("-9223372036854775808") as i64 == -9223372036854775808);
- assert(is_overflow_i32(stoi32("2147483648")));
- assert(is_overflow_i32(stoi32("-2147483649")));
+ assert(stoi32("2147483648") is overflow);
+ assert(stoi32("-2147483649") is overflow);
- assert(is_number_i32(2147483647i32, stoi32("2147483647")));
- assert(is_number_i32(-2147483648i32, stoi32("-2147483648")));
+ assert(stoi32("2147483647") as i32 == 2147483647);
+ assert(stoi32("-2147483648") as i32 == -2147483648);
};
diff --git a/strconv/+test/stou.ha b/strconv/+test/stou.ha
@@ -1,41 +1,20 @@
-fn is_invalid64(value: (u64 | invalid | overflow)) bool = {
- return match (value) {
- invalid => true,
- * => false,
- };
-};
-
-fn is_overflow64(value: (u64 | invalid | overflow)) bool = {
- return match (value) {
- overflow => true,
- * => false,
- };
-};
-
-fn is_number64(n: u64, value: (u64 | invalid | overflow)) bool = {
- return match (value) {
- v: u64 => v == n,
- * => false,
- };
-};
-
@test fn stou() void = {
- assert(is_invalid64(stou64("")));
- assert(is_invalid64(stou64("abc")));
- assert(is_invalid64(stou64("1a")));
- assert(is_invalid64(stou64("-1")));
+ assert(stou64("") as invalid == 0: strconv::invalid);
+ assert(stou64("abc") as invalid == 0: strconv::invalid);
+ assert(stou64("1a") as invalid == 1: strconv::invalid);
+ assert(stou64("-1") as invalid == 0: strconv::invalid);
- assert(is_overflow64(stou64("18446744073709551616")));
- assert(is_overflow64(stou64("184467440737095516150")));
+ assert(stou64("18446744073709551616") is overflow);
+ assert(stou64("184467440737095516150") is overflow);
- assert(is_number64(0u64, stou64("0")));
- assert(is_number64(1u64, stou64("1")));
- assert(is_number64(18446744073709551615u64, stou64("18446744073709551615")));
+ assert(stou64("0") as u64 == 0);
+ assert(stou64("1") as u64 == 1);
+ assert(stou64("18446744073709551615") as u64 == 18446744073709551615);
};
@test fn stoub() void = {
- assert(is_number64(0x7fu64, stou64b("7f", 16u)));
- assert(is_number64(0x7fu64, stou64b("7F", 16u)));
- assert(is_number64(0o37u64, stou64b("37", 8u)));
- assert(is_number64(0b110101u64, stou64b("110101", 2u)));
+ assert(stou64b("7f", 16) as u64 == 0x7f);
+ assert(stou64b("7F", 16u) as u64 == 0x7f);
+ assert(stou64b("37", 8) as u64 == 0o37);
+ assert(stou64b("110101", 2) as u64 == 0b110101);
};
diff --git a/strconv/stoi.ha b/strconv/stoi.ha
@@ -6,7 +6,7 @@ use strings;
// [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) = {
- if (len(s) == 0) return invalid;
+ if (len(s) == 0) return 0: invalid;
let b = strings::to_utf8(s);
let sign = 1i64;
let max = types::I64_MAX: u64;
diff --git a/strconv/stou.ha b/strconv/stou.ha
@@ -20,10 +20,10 @@ export fn stou64b(s: str, base: uint) (u64 | invalid | overflow) = {
assert(base == 2 || base == 8 || base == 10 || base == 16);
if (len(s) == 0) {
- return invalid;
+ return 0: invalid;
};
- let n = 0z;
+ let n = 0u64;
let iter = strings::iter(s);
for (true) {
let r: rune = match (strings::next(&iter)) {
@@ -32,11 +32,11 @@ export fn stou64b(s: str, base: uint) (u64 | invalid | overflow) = {
};
let digit = match (rune_to_integer(r)) {
- void => return invalid,
+ void => return (iter.dec.offs - 1): invalid,
d: u64 => d,
};
- if (digit >= base: u64) return invalid;
+ if (digit >= base: u64) return (iter.dec.offs - 1): invalid;
let old = n;
diff --git a/strconv/types.ha b/strconv/types.ha
@@ -1,8 +1,9 @@
-// Indicates that the input string is not an integer
-export type invalid = void!;
+// Indicates that the input string is not an integer. Contains the index of the
+// first nondigit rune.
+export type invalid = size!;
// Indicates that the input number is too large to be represented by the
-// requested data type
+// requested data type.
export type overflow = void!;
// The valid numeric bases for numeric conversions.