aboutsummaryrefslogtreecommitdiff
path: root/parse.c
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-08-13 01:30:25 -0400
committerBruce Hill <bruce@bruce-hill.com>2024-08-13 01:30:25 -0400
commitd08f795794b33a5d52e39c6b9f0c4e6e88fede3d (patch)
tree7267e0828b73685f9af0c3e9cf58212c45af289c /parse.c
parentc1c889b024529ac754f83caec4cc15971123d07b (diff)
Partially working first draft of bigints
Diffstat (limited to 'parse.c')
-rw-r--r--parse.c57
1 files changed, 18 insertions, 39 deletions
diff --git a/parse.c b/parse.c
index 8ef8665e..e5072d22 100644
--- a/parse.c
+++ b/parse.c
@@ -1,6 +1,7 @@
// Recursive descent parser for parsing code
#include <ctype.h>
#include <gc.h>
+#include <gmp.h>
#include <libgen.h>
#include <linux/limits.h>
#include <setjmp.h>
@@ -12,6 +13,7 @@
#include <signal.h>
#include "ast.h"
+#include "builtins/integers.h"
#include "builtins/table.h"
#include "builtins/util.h"
@@ -439,59 +441,34 @@ PARSER(parse_parens) {
PARSER(parse_int) {
const char *start = pos;
- bool negative = match(&pos, "-");
+ (void)match(&pos, "-");
if (!isdigit(*pos)) return false;
int64_t i = 0;
if (match(&pos, "0x")) { // Hex
- size_t span = strspn(pos, "0123456789abcdefABCDEF_");
- char *buf = GC_MALLOC_ATOMIC(span+1);
- memset(buf, 0, span+1);
- for (char *src = (char*)pos, *dest = buf; src < pos+span; ++src) {
- if (*src != '_') *(dest++) = *src;
- }
- i = strtol(buf, NULL, 16);
- pos += span;
+ pos += strspn(pos, "0123456789abcdefABCDEF_");
} else if (match(&pos, "0b")) { // Binary
- size_t span = strspn(pos, "01_");
- char *buf = GC_MALLOC_ATOMIC(span+1);
- memset(buf, 0, span+1);
- for (char *src = (char*)pos, *dest = buf; src < pos+span; ++src) {
- if (*src != '_') *(dest++) = *src;
- }
- i = strtol(buf, NULL, 2);
- pos += span;
+ pos += strspn(pos, "01_");
} else if (match(&pos, "0o")) { // Octal
- size_t span = strspn(pos, "01234567_");
- char *buf = GC_MALLOC_ATOMIC(span+1);
- memset(buf, 0, span+1);
- for (char *src = (char*)pos, *dest = buf; src < pos+span; ++src) {
- if (*src != '_') *(dest++) = *src;
- }
- i = strtol(buf, NULL, 8);
- pos += span;
+ pos += strspn(pos, "01234567_");
} else { // Decimal
- size_t span = strspn(pos, "0123456789_");
- char *buf = GC_MALLOC_ATOMIC(span+1);
- memset(buf, 0, span+1);
- for (char *src = (char*)pos, *dest = buf; src < pos+span; ++src) {
- if (*src != '_') *(dest++) = *src;
- }
- i = strtol(buf, NULL, 10);
- pos += span;
+ pos += strspn(pos, "0123456789_");
+ }
+ char *str = GC_MALLOC_ATOMIC((size_t)(pos - start) + 1);
+ memset(str, 0, (size_t)(pos - start) + 1);
+ for (char *src = (char*)start, *dest = str; src < pos; ++src) {
+ if (*src != '_') *(dest++) = *src;
}
if (match(&pos, "e") || match(&pos, "f")) // floating point literal
return NULL;
- if (negative) i *= -1;
-
if (match(&pos, "%")) {
double d = (double)i / 100.;
return NewAST(ctx->file, start, pos, Num, .n=d, .bits=64);
}
match(&pos, "_");
- int64_t bits = 64;
+ int64_t bits = 0;
if (match(&pos, "i64")) bits = 64;
else if (match(&pos, "i32")) bits = 32;
else if (match(&pos, "i16")) bits = 16;
@@ -499,7 +476,7 @@ PARSER(parse_int) {
// else if (match(&pos, ".") || match(&pos, "e")) return NULL; // looks like a float
- return NewAST(ctx->file, start, pos, Int, .i=i, .bits=bits);
+ return NewAST(ctx->file, start, pos, Int, .str=str, .bits=bits);
}
type_ast_t *parse_table_type(parse_ctx_t *ctx, const char *pos) {
@@ -1908,7 +1885,9 @@ ast_t *parse_enum_def(parse_ctx_t *ctx, const char *pos) {
spaces(&pos);
if (match(&pos, "=")) {
ast_t *val = expect(ctx, tag_start, &pos, parse_int, "I expected an integer literal after this '='");
- next_value = Match(val, Int)->i;
+ Int_t i = Int$from_text(Match(val, Int)->str);
+ // TODO check for overflow
+ next_value = (i.small >> 2);
}
// Check for duplicate values:
@@ -2051,7 +2030,7 @@ PARSER(parse_func_def) {
if (match_word(&pos, "inline")) {
is_inline = true;
} else if (match_word(&pos, "cached")) {
- if (!cache_ast) cache_ast = NewAST(ctx->file, pos, pos, Int, .i=INT64_MAX, .bits=64);
+ if (!cache_ast) cache_ast = NewAST(ctx->file, pos, pos, Int, .str="-1", .bits=0);
} else if (match_word(&pos, "cache_size")) {
whitespace(&pos);
if (!match(&pos, "="))