summaryrefslogtreecommitdiff
path: root/pit/src/parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'pit/src/parser.c')
-rw-r--r--pit/src/parser.c34
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));