Return (value: T, ok: bool) instead

This commit is contained in:
Tetralux
2020-04-29 22:37:33 +01:00
parent 190932935c
commit 704ee9f851
+20 -30
View File
@@ -28,7 +28,7 @@ _digit_value :: proc(r: rune) -> int {
// n, rest := strconv.parse_i64_of_base("-1234eeee", 10); // n, rest := strconv.parse_i64_of_base("-1234eeee", 10);
// assert(n == -1234 && rest == "eeee"); // assert(n == -1234 && rest == "eeee");
// ``` // ```
parse_i64_of_base :: proc(str: string, base: int) -> (value: i64, rest: string) { parse_i64_of_base :: proc(str: string, base: int) -> (value: i64, ok: bool) {
assert(base <= 16, "base must be 1-16"); assert(base <= 16, "base must be 1-16");
s := str; s := str;
neg := false; neg := false;
@@ -43,13 +43,11 @@ parse_i64_of_base :: proc(str: string, base: int) -> (value: i64, rest: string)
} }
i := 0; i := 0;
reached_end := true;
for r in s { for r in s {
i += 1; i += 1;
if r == '_' do continue; if r == '_' do continue;
v := i64(_digit_value(r)); v := i64(_digit_value(r));
if v >= i64(base) { if v >= i64(base) {
reached_end = false;
break; break;
} }
value *= i64(base); value *= i64(base);
@@ -57,7 +55,7 @@ parse_i64_of_base :: proc(str: string, base: int) -> (value: i64, rest: string)
} }
if neg do value = -value; if neg do value = -value;
rest = reached_end ? "" : s[i-1:]; ok = i > 1;
return; return;
} }
@@ -69,7 +67,7 @@ parse_i64_of_base :: proc(str: string, base: int) -> (value: i64, rest: string)
// n, rest = strconv.parse_i64_maybe_prefixed("0xeeee"); // n, rest = strconv.parse_i64_maybe_prefixed("0xeeee");
// assert(n == 0xeeee && rest == ""); // assert(n == 0xeeee && rest == "");
// ``` // ```
parse_i64_maybe_prefixed :: proc(str: string) -> (value: i64, rest: string) { parse_i64_maybe_prefixed :: proc(str: string) -> (value: i64, ok: bool) {
s := str; s := str;
neg := false; neg := false;
if len(s) > 1 { if len(s) > 1 {
@@ -95,13 +93,11 @@ parse_i64_maybe_prefixed :: proc(str: string) -> (value: i64, rest: string) {
} }
i := 0; i := 0;
reached_end := true;
for r in s { for r in s {
i += 1; i += 1;
if r == '_' do continue; if r == '_' do continue;
v := i64(_digit_value(r)); v := i64(_digit_value(r));
if v >= base { if v >= base {
reached_end = false;
break; break;
} }
value *= base; value *= base;
@@ -109,7 +105,7 @@ parse_i64_maybe_prefixed :: proc(str: string) -> (value: i64, rest: string) {
} }
if neg do value = -value; if neg do value = -value;
rest = reached_end ? "" : s[i-1:]; ok = i > 1;
return; return;
} }
@@ -124,7 +120,7 @@ parse_i64 :: proc{parse_i64_maybe_prefixed, parse_i64_of_base};
// n, rest = strconv.parse_u64_of_base("1234eeee", 16); // n, rest = strconv.parse_u64_of_base("1234eeee", 16);
// assert(n == 0x1234eeee && rest == ""); // assert(n == 0x1234eeee && rest == "");
// ``` // ```
parse_u64_of_base :: proc(str: string, base: int) -> (value: u64, rest: string) { parse_u64_of_base :: proc(str: string, base: int) -> (value: u64, ok: bool) {
assert(base <= 16, "base must be 1-16"); assert(base <= 16, "base must be 1-16");
s := str; s := str;
if len(s) > 1 && s[0] == '+' { if len(s) > 1 && s[0] == '+' {
@@ -132,20 +128,18 @@ parse_u64_of_base :: proc(str: string, base: int) -> (value: u64, rest: string)
} }
i := 0; i := 0;
reached_end := true;
for r in s { for r in s {
i += 1; i += 1;
if r == '_' do continue; if r == '_' do continue;
v := u64(_digit_value(r)); v := u64(_digit_value(r));
if v >= u64(base) { if v >= u64(base) {
reached_end = false;
break; break;
} }
value *= u64(base); value *= u64(base);
value += v; value += v;
} }
rest = reached_end ? "" : s[i-1:]; ok = i > 1;
return; return;
} }
@@ -157,7 +151,7 @@ parse_u64_of_base :: proc(str: string, base: int) -> (value: u64, rest: string)
// n, rest = strconv.parse_u64_maybe_prefixed("0xeeee"); // n, rest = strconv.parse_u64_maybe_prefixed("0xeeee");
// assert(n == 0xeeee && rest == ""); // assert(n == 0xeeee && rest == "");
// ``` // ```
parse_u64_maybe_prefixed :: proc(str: string) -> (value: u64, rest: string) { parse_u64_maybe_prefixed :: proc(str: string) -> (value: u64, ok: bool) {
s := str; s := str;
if len(s) > 1 && s[0] == '+' { if len(s) > 1 && s[0] == '+' {
s = s[1:]; s = s[1:];
@@ -176,20 +170,18 @@ parse_u64_maybe_prefixed :: proc(str: string) -> (value: u64, rest: string) {
} }
i := 0; i := 0;
reached_end := true;
for r in s { for r in s {
i += 1; i += 1;
if r == '_' do continue; if r == '_' do continue;
v := u64(_digit_value(r)); v := u64(_digit_value(r));
if v >= base { if v >= base {
reached_end = false;
break; break;
} }
value *= base; value *= base;
value += u64(v); value += u64(v);
} }
rest = reached_end ? "" : s[i-1:]; ok = i > 1;
return; return;
} }
@@ -208,29 +200,30 @@ parse_u64 :: proc{parse_u64_maybe_prefixed, parse_u64_of_base};
// n, rest = strconv.parse_int("0xffff"); // with prefix and inferred base // n, rest = strconv.parse_int("0xffff"); // with prefix and inferred base
// assert(n == 0xffff && rest == ""); // assert(n == 0xffff && rest == "");
// ``` // ```
parse_int :: proc(s: string, base := 0) -> (value: int, rest: string) { parse_int :: proc(s: string, base := 0) -> (value: int, ok: bool) {
v: i64 = ---; v: i64 = ---;
switch base { switch base {
case 0: v, rest = parse_i64_maybe_prefixed(s); case 0: v, ok = parse_i64_maybe_prefixed(s);
case: v, rest = parse_i64_of_base(s, base); case: v, ok = parse_i64_of_base(s, base);
} }
value = int(v); value = int(v);
return; return;
} }
parse_uint :: proc(s: string, base := 0) -> (value: uint, rest: string) { parse_uint :: proc(s: string, base := 0) -> (value: uint, ok: bool) {
v: u64 = ---; v: u64 = ---;
switch base { switch base {
case 0: v, rest = parse_u64_maybe_prefixed(s); case 0: v, ok = parse_u64_maybe_prefixed(s);
case: v, rest = parse_u64_of_base(s, base); case: v, ok = parse_u64_of_base(s, base);
} }
value = uint(v); value = uint(v);
return; return;
} }
parse_f32 :: proc(s: string) -> (value: f32, rest: string) { parse_f32 :: proc(s: string) -> (value: f32, ok: bool) {
v, r := parse_f64(s); v: f64 = ---;
return f32(v), r; v, ok = parse_f64(s);
return f32(v), ok;
} }
// Parses a floating point number from a string. // Parses a floating point number from a string.
@@ -241,7 +234,7 @@ parse_f32 :: proc(s: string) -> (value: f32, rest: string) {
// n, rest = strconv.parse_f64("12.34"); // n, rest = strconv.parse_f64("12.34");
// assert(n == 12.34 && rest == ""); // assert(n == 12.34 && rest == "");
// ``` // ```
parse_f64 :: proc(s: string) -> (value: f64, rest: string) { parse_f64 :: proc(s: string) -> (value: f64, ok: bool) {
if s == "" { if s == "" {
return; return;
} }
@@ -263,7 +256,6 @@ parse_f64 :: proc(s: string) -> (value: f64, rest: string) {
value += f64(v); value += f64(v);
} }
reached_end := true;
if i < len(s) && s[i] == '.' { if i < len(s) && s[i] == '.' {
pow10: f64 = 10; pow10: f64 = 10;
i += 1; i += 1;
@@ -274,7 +266,6 @@ parse_f64 :: proc(s: string) -> (value: f64, rest: string) {
v := _digit_value(r); v := _digit_value(r);
if v >= 10 { if v >= 10 {
reached_end = false;
break; break;
} }
value += f64(v)/pow10; value += f64(v)/pow10;
@@ -301,7 +292,6 @@ parse_f64 :: proc(s: string) -> (value: f64, rest: string) {
d := u32(_digit_value(r)); d := u32(_digit_value(r));
if d >= 10 { if d >= 10 {
reached_end = false;
break; break;
} }
exp = exp * 10 + d; exp = exp * 10 + d;
@@ -320,7 +310,7 @@ parse_f64 :: proc(s: string) -> (value: f64, rest: string) {
value = sign * (value*scale); value = sign * (value*scale);
} }
rest = reached_end ? "" : s[i-1:]; ok = i > 0;
return; return;
} }