diff --git a/src/big_int.cpp b/src/big_int.cpp index f59dccf24..ffb7a6ad6 100644 --- a/src/big_int.cpp +++ b/src/big_int.cpp @@ -249,13 +249,28 @@ gb_internal void big_int_from_string(BigInt *dst, String const &s, bool *success } if (i < len && (text[i] == 'e' || text[i] == 'E')) { i += 1; - GB_ASSERT(base == 10); - GB_ASSERT(text[i] != '-'); + if (base != 10) { + // An exponent is only meaningful for a base 10 literal. + *success = false; + return; + } + if (i >= len) { + // Nothing follows the exponent marker. + *success = false; + return; + } + if (text[i] == '-') { + // A negative exponent is never an integer. + // The caller is expected to parse the value as a float instead. + *success = false; + return; + } if (text[i] == '+') { i += 1; } u64 exp = 0; + isize exp_digits = 0; for (; i < len; i++) { char r = cast(char)text[i]; if (r == '_') { @@ -270,6 +285,11 @@ gb_internal void big_int_from_string(BigInt *dst, String const &s, bool *success } exp *= 10; exp += v; + exp_digits += 1; + } + if (exp_digits == 0) { + *success = false; + return; } // NOTE(Jeroen): A valid integer can never have an exponent larger than 308 (per `max(f64)`). diff --git a/src/main.cpp b/src/main.cpp index de4c219e2..74900587f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -537,6 +537,27 @@ gb_internal void add_flag(Array *build_flags, BuildFlagKind kind, Str array_add(build_flags, flag); } +// A value such as `1e-5` is a float, not an integer. Base prefixed literals are excluded because +// `e` is a valid digit in bases 16 and above, e.g. `0x1e`. +gb_internal bool build_param_looks_like_float(String const ¶m) { + if (string_contains_char(param, '.')) { + return true; + } + isize i = 0; + if (param.len > 0 && (param[0] == '-' || param[0] == '+')) { + i = 1; + } + if (param.len > i+1 && param[i] == '0' && !gb_char_is_digit(cast(char)param[i+1])) { + return false; + } + for (; i < param.len; i++) { + if (param[i] == 'e' || param[i] == 'E') { + return true; + } + } + return false; +} + gb_internal ExactValue build_param_to_exact_value(String name, String param) { ExactValue value = {}; @@ -562,7 +583,7 @@ gb_internal ExactValue build_param_to_exact_value(String name, String param) { Try to parse as an integer or float */ if (param[0] == '-' || param[0] == '+' || gb_is_between(param[0], '0', '9')) { - if (string_contains_char(param, '.')) { + if (build_param_looks_like_float(param)) { value = exact_value_float_from_string(param); } else { value = exact_value_integer_from_string(param);