aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/parse/numbers.c83
-rw-r--r--src/parse/numbers.h10
-rw-r--r--src/parse/parse.c72
-rw-r--r--src/parse/parse.h2
4 files changed, 95 insertions, 72 deletions
diff --git a/src/parse/numbers.c b/src/parse/numbers.c
new file mode 100644
index 00000000..a0db1273
--- /dev/null
+++ b/src/parse/numbers.c
@@ -0,0 +1,83 @@
+
+#include <ctype.h>
+#include <gc.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include <unictype.h>
+#include <uniname.h>
+
+#include "../ast.h"
+#include "../stdlib/util.h"
+#include "context.h"
+#include "errors.h"
+#include "utils.h"
+
+static const double RADIANS_PER_DEGREE = 0.0174532925199432957692369076848861271344287188854172545609719144;
+
+public
+ast_t *parse_int(parse_ctx_t *ctx, const char *pos) {
+ const char *start = pos;
+ (void)match(&pos, "-");
+ if (!isdigit(*pos)) return NULL;
+ if (match(&pos, "0x")) { // Hex
+ pos += strspn(pos, "0123456789abcdefABCDEF_");
+ } else if (match(&pos, "0b")) { // Binary
+ pos += strspn(pos, "01_");
+ } else if (match(&pos, "0o")) { // Octal
+ pos += strspn(pos, "01234567_");
+ } else { // Decimal
+ 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 (match(&pos, "%")) {
+ double n = strtod(str, NULL) / 100.;
+ return NewAST(ctx->file, start, pos, Num, .n = n);
+ } else if (match(&pos, "deg")) {
+ double n = strtod(str, NULL) * RADIANS_PER_DEGREE;
+ return NewAST(ctx->file, start, pos, Num, .n = n);
+ }
+
+ return NewAST(ctx->file, start, pos, Int, .str = str);
+}
+
+public
+ast_t *parse_num(parse_ctx_t *ctx, const char *pos) {
+ const char *start = pos;
+ bool negative = match(&pos, "-");
+ if (!isdigit(*pos) && *pos != '.') return NULL;
+ else if (*pos == '.' && !isdigit(pos[1])) return NULL;
+
+ size_t len = strspn(pos, "0123456789_");
+ if (strncmp(pos + len, "..", 2) == 0) return NULL;
+ else if (pos[len] == '.') len += 1 + strspn(pos + len + 1, "0123456789");
+ else if (pos[len] != 'e' && pos[len] != 'f' && pos[len] != '%') return NULL;
+ if (pos[len] == 'e') {
+ len += 1;
+ if (pos[len] == '-') len += 1;
+ len += strspn(pos + len, "0123456789_");
+ }
+ char *buf = GC_MALLOC_ATOMIC(len + 1);
+ memset(buf, 0, len + 1);
+ for (char *src = (char *)pos, *dest = buf; src < pos + len; ++src) {
+ if (*src != '_') *(dest++) = *src;
+ }
+ double d = strtod(buf, NULL);
+ pos += len;
+
+ if (negative) d *= -1;
+
+ if (match(&pos, "%")) d /= 100.;
+ else if (match(&pos, "deg")) d *= RADIANS_PER_DEGREE;
+
+ return NewAST(ctx->file, start, pos, Num, .n = d);
+}
diff --git a/src/parse/numbers.h b/src/parse/numbers.h
new file mode 100644
index 00000000..89f5e28b
--- /dev/null
+++ b/src/parse/numbers.h
@@ -0,0 +1,10 @@
+// Logic for parsing numbers
+#pragma once
+
+// Parsing logic
+
+#include "../ast.h"
+#include "context.h"
+
+ast_t *parse_int(parse_ctx_t *ctx, const char *pos);
+ast_t *parse_num(parse_ctx_t *ctx, const char *pos);
diff --git a/src/parse/parse.c b/src/parse/parse.c
index 48c92ef9..53365ee7 100644
--- a/src/parse/parse.c
+++ b/src/parse/parse.c
@@ -1,5 +1,5 @@
// Recursive descent parser for parsing code
-#include <ctype.h>
+
#include <gc.h>
#include <stdarg.h>
#include <stdbool.h>
@@ -16,10 +16,10 @@
#include "context.h"
#include "errors.h"
#include "files.h"
+#include "numbers.h"
#include "parse.h"
#include "utils.h"
-static const double RADIANS_PER_DEGREE = 0.0174532925199432957692369076848861271344287188854172545609719144;
static const char closing[128] = {['('] = ')', ['['] = ']', ['<'] = '>', ['{'] = '}'};
int op_tightness[] = {
@@ -49,10 +49,6 @@ int op_tightness[] = {
[Xor] = 1,
};
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////// AST-based parsers /////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-
ast_t *parse_parens(parse_ctx_t *ctx, const char *pos) {
const char *start = pos;
spaces(&pos);
@@ -75,39 +71,6 @@ ast_t *parse_parens(parse_ctx_t *ctx, const char *pos) {
return new (ast_t, .file = (ctx)->file, .start = start, .end = pos, .tag = expr->tag, .__data = expr->__data);
}
-ast_t *parse_int(parse_ctx_t *ctx, const char *pos) {
- const char *start = pos;
- (void)match(&pos, "-");
- if (!isdigit(*pos)) return NULL;
- if (match(&pos, "0x")) { // Hex
- pos += strspn(pos, "0123456789abcdefABCDEF_");
- } else if (match(&pos, "0b")) { // Binary
- pos += strspn(pos, "01_");
- } else if (match(&pos, "0o")) { // Octal
- pos += strspn(pos, "01234567_");
- } else { // Decimal
- 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 (match(&pos, "%")) {
- double n = strtod(str, NULL) / 100.;
- return NewAST(ctx->file, start, pos, Num, .n = n);
- } else if (match(&pos, "deg")) {
- double n = strtod(str, NULL) * RADIANS_PER_DEGREE;
- return NewAST(ctx->file, start, pos, Num, .n = n);
- }
-
- return NewAST(ctx->file, start, pos, Int, .str = str);
-}
-
type_ast_t *parse_table_type(parse_ctx_t *ctx, const char *pos) {
const char *start = pos;
if (!match(&pos, "{")) return NULL;
@@ -230,37 +193,6 @@ type_ast_t *parse_type(parse_ctx_t *ctx, const char *pos) {
return type;
}
-ast_t *parse_num(parse_ctx_t *ctx, const char *pos) {
- const char *start = pos;
- bool negative = match(&pos, "-");
- if (!isdigit(*pos) && *pos != '.') return NULL;
- else if (*pos == '.' && !isdigit(pos[1])) return NULL;
-
- size_t len = strspn(pos, "0123456789_");
- if (strncmp(pos + len, "..", 2) == 0) return NULL;
- else if (pos[len] == '.') len += 1 + strspn(pos + len + 1, "0123456789");
- else if (pos[len] != 'e' && pos[len] != 'f' && pos[len] != '%') return NULL;
- if (pos[len] == 'e') {
- len += 1;
- if (pos[len] == '-') len += 1;
- len += strspn(pos + len, "0123456789_");
- }
- char *buf = GC_MALLOC_ATOMIC(len + 1);
- memset(buf, 0, len + 1);
- for (char *src = (char *)pos, *dest = buf; src < pos + len; ++src) {
- if (*src != '_') *(dest++) = *src;
- }
- double d = strtod(buf, NULL);
- pos += len;
-
- if (negative) d *= -1;
-
- if (match(&pos, "%")) d /= 100.;
- else if (match(&pos, "deg")) d *= RADIANS_PER_DEGREE;
-
- return NewAST(ctx->file, start, pos, Num, .n = d);
-}
-
ast_t *parse_list(parse_ctx_t *ctx, const char *pos) {
const char *start = pos;
if (!match(&pos, "[")) return NULL;
diff --git a/src/parse/parse.h b/src/parse/parse.h
index 1e8c979f..fed78032 100644
--- a/src/parse/parse.h
+++ b/src/parse/parse.h
@@ -45,7 +45,6 @@ ast_t *parse_func_def(parse_ctx_t *ctx, const char *pos);
ast_t *parse_heap_alloc(parse_ctx_t *ctx, const char *pos);
ast_t *parse_if(parse_ctx_t *ctx, const char *pos);
ast_t *parse_inline_c(parse_ctx_t *ctx, const char *pos);
-ast_t *parse_int(parse_ctx_t *ctx, const char *pos);
ast_t *parse_lambda(parse_ctx_t *ctx, const char *pos);
ast_t *parse_lang_def(parse_ctx_t *ctx, const char *pos);
ast_t *parse_extend(parse_ctx_t *ctx, const char *pos);
@@ -53,7 +52,6 @@ ast_t *parse_namespace(parse_ctx_t *ctx, const char *pos);
ast_t *parse_negative(parse_ctx_t *ctx, const char *pos);
ast_t *parse_not(parse_ctx_t *ctx, const char *pos);
ast_t *parse_none(parse_ctx_t *ctx, const char *pos);
-ast_t *parse_num(parse_ctx_t *ctx, const char *pos);
ast_t *parse_parens(parse_ctx_t *ctx, const char *pos);
ast_t *parse_pass(parse_ctx_t *ctx, const char *pos);
ast_t *parse_path(parse_ctx_t *ctx, const char *pos);