diff options
| author | LLLL Colonq <llll@colonq> | 2026-09-29 17:34:12 -0400 |
|---|---|---|
| committer | LLLL Colonq <llll@colonq> | 2026-09-29 17:34:12 -0400 |
| commit | 84f13229756b5a9253d7013ede8ed3a602ee5376 (patch) | |
| tree | 618c88ed27e9e528a6eeb52935baa1d55be0ee5d /pit/src/parser.c | |
| parent | 17df4b1ff7f4cbcf3b3218fea68f65d3cb60c984 (diff) | |
pit: Better double support
Diffstat (limited to 'pit/src/parser.c')
| -rw-r--r-- | pit/src/parser.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/pit/src/parser.c b/pit/src/parser.c index 0f9b167..6c633c9 100644 --- a/pit/src/parser.c +++ b/pit/src/parser.c @@ -46,6 +46,11 @@ static i64 digit_value(char c) { } } +static double digit_value_double(char c) { + i64 ret = digit_value(c); + return (double) ret; +} + void pit_parser_from_lexer(pit_parser *ret, pit_lexer *lex) { ret->lexer = lex; ret->cur.token = ret->next.token = PIT_LEX_TOKEN_ERROR; @@ -154,6 +159,35 @@ pit_value pit_parse(pit_runtime *rt, pit_parser *st, bool *eof) { } return pit_value_integer_new(rt, neg ? -total : total); } + case PIT_LEX_TOKEN_DOUBLE_LITERAL: { + i64 idx = st->cur.start; + double total = 0.0; + double point = 1.0; + bool after_point = false; + bool neg = false; + char c = st->lexer->input[idx++]; + if (c == '-') { + neg = true; + if (idx < st->cur.end) { + c = st->lexer->input[idx++]; + } else { + pit_error(rt, "malformed negative double literal"); return PIT_NIL; + } + } else if (c == '.') after_point = true; + total = digit_value_double(c); + while (idx < st->cur.end) { + c = st->lexer->input[idx++]; + if (c == '.') { + after_point = true; + } else { + total *= 10.0; + total += digit_value_double(c); + if (after_point) point *= 10.0; + } + } + total /= point; + return pit_value_double_new(rt, neg ? -total : total); + } case PIT_LEX_TOKEN_STRING_LITERAL: { char buf[256] = {0}; get_token_string(st, buf, sizeof(buf)); |
