diff --git a/src/compiler/lexer.c b/src/compiler/lexer.c index c2fc27bf2..0280fd784 100644 --- a/src/compiler/lexer.c +++ b/src/compiler/lexer.c @@ -397,6 +397,23 @@ static inline bool scan_hex(Lexer *lexer) while (is_digit(peek(lexer))) next(lexer); } if (prev(lexer) == '_') return add_error_token(lexer, "The number ended with '_', but that character needs to be between, not after, digits."); + if (is_float) + { + // IMPROVE + // For the float we actually parse things, using strtold + // this is not ideal, we should try to use f128 if possible for example. + // Possibly we should move to a BigDecimal implementation or at least a soft float 256 + // implementation for the constants. + char *end = NULL; + long double fval = strtold(lexer->lexing_start, &end); + if (end != lexer->current) + { + return add_error_token(lexer, "Invalid float value."); + } + add_generic_token(lexer, TOKEN_REAL); + lexer->latest_token_data->value = fval; + return true; + } return add_token(lexer, is_float ? TOKEN_REAL : TOKEN_INTEGER, lexer->lexing_start); } diff --git a/test/test_suite/expressions/parsed_numbers.c3t b/test/test_suite/expressions/parsed_numbers.c3t new file mode 100644 index 000000000..727d824eb --- /dev/null +++ b/test/test_suite/expressions/parsed_numbers.c3t @@ -0,0 +1,13 @@ +module numbers; + +double a = 0x1.1p+1; +double b = -12.3e-12; +double c = 0x1.1p-1; +double d = 12.3e+12; + +// #expect: numbers.ll + +@numbers.a = global double 2.125000e+00, align 8 +@numbers.b = global double -1.230000e-11, align 8 +@numbers.c = global double 5.312500e-01, align 8 +@numbers.d = global double 1.230000e+13, align 8 \ No newline at end of file