harec

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 9048ce748f804c96ea61d27b2139edd8d4548428
parent 171bc0b0d1d5940b779ccab776bca38d4a59f639
Author: Sudipto Mallick <smlckz@disroot.org>
Date:   Tue, 13 Apr 2021 12:56:23 +0000

lex: allow signed exponents for floating literals

Diffstat:
Msrc/lex.c | 33+++++++++++++++++++++++++--------
Mtests/00-constants.ha | 1+
2 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/src/lex.c b/src/lex.c @@ -304,7 +304,7 @@ lex_literal(struct lexer *lexer, struct token *out) if (!strchr(basechrs, c)) { switch (c) { case '.': - if (isfloat || suff) { + if (isfloat || suff || exp) { push(lexer, c, true); goto finalize; } @@ -322,7 +322,15 @@ lex_literal(struct lexer *lexer, struct token *out) push(lexer, c, true); goto finalize; } - exp = &lexer->buf[lexer->buflen]; + // exponent is always in base 10 + basechrs = "0123456789"; + c = next(lexer, NULL, true); + if (c != '-' && c != '+' && !strchr(basechrs, c)) { + push(lexer, c, true); + push(lexer, 'e', true); + goto finalize; + }; + exp = &lexer->buf[lexer->buflen - 1]; break; case 'i': case 'u': @@ -382,11 +390,20 @@ finalize: } } - uintmax_t exponent = 0; + intmax_t exponent = 0; if (exp) { char *endptr = NULL; - exponent = strtoumax(exp, &endptr, 10); - if (endptr == exp) { + exponent = strtoimax(exp, &endptr, 10); + // integers can't have negative exponents + if (exponent < 0 && !suff) { + out->storage = STORAGE_FCONST; + } + enum type_storage s = out->storage; + bool valid = exponent >= 0 + || s == STORAGE_F32 + || s == STORAGE_F64 + || s == STORAGE_FCONST; + if (endptr == exp || !valid) { out->token = T_ERROR; consume(lexer, -1); return out->token; @@ -402,14 +419,14 @@ finalize: case STORAGE_U64: case STORAGE_SIZE: out->uval = strtoumax(lexer->buf, NULL, base); - for (uintmax_t i = 0; i < exponent; i++) { + for (intmax_t i = 0; i < exponent; i++) { out->uval *= 10; } break; case STORAGE_ICONST: if (lexer->buf[0] != '-') { uintmax_t uval = strtoumax(lexer->buf, NULL, base); - for (uintmax_t i = 0; i < exponent; i++) { + for (intmax_t i = 0; i < exponent; i++) { uval *= 10; } if (uval > (uintmax_t)INT64_MAX) { @@ -425,7 +442,7 @@ finalize: case STORAGE_INT: case STORAGE_I64: out->ival = strtoimax(lexer->buf, NULL, base); - for (uintmax_t i = 0; i < exponent; i++) { + for (intmax_t i = 0; i < exponent; i++) { out->ival *= 10; } break; diff --git a/tests/00-constants.ha b/tests/00-constants.ha @@ -8,4 +8,5 @@ export fn main() void = { r6 = '\b', r7 = '\f', r8 = '\n', r9 = '\r', r10 = '\t', r11 = '\v', r12 = '\\', r13 = '\'', r14 = '\"'; let f1 = 1.0, f2 = 1f32, f3 = 1.0e2, f4 = 1.0f64; + let f5 = 1.23e+45, f6 = 9.87e-65, f7 = 1e-7; };