aboutsummaryrefslogtreecommitdiff
path: root/src/parse.c
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-08-23 19:28:08 -0400
committerBruce Hill <bruce@bruce-hill.com>2025-08-23 19:28:08 -0400
commitfcda36561d668f43bac91ea31cd55cbbd605d330 (patch)
treeeb74c0b17df584af0fd8154422ad924e04c96cc2 /src/parse.c
parent414b0c7472c87c5a013029aefef49e2dbc41e700 (diff)
Autoformat everything with clang-format
Diffstat (limited to 'src/parse.c')
-rw-r--r--src/parse.c1020
1 files changed, 445 insertions, 575 deletions
diff --git a/src/parse.c b/src/parse.c
index 06184b97..9f6f1581 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -14,9 +14,9 @@
#include <unistr.h>
#endif
+#include <signal.h>
#include <unictype.h>
#include <uniname.h>
-#include <signal.h>
#include "ast.h"
#include "stdlib/print.h"
@@ -32,7 +32,7 @@
#endif
static const double RADIANS_PER_DEGREE = 0.0174532925199432957692369076848861271344287188854172545609719144;
-static const char closing[128] = {['(']=')', ['[']=']', ['<']='>', ['{']='}'};
+static const char closing[128] = {['('] = ')', ['['] = ']', ['<'] = '>', ['{'] = '}'};
typedef struct {
file_t *file;
@@ -45,26 +45,40 @@ typedef struct {
#define PARSER(name) ast_t *name(parse_ctx_t *ctx, const char *pos)
int op_tightness[] = {
- [Power]=9,
- [Multiply]=8, [Divide]=8, [Mod]=8, [Mod1]=8,
- [Plus]=7, [Minus]=7,
- [Concat]=6,
- [LeftShift]=5, [RightShift]=5, [UnsignedLeftShift]=5, [UnsignedRightShift]=5,
- [Min]=4, [Max]=4,
- [Equals]=3, [NotEquals]=3,
- [LessThan]=2, [LessThanOrEquals]=2, [GreaterThan]=2, [GreaterThanOrEquals]=2,
- [Compare]=2,
- [And]=1, [Or]=1, [Xor]=1,
+ [Power] = 9,
+ [Multiply] = 8,
+ [Divide] = 8,
+ [Mod] = 8,
+ [Mod1] = 8,
+ [Plus] = 7,
+ [Minus] = 7,
+ [Concat] = 6,
+ [LeftShift] = 5,
+ [RightShift] = 5,
+ [UnsignedLeftShift] = 5,
+ [UnsignedRightShift] = 5,
+ [Min] = 4,
+ [Max] = 4,
+ [Equals] = 3,
+ [NotEquals] = 3,
+ [LessThan] = 2,
+ [LessThanOrEquals] = 2,
+ [GreaterThan] = 2,
+ [GreaterThanOrEquals] = 2,
+ [Compare] = 2,
+ [And] = 1,
+ [Or] = 1,
+ [Xor] = 1,
};
static const char *keywords[] = {
- "C_code", "_max_", "_min_", "and", "assert", "break", "continue", "defer", "deserialize", "do", "else",
- "enum", "extend", "extern", "for", "func", "if", "in", "lang", "mod", "mod1", "no", "none",
- "not", "or", "pass", "return", "skip", "skip", "stop", "struct", "then", "unless", "use", "when",
- "while", "xor", "yes",
+ "C_code", "_max_", "_min_", "and", "assert", "break", "continue", "defer", "deserialize", "do",
+ "else", "enum", "extend", "extern", "for", "func", "if", "in", "lang", "mod",
+ "mod1", "no", "none", "not", "or", "pass", "return", "skip", "skip", "stop",
+ "struct", "then", "unless", "use", "when", "while", "xor", "yes",
};
-enum {NORMAL_FUNCTION=0, EXTERN_FUNCTION=1};
+enum { NORMAL_FUNCTION = 0, EXTERN_FUNCTION = 1 };
static INLINE size_t some_of(const char **pos, const char *allow);
static INLINE size_t some_not(const char **pos, const char *forbid);
@@ -72,8 +86,8 @@ static INLINE size_t spaces(const char **pos);
static INLINE void whitespace(const char **pos);
static INLINE size_t match(const char **pos, const char *target);
static INLINE size_t match_word(const char **pos, const char *word);
-static INLINE const char* get_word(const char **pos);
-static INLINE const char* get_id(const char **pos);
+static INLINE const char *get_word(const char **pos);
+static INLINE const char *get_id(const char **pos);
static INLINE bool comment(const char **pos);
static INLINE bool indent(parse_ctx_t *ctx, const char **pos);
static INLINE ast_e match_binary_operator(const char **pos);
@@ -145,83 +159,83 @@ static PARSER(parse_var);
static PARSER(parse_when);
static PARSER(parse_while);
static PARSER(parse_deserialize);
-static ast_list_t *_parse_text_helper(parse_ctx_t *ctx, const char **out_pos, char open_quote, char close_quote, char open_interp, bool allow_escapes);
+static ast_list_t *_parse_text_helper(parse_ctx_t *ctx, const char **out_pos, char open_quote, char close_quote,
+ char open_interp, bool allow_escapes);
//
// Print a parse error and exit (or use the on_err longjmp)
//
-#define parser_err(ctx, start, end, ...) ({ \
- if (USE_COLOR) \
- fputs("\x1b[31;1;7m", stderr); \
- fprint_inline(stderr, (ctx)->file->relative_filename, ":", get_line_number((ctx)->file, (start)), \
- ".", get_line_column((ctx)->file, (start)), ": ", __VA_ARGS__); \
- if (USE_COLOR) \
- fputs(" \x1b[m", stderr); \
- fputs("\n\n", stderr); \
- highlight_error((ctx)->file, (start), (end), "\x1b[31;1;7m", 2, USE_COLOR); \
- fputs("\n", stderr); \
- if (getenv("TOMO_STACKTRACE")) \
- print_stacktrace(stderr, 1); \
- if ((ctx)->on_err) \
- longjmp(*((ctx)->on_err), 1); \
- raise(SIGABRT); \
- exit(1); \
-})
+#define parser_err(ctx, start, end, ...) \
+ ({ \
+ if (USE_COLOR) fputs("\x1b[31;1;7m", stderr); \
+ fprint_inline(stderr, (ctx)->file->relative_filename, ":", get_line_number((ctx)->file, (start)), ".", \
+ get_line_column((ctx)->file, (start)), ": ", __VA_ARGS__); \
+ if (USE_COLOR) fputs(" \x1b[m", stderr); \
+ fputs("\n\n", stderr); \
+ highlight_error((ctx)->file, (start), (end), "\x1b[31;1;7m", 2, USE_COLOR); \
+ fputs("\n", stderr); \
+ if (getenv("TOMO_STACKTRACE")) print_stacktrace(stderr, 1); \
+ if ((ctx)->on_err) longjmp(*((ctx)->on_err), 1); \
+ raise(SIGABRT); \
+ exit(1); \
+ })
//
// Expect a string (potentially after whitespace) and emit a parser error if it's not there
//
-#define expect_str(ctx, start, pos, target, ...) ({ \
- spaces(pos); \
- if (!match(pos, target)) { \
- if (USE_COLOR) \
- fputs("\x1b[31;1;7m", stderr); \
- parser_err(ctx, start, *pos, __VA_ARGS__); \
- } \
- char _lastchar = target[strlen(target)-1]; \
- if (isalpha(_lastchar) || isdigit(_lastchar) || _lastchar == '_') { \
- if (is_xid_continue_next(*pos)) { \
- if (USE_COLOR) \
- fputs("\x1b[31;1;7m", stderr); \
- parser_err(ctx, start, *pos, __VA_ARGS__); \
- } \
- } \
-})
+#define expect_str(ctx, start, pos, target, ...) \
+ ({ \
+ spaces(pos); \
+ if (!match(pos, target)) { \
+ if (USE_COLOR) fputs("\x1b[31;1;7m", stderr); \
+ parser_err(ctx, start, *pos, __VA_ARGS__); \
+ } \
+ char _lastchar = target[strlen(target) - 1]; \
+ if (isalpha(_lastchar) || isdigit(_lastchar) || _lastchar == '_') { \
+ if (is_xid_continue_next(*pos)) { \
+ if (USE_COLOR) fputs("\x1b[31;1;7m", stderr); \
+ parser_err(ctx, start, *pos, __VA_ARGS__); \
+ } \
+ } \
+ })
//
// Helper for matching closing parens with good error messages
//
-#define expect_closing(ctx, pos, close_str, ...) ({ \
- const char *_start = *pos; \
- spaces(pos); \
- if (!match(pos, (close_str))) { \
- const char *_eol = strchr(*pos, '\n'); \
- const char *_next = strstr(*pos, (close_str)); \
- const char *_end = _eol < _next ? _eol : _next; \
- if (USE_COLOR) \
- fputs("\x1b[31;1;7m", stderr); \
- parser_err(ctx, _start, _end, __VA_ARGS__); \
- } \
-})
-
-#define expect(ctx, start, pos, parser, ...) ({ \
- const char **_pos = pos; \
- spaces(_pos); \
- __typeof(parser(ctx, *_pos)) _result = parser(ctx, *_pos); \
- if (!_result) { \
- if (USE_COLOR) \
- fputs("\x1b[31;1;7m", stderr); \
- parser_err(ctx, start, *_pos, __VA_ARGS__); \
- } \
- *_pos = _result->end; \
- _result; })
-
-#define optional(ctx, pos, parser) ({ \
- const char **_pos = pos; \
- spaces(_pos); \
- __typeof(parser(ctx, *_pos)) _result = parser(ctx, *_pos); \
- if (_result) *_pos = _result->end; \
- _result; })
+#define expect_closing(ctx, pos, close_str, ...) \
+ ({ \
+ const char *_start = *pos; \
+ spaces(pos); \
+ if (!match(pos, (close_str))) { \
+ const char *_eol = strchr(*pos, '\n'); \
+ const char *_next = strstr(*pos, (close_str)); \
+ const char *_end = _eol < _next ? _eol : _next; \
+ if (USE_COLOR) fputs("\x1b[31;1;7m", stderr); \
+ parser_err(ctx, _start, _end, __VA_ARGS__); \
+ } \
+ })
+
+#define expect(ctx, start, pos, parser, ...) \
+ ({ \
+ const char **_pos = pos; \
+ spaces(_pos); \
+ __typeof(parser(ctx, *_pos)) _result = parser(ctx, *_pos); \
+ if (!_result) { \
+ if (USE_COLOR) fputs("\x1b[31;1;7m", stderr); \
+ parser_err(ctx, start, *_pos, __VA_ARGS__); \
+ } \
+ *_pos = _result->end; \
+ _result; \
+ })
+
+#define optional(ctx, pos, parser) \
+ ({ \
+ const char **_pos = pos; \
+ spaces(_pos); \
+ __typeof(parser(ctx, *_pos)) _result = parser(ctx, *_pos); \
+ if (_result) *_pos = _result->end; \
+ _result; \
+ })
//
// Convert an escape sequence like \n to a string
@@ -233,7 +247,8 @@ static ast_list_t *_parse_text_helper(parse_ctx_t *ctx, const char **out_pos, ch
static const char *unescape(parse_ctx_t *ctx, const char **out) {
const char **endpos = out;
const char *escape = *out;
- static const char *unescapes[256] = {['a']="\a",['b']="\b",['e']="\x1b",['f']="\f",['n']="\n",['r']="\r",['t']="\t",['v']="\v",['_']=" "};
+ static const char *unescapes[256] = {['a'] = "\a", ['b'] = "\b", ['e'] = "\x1b", ['f'] = "\f", ['n'] = "\n",
+ ['r'] = "\r", ['t'] = "\t", ['v'] = "\v", ['_'] = " "};
assert(*escape == '\\');
if (unescapes[(int)escape[1]]) {
*endpos = escape + 2;
@@ -241,16 +256,14 @@ static const char *unescape(parse_ctx_t *ctx, const char **out) {
} else if (escape[1] == '[') {
// ANSI Control Sequence Indicator: \033 [ ... m
size_t len = strcspn(&escape[2], "\r\n]");
- if (escape[2+len] != ']')
- parser_err(ctx, escape, escape + 2 + len, "Missing closing ']'");
+ if (escape[2 + len] != ']') parser_err(ctx, escape, escape + 2 + len, "Missing closing ']'");
*endpos = escape + 3 + len;
return String("\033[", string_slice(&escape[2], len), "m");
} else if (escape[1] == '{') {
// Unicode codepoints by name
size_t len = strcspn(&escape[2], "\r\n}");
- if (escape[2+len] != '}')
- parser_err(ctx, escape, escape + 2 + len, "Missing closing '}'");
- char name[len+1];
+ if (escape[2 + len] != '}') parser_err(ctx, escape, escape + 2 + len, "Missing closing '}'");
+ char name[len + 1];
memcpy(name, &escape[2], len);
name[len] = '\0';
@@ -260,25 +273,24 @@ static const char *unescape(parse_ctx_t *ctx, const char **out) {
}
// Unicode codepoints by hex
char *endptr = NULL;
- long codepoint = strtol(name+1, &endptr, 16);
+ long codepoint = strtol(name + 1, &endptr, 16);
uint32_t ustr[2] = {codepoint, 0};
size_t bufsize = 8;
uint8_t buf[bufsize];
(void)u32_to_u8(ustr, bufsize, buf, &bufsize);
*endpos = escape + 3 + len;
- return GC_strndup((char*)buf, bufsize);
+ return GC_strndup((char *)buf, bufsize);
}
- look_up_unicode_name:;
+ look_up_unicode_name:;
uint32_t codepoint = unicode_name_character(name);
if (codepoint == UNINAME_INVALID)
- parser_err(ctx, escape, escape + 3 + len,
- "Invalid unicode codepoint name: ", quoted(name));
+ parser_err(ctx, escape, escape + 3 + len, "Invalid unicode codepoint name: ", quoted(name));
*endpos = escape + 3 + len;
char *str = GC_MALLOC_ATOMIC(16);
size_t u8_len = 16;
- (void)u32_to_u8(&codepoint, 1, (uint8_t*)str, &u8_len);
+ (void)u32_to_u8(&codepoint, 1, (uint8_t *)str, &u8_len);
str[u8_len] = '\0';
return str;
} else if (escape[1] == 'x' && escape[2] && escape[3]) {
@@ -287,14 +299,15 @@ static const char *unescape(parse_ctx_t *ctx, const char **out) {
char c = (char)strtol(buf, NULL, 16);
*endpos = escape + 4;
return GC_strndup(&c, 1);
- } else if ('0' <= escape[1] && escape[1] <= '7' && '0' <= escape[2] && escape[2] <= '7' && '0' <= escape[3] && escape[3] <= '7') {
+ } else if ('0' <= escape[1] && escape[1] <= '7' && '0' <= escape[2] && escape[2] <= '7' && '0' <= escape[3]
+ && escape[3] <= '7') {
char buf[] = {escape[1], escape[2], escape[3], 0};
char c = (char)strtol(buf, NULL, 8);
*endpos = escape + 4;
return GC_strndup(&c, 1);
} else {
*endpos = escape + 2;
- return GC_strndup(escape+1, 1);
+ return GC_strndup(escape + 1, 1);
}
}
#ifdef __GNUC__
@@ -302,8 +315,7 @@ static const char *unescape(parse_ctx_t *ctx, const char **out) {
#endif
// Indent is in number of spaces (assuming that \t is 4 spaces)
-PUREFUNC static INLINE int64_t get_indent(parse_ctx_t *ctx, const char *pos)
-{
+PUREFUNC static INLINE int64_t get_indent(parse_ctx_t *ctx, const char *pos) {
int64_t line_num = get_line_number(ctx->file, pos);
const char *line = get_line(ctx->file, line_num);
if (line == NULL) {
@@ -311,12 +323,14 @@ PUREFUNC static INLINE int64_t get_indent(parse_ctx_t *ctx, const char *pos)
} else if (*line == ' ') {
int64_t spaces = (int64_t)strspn(line, " ");
if (line[spaces] == '\t')
- parser_err(ctx, line + spaces, line + spaces + 1, "This is a tab following spaces, and you can't mix tabs and spaces");
+ parser_err(ctx, line + spaces, line + spaces + 1,
+ "This is a tab following spaces, and you can't mix tabs and spaces");
return spaces;
} else if (*line == '\t') {
int64_t indent = (int64_t)strspn(line, "\t");
if (line[indent] == ' ')
- parser_err(ctx, line + indent, line + indent + 1, "This is a space following tabs, and you can't mix tabs and spaces");
+ parser_err(ctx, line + indent, line + indent + 1,
+ "This is a space following tabs, and you can't mix tabs and spaces");
return indent * SPACES_PER_INDENT;
} else {
return 0;
@@ -338,9 +352,7 @@ size_t some_not(const char **pos, const char *forbid) {
return len;
}
-size_t spaces(const char **pos) {
- return some_of(pos, " \t");
-}
+size_t spaces(const char **pos) { return some_of(pos, " \t"); }
void whitespace(const char **pos) {
while (some_of(pos, " \t\r\n") || comment(pos))
@@ -349,23 +361,21 @@ void whitespace(const char **pos) {
size_t match(const char **pos, const char *target) {
size_t len = strlen(target);
- if (strncmp(*pos, target, len) != 0)
- return 0;
+ if (strncmp(*pos, target, len) != 0) return 0;
*pos += len;
return len;
}
static INLINE bool is_xid_continue_next(const char *pos) {
ucs4_t point = 0;
- u8_next(&point, (const uint8_t*)pos);
+ u8_next(&point, (const uint8_t *)pos);
return uc_is_property_xid_continue(point);
}
size_t match_word(const char **out, const char *word) {
const char *pos = *out;
spaces(&pos);
- if (!match(&pos, word) || is_xid_continue_next(pos))
- return 0;
+ if (!match(&pos, word) || is_xid_continue_next(pos)) return 0;
*out = pos;
return strlen(word);
@@ -374,31 +384,26 @@ size_t match_word(const char **out, const char *word) {
const char *get_word(const char **inout) {
const char *word = *inout;
spaces(&word);
- const uint8_t *pos = (const uint8_t*)word;
+ const uint8_t *pos = (const uint8_t *)word;
ucs4_t point;
pos = u8_next(&point, pos);
- if (!uc_is_property_xid_start(point) && point != '_')
- return NULL;
+ if (!uc_is_property_xid_start(point) && point != '_') return NULL;
for (const uint8_t *next; (next = u8_next(&point, pos)); pos = next) {
- if (!uc_is_property_xid_continue(point))
- break;
+ if (!uc_is_property_xid_continue(point)) break;
}
- *inout = (const char*)pos;
- return GC_strndup(word, (size_t)((const char*)pos - word));
+ *inout = (const char *)pos;
+ return GC_strndup(word, (size_t)((const char *)pos - word));
}
static CONSTFUNC bool is_keyword(const char *word) {
- int64_t lo = 0, hi = sizeof(keywords)/sizeof(keywords[0])-1;
+ int64_t lo = 0, hi = sizeof(keywords) / sizeof(keywords[0]) - 1;
while (lo <= hi) {
int64_t mid = (lo + hi) / 2;
int32_t cmp = strcmp(word, keywords[mid]);
- if (cmp == 0)
- return true;
- else if (cmp > 0)
- lo = mid + 1;
- else if (cmp < 0)
- hi = mid - 1;
+ if (cmp == 0) return true;
+ else if (cmp > 0) lo = mid + 1;
+ else if (cmp < 0) hi = mid - 1;
}
return false;
}
@@ -406,15 +411,12 @@ static CONSTFUNC bool is_keyword(const char *word) {
const char *get_id(const char **inout) {
const char *pos = *inout;
const char *word = get_word(&pos);
- if (!word || is_keyword(word))
- return NULL;
+ if (!word || is_keyword(word)) return NULL;
*inout = pos;
return word;
}
-static const char *eol(const char *str) {
- return str + strcspn(str, "\r\n");
-}
+static const char *eol(const char *str) { return str + strcspn(str, "\r\n"); }
bool comment(const char **pos) {
if ((*pos)[0] == '#') {
@@ -430,11 +432,9 @@ bool indent(parse_ctx_t *ctx, const char **out) {
int64_t starting_indent = get_indent(ctx, pos);
whitespace(&pos);
const char *next_line = get_line(ctx->file, get_line_number(ctx->file, pos));
- if (next_line <= *out)
- return false;
+ if (next_line <= *out) return false;
- if (get_indent(ctx, next_line) != starting_indent + SPACES_PER_INDENT)
- return false;
+ if (get_indent(ctx, next_line) != starting_indent + SPACES_PER_INDENT) return false;
*out = next_line + strspn(next_line, " \t");
return true;
@@ -486,8 +486,7 @@ PARSER(parse_parens) {
expect_closing(ctx, &pos, ")", "I wasn't able to parse the rest of this expression");
// Update the span to include the parens:
- return new(ast_t, .file=(ctx)->file, .start=start, .end=pos,
- .tag=expr->tag, .__data=expr->__data);
+ return new (ast_t, .file = (ctx)->file, .start = start, .end = pos, .tag = expr->tag, .__data = expr->__data);
}
PARSER(parse_int) {
@@ -505,7 +504,7 @@ PARSER(parse_int) {
}
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) {
+ for (char *src = (char *)start, *dest = str; src < pos; ++src) {
if (*src != '_') *(dest++) = *src;
}
@@ -514,13 +513,13 @@ PARSER(parse_int) {
if (match(&pos, "%")) {
double n = strtod(str, NULL) / 100.;
- return NewAST(ctx->file, start, pos, Num, .n=n);
+ 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, Num, .n = n);
}
- return NewAST(ctx->file, start, pos, Int, .str=str);
+ return NewAST(ctx->file, start, pos, Int, .str = str);
}
type_ast_t *parse_table_type(parse_ctx_t *ctx, const char *pos) {
@@ -541,11 +540,13 @@ type_ast_t *parse_table_type(parse_ctx_t *ctx, const char *pos) {
ast_t *default_value = NULL;
if (match(&pos, ";") && match_word(&pos, "default")) {
expect_str(ctx, pos, &pos, "=", "I expected an '=' here");
- default_value = expect(ctx, start, &pos, parse_extended_expr, "I couldn't parse the default value for this table");
+ default_value =
+ expect(ctx, start, &pos, parse_extended_expr, "I couldn't parse the default value for this table");
}
whitespace(&pos);
expect_closing(ctx, &pos, "}", "I wasn't able to parse the rest of this table type");
- return NewTypeAST(ctx->file, start, pos, TableTypeAST, .key=key_type, .value=value_type, .default_value=default_value);
+ return NewTypeAST(ctx->file, start, pos, TableTypeAST, .key = key_type, .value = value_type,
+ .default_value = default_value);
}
type_ast_t *parse_set_type(parse_ctx_t *ctx, const char *pos) {
@@ -557,7 +558,7 @@ type_ast_t *parse_set_type(parse_ctx_t *ctx, const char *pos) {
pos = item_type->end;
whitespace(&pos);
expect_closing(ctx, &pos, "|", "I wasn't able to parse the rest of this set type");
- return NewTypeAST(ctx->file, start, pos, SetTypeAST, .item=item_type);
+ return NewTypeAST(ctx->file, start, pos, SetTypeAST, .item = item_type);
}
type_ast_t *parse_func_type(parse_ctx_t *ctx, const char *pos) {
@@ -569,35 +570,31 @@ type_ast_t *parse_func_type(parse_ctx_t *ctx, const char *pos) {
spaces(&pos);
type_ast_t *ret = match(&pos, "->") ? optional(ctx, &pos, parse_type) : NULL;
expect_closing(ctx, &pos, ")", "I wasn't able to parse the rest of this function type");
- return NewTypeAST(ctx->file, start, pos, FunctionTypeAST, .args=args, .ret=ret);
+ return NewTypeAST(ctx->file, start, pos, FunctionTypeAST, .args = args, .ret = ret);
}
type_ast_t *parse_list_type(parse_ctx_t *ctx, const char *pos) {
const char *start = pos;
if (!match(&pos, "[")) return NULL;
- type_ast_t *type = expect(ctx, start, &pos, parse_type,
- "I couldn't parse a list item type after this point");
+ type_ast_t *type = expect(ctx, start, &pos, parse_type, "I couldn't parse a list item type after this point");
expect_closing(ctx, &pos, "]", "I wasn't able to parse the rest of this list type");
- return NewTypeAST(ctx->file, start, pos, ListTypeAST, .item=type);
+ return NewTypeAST(ctx->file, start, pos, ListTypeAST, .item = type);
}
type_ast_t *parse_pointer_type(parse_ctx_t *ctx, const char *pos) {
const char *start = pos;
bool is_stack;
- if (match(&pos, "@"))
- is_stack = false;
- else if (match(&pos, "&"))
- is_stack = true;
- else
- return NULL;
+ if (match(&pos, "@")) is_stack = false;
+ else if (match(&pos, "&")) is_stack = true;
+ else return NULL;
spaces(&pos);
- type_ast_t *type = expect(ctx, start, &pos, parse_non_optional_type,
- "I couldn't parse a pointer type after this point");
- type_ast_t *ptr_type = NewTypeAST(ctx->file, start, pos, PointerTypeAST, .pointed=type, .is_stack=is_stack);
+ type_ast_t *type =
+ expect(ctx, start, &pos, parse_non_optional_type, "I couldn't parse a pointer type after this point");
+ type_ast_t *ptr_type = NewTypeAST(ctx->file, start, pos, PointerTypeAST, .pointed = type, .is_stack = is_stack);
spaces(&pos);
while (match(&pos, "?"))
- ptr_type = NewTypeAST(ctx->file, start, pos, OptionalTypeAST, .type=ptr_type);
+ ptr_type = NewTypeAST(ctx->file, start, pos, OptionalTypeAST, .type = ptr_type);
return ptr_type;
}
@@ -614,20 +611,15 @@ type_ast_t *parse_type_name(parse_ctx_t *ctx, const char *pos) {
id = String(id, ".", next_id);
pos = next;
}
- return NewTypeAST(ctx->file, start, pos, VarTypeAST, .name=id);
+ return NewTypeAST(ctx->file, start, pos, VarTypeAST, .name = id);
}
type_ast_t *parse_non_optional_type(parse_ctx_t *ctx, const char *pos) {
const char *start = pos;
type_ast_t *type = NULL;
- bool success = (false
- || (type=parse_pointer_type(ctx, pos))
- || (type=parse_list_type(ctx, pos))
- || (type=parse_table_type(ctx, pos))
- || (type=parse_set_type(ctx, pos))
- || (type=parse_type_name(ctx, pos))
- || (type=parse_func_type(ctx, pos))
- );
+ bool success = (false || (type = parse_pointer_type(ctx, pos)) || (type = parse_list_type(ctx, pos))
+ || (type = parse_table_type(ctx, pos)) || (type = parse_set_type(ctx, pos))
+ || (type = parse_type_name(ctx, pos)) || (type = parse_func_type(ctx, pos)));
if (!success && match(&pos, "(")) {
whitespace(&pos);
type = optional(ctx, &pos, parse_type);
@@ -648,7 +640,7 @@ type_ast_t *parse_type(parse_ctx_t *ctx, const char *pos) {
pos = type->end;
spaces(&pos);
while (match(&pos, "?"))
- type = NewTypeAST(ctx->file, start, pos, OptionalTypeAST, .type=type);
+ type = NewTypeAST(ctx->file, start, pos, OptionalTypeAST, .type = type);
return type;
}
@@ -659,21 +651,17 @@ PARSER(parse_num) {
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 (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;
+ 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) {
+ 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);
@@ -681,22 +669,18 @@ PARSER(parse_num) {
if (negative) d *= -1;
- if (match(&pos, "%"))
- d /= 100.;
- else if (match(&pos, "deg"))
- d *= RADIANS_PER_DEGREE;
+ if (match(&pos, "%")) d /= 100.;
+ else if (match(&pos, "deg")) d *= RADIANS_PER_DEGREE;
- return NewAST(ctx->file, start, pos, Num, .n=d);
+ return NewAST(ctx->file, start, pos, Num, .n = d);
}
static INLINE bool match_separator(const char **pos) { // Either comma or newline
const char *p = *pos;
int separators = 0;
for (;;) {
- if (some_of(&p, "\r\n,"))
- ++separators;
- else if (!comment(&p) && !some_of(&p, " \t"))
- break;
+ if (some_of(&p, "\r\n,")) ++separators;
+ else if (!comment(&p) && !some_of(&p, " \t")) break;
}
if (separators > 0) {
*pos = p;
@@ -722,15 +706,14 @@ PARSER(parse_list) {
pos = suffixed->end;
suffixed = parse_comprehension_suffix(ctx, item);
}
- items = new(ast_list_t, .ast=item, .next=items);
- if (!match_separator(&pos))
- break;
+ items = new (ast_list_t, .ast = item, .next = items);
+ if (!match_separator(&pos)) break;
}
whitespace(&pos);
expect_closing(ctx, &pos, "]", "I wasn't able to parse the rest of this list");
REVERSE_LIST(items);
- return NewAST(ctx->file, start, pos, List, .items=items);
+ return NewAST(ctx->file, start, pos, List, .items = items);
}
PARSER(parse_table) {
@@ -746,17 +729,16 @@ PARSER(parse_table) {
if (!key) break;
whitespace(&pos);
if (!match(&pos, "=")) return NULL;
- ast_t *value = expect(ctx, pos-1, &pos, parse_expr, "I couldn't parse the value for this table entry");
- ast_t *entry = NewAST(ctx->file, entry_start, pos, TableEntry, .key=key, .value=value);
+ ast_t *value = expect(ctx, pos - 1, &pos, parse_expr, "I couldn't parse the value for this table entry");
+ ast_t *entry = NewAST(ctx->file, entry_start, pos, TableEntry, .key = key, .value = value);
ast_t *suffixed = parse_comprehension_suffix(ctx, entry);
while (suffixed) {
entry = suffixed;
pos = suffixed->end;
suffixed = parse_comprehension_suffix(ctx, entry);
}
- entries = new(ast_list_t, .ast=entry, .next=entries);
- if (!match_separator(&pos))
- break;
+ entries = new (ast_list_t, .ast = entry, .next = entries);
+ if (!match_separator(&pos)) break;
}
REVERSE_LIST(entries);
@@ -771,14 +753,12 @@ PARSER(parse_table) {
if (match_word(&pos, "fallback")) {
whitespace(&pos);
if (!match(&pos, "=")) parser_err(ctx, attr_start, pos, "I expected an '=' after 'fallback'");
- if (fallback)
- parser_err(ctx, attr_start, pos, "This table already has a fallback");
+ if (fallback) parser_err(ctx, attr_start, pos, "This table already has a fallback");
fallback = expect(ctx, attr_start, &pos, parse_expr, "I expected a fallback table");
} else if (match_word(&pos, "default")) {
whitespace(&pos);
if (!match(&pos, "=")) parser_err(ctx, attr_start, pos, "I expected an '=' after 'default'");
- if (default_value)
- parser_err(ctx, attr_start, pos, "This table already has a default");
+ if (default_value) parser_err(ctx, attr_start, pos, "This table already has a default");
default_value = expect(ctx, attr_start, &pos, parse_expr, "I expected a default value");
} else {
break;
@@ -791,13 +771,13 @@ PARSER(parse_table) {
whitespace(&pos);
expect_closing(ctx, &pos, "}", "I wasn't able to parse the rest of this table");
- return NewAST(ctx->file, start, pos, Table, .default_value=default_value, .entries=entries, .fallback=fallback);
+ return NewAST(ctx->file, start, pos, Table, .default_value = default_value, .entries = entries,
+ .fallback = fallback);
}
PARSER(parse_set) {
const char *start = pos;
- if (match(&pos, "||"))
- return NewAST(ctx->file, start, pos, Set);
+ if (match(&pos, "||")) return NewAST(ctx->file, start, pos, Set);
if (!match(&pos, "|")) return NULL;
whitespace(&pos);
@@ -813,9 +793,8 @@ PARSER(parse_set) {
pos = suffixed->end;
suffixed = parse_comprehension_suffix(ctx, item);
}
- items = new(ast_list_t, .ast=item, .next=items);
- if (!match_separator(&pos))
- break;
+ items = new (ast_list_t, .ast = item, .next = items);
+ if (!match_separator(&pos)) break;
}
REVERSE_LIST(items);
@@ -823,7 +802,7 @@ PARSER(parse_set) {
whitespace(&pos);
expect_closing(ctx, &pos, "|", "I wasn't able to parse the rest of this set");
- return NewAST(ctx->file, start, pos, Set, .items=items);
+ return NewAST(ctx->file, start, pos, Set, .items = items);
}
ast_t *parse_field_suffix(parse_ctx_t *ctx, ast_t *lhs) {
@@ -834,49 +813,41 @@ ast_t *parse_field_suffix(parse_ctx_t *ctx, ast_t *lhs) {
if (*pos == '.') return NULL;
whitespace(&pos);
bool dollar = match(&pos, "$");
- const char* field = get_id(&pos);
+ const char *field = get_id(&pos);
if (!field) return NULL;
if (dollar) field = String("$", field);
- return NewAST(ctx->file, lhs->start, pos, FieldAccess, .fielded=lhs, .field=field);
+ return NewAST(ctx->file, lhs->start, pos, FieldAccess, .fielded = lhs, .field = field);
}
ast_t *parse_optional_suffix(parse_ctx_t *ctx, ast_t *lhs) {
if (!lhs) return NULL;
const char *pos = lhs->end;
- if (match(&pos, "?"))
- return NewAST(ctx->file, lhs->start, pos, Optional, .value=lhs);
- else
- return NULL;
+ if (match(&pos, "?")) return NewAST(ctx->file, lhs->start, pos, Optional, .value = lhs);
+ else return NULL;
}
ast_t *parse_non_optional_suffix(parse_ctx_t *ctx, ast_t *lhs) {
if (!lhs) return NULL;
const char *pos = lhs->end;
- if (match(&pos, "!"))
- return NewAST(ctx->file, lhs->start, pos, NonOptional, .value=lhs);
- else
- return NULL;
+ if (match(&pos, "!")) return NewAST(ctx->file, lhs->start, pos, NonOptional, .value = lhs);
+ else return NULL;
}
PARSER(parse_reduction) {
const char *start = pos;
if (!match(&pos, "(")) return NULL;
-
+
whitespace(&pos);
ast_e op = match_binary_operator(&pos);
if (op == Unknown) return NULL;
- ast_t *key = NewAST(ctx->file, pos, pos, Var, .name="$");
- for (bool progress = true; progress; ) {
+ ast_t *key = NewAST(ctx->file, pos, pos, Var, .name = "$");
+ for (bool progress = true; progress;) {
ast_t *new_term;
- progress = (false
- || (new_term=parse_index_suffix(ctx, key))
- || (new_term=parse_method_call_suffix(ctx, key))
- || (new_term=parse_field_suffix(ctx, key))
- || (new_term=parse_fncall_suffix(ctx, key))
- || (new_term=parse_optional_suffix(ctx, key))
- || (new_term=parse_non_optional_suffix(ctx, key))
- );
+ progress =
+ (false || (new_term = parse_index_suffix(ctx, key)) || (new_term = parse_method_call_suffix(ctx, key))
+ || (new_term = parse_field_suffix(ctx, key)) || (new_term = parse_fncall_suffix(ctx, key))
+ || (new_term = parse_optional_suffix(ctx, key)) || (new_term = parse_non_optional_suffix(ctx, key)));
if (progress) key = new_term;
}
if (key && key->tag == Var) key = NULL;
@@ -897,7 +868,7 @@ PARSER(parse_reduction) {
whitespace(&pos);
expect_closing(ctx, &pos, ")", "I wasn't able to parse the rest of this reduction");
- return NewAST(ctx->file, start, pos, Reduction, .iter=iter, .op=op, .key=key);
+ return NewAST(ctx->file, start, pos, Reduction, .iter = iter, .op = op, .key = key);
}
ast_t *parse_index_suffix(parse_ctx_t *ctx, ast_t *lhs) {
@@ -910,7 +881,7 @@ ast_t *parse_index_suffix(parse_ctx_t *ctx, ast_t *lhs) {
whitespace(&pos);
bool unchecked = match(&pos, ";") && (spaces(&pos), match_word(&pos, "unchecked") != 0);
expect_closing(ctx, &pos, "]", "I wasn't able to parse the rest of this index");
- return NewAST(ctx->file, start, pos, Index, .indexed=lhs, .index=index, .unchecked=unchecked);
+ return NewAST(ctx->file, start, pos, Index, .indexed = lhs, .index = index, .unchecked = unchecked);
}
ast_t *parse_comprehension_suffix(parse_ctx_t *ctx, ast_t *expr) {
@@ -924,12 +895,10 @@ ast_t *parse_comprehension_suffix(parse_ctx_t *ctx, ast_t *expr) {
ast_list_t *vars = NULL;
for (;;) {
ast_t *var = optional(ctx, &pos, parse_var);
- if (var)
- vars = new(ast_list_t, .ast=var, .next=vars);
+ if (var) vars = new (ast_list_t, .ast = var, .next = vars);
spaces(&pos);
- if (!match(&pos, ","))
- break;
+ if (!match(&pos, ",")) break;
}
REVERSE_LIST(vars);
@@ -940,13 +909,13 @@ ast_t *parse_comprehension_suffix(parse_ctx_t *ctx, ast_t *expr) {
ast_t *filter = NULL;
if (match_word(&next_pos, "if")) {
pos = next_pos;
- filter = expect(ctx, pos-2, &pos, parse_expr, "I expected a condition for this 'if'");
+ filter = expect(ctx, pos - 2, &pos, parse_expr, "I expected a condition for this 'if'");
} else if (match_word(&next_pos, "unless")) {
pos = next_pos;
- filter = expect(ctx, pos-2, &pos, parse_expr, "I expected a condition for this 'unless'");
+ filter = expect(ctx, pos - 2, &pos, parse_expr, "I expected a condition for this 'unless'");
filter = WrapAST(filter, Not, filter);
}
- return NewAST(ctx->file, start, pos, Comprehension, .expr=expr, .vars=vars, .iter=iter, .filter=filter);
+ return NewAST(ctx->file, start, pos, Comprehension, .expr = expr, .vars = vars, .iter = iter, .filter = filter);
}
ast_t *parse_optional_conditional_suffix(parse_ctx_t *ctx, ast_t *stmt) {
@@ -955,12 +924,12 @@ ast_t *parse_optional_conditional_suffix(parse_ctx_t *ctx, ast_t *stmt) {
const char *start = stmt->start;
const char *pos = stmt->end;
if (match_word(&pos, "if")) {
- ast_t *condition = expect(ctx, pos-2, &pos, parse_expr, "I expected a condition for this 'if'");
- return NewAST(ctx->file, start, pos, If, .condition=condition, .body=stmt);
+ ast_t *condition = expect(ctx, pos - 2, &pos, parse_expr, "I expected a condition for this 'if'");
+ return NewAST(ctx->file, start, pos, If, .condition = condition, .body = stmt);
} else if (match_word(&pos, "unless")) {
- ast_t *condition = expect(ctx, pos-2, &pos, parse_expr, "I expected a condition for this 'unless'");
+ ast_t *condition = expect(ctx, pos - 2, &pos, parse_expr, "I expected a condition for this 'unless'");
condition = WrapAST(condition, Not, condition);
- return NewAST(ctx->file, start, pos, If, .condition=condition, .body=stmt);
+ return NewAST(ctx->file, start, pos, If, .condition = condition, .body = stmt);
} else {
return stmt;
}
@@ -972,22 +941,17 @@ PARSER(parse_if) {
int64_t starting_indent = get_indent(ctx, pos);
bool unless;
- if (match_word(&pos, "if"))
- unless = false;
- else if (match_word(&pos, "unless"))
- unless = true;
- else
- return NULL;
+ if (match_word(&pos, "if")) unless = false;
+ else if (match_word(&pos, "unless")) unless = true;
+ else return NULL;
ast_t *condition = unless ? NULL : optional(ctx, &pos, parse_declaration);
- if (!condition)
- condition = expect(ctx, start, &pos, parse_expr, "I expected to find a condition for this 'if'");
+ if (!condition) condition = expect(ctx, start, &pos, parse_expr, "I expected to find a condition for this 'if'");
- if (unless)
- condition = WrapAST(condition, Not, condition);
+ if (unless) condition = WrapAST(condition, Not, condition);
(void)match_word(&pos, "then"); // Optional 'then'
- ast_t *body = expect(ctx, start, &pos, parse_block, "I expected a body for this 'if' statement");
+ ast_t *body = expect(ctx, start, &pos, parse_block, "I expected a body for this 'if' statement");
const char *tmp = pos;
whitespace(&tmp);
@@ -997,10 +961,9 @@ PARSER(parse_if) {
pos = tmp;
spaces(&pos);
else_body = optional(ctx, &pos, parse_if);
- if (!else_body)
- else_body = expect(ctx, else_start, &pos, parse_block, "I expected a body for this 'else'");
+ if (!else_body) else_body = expect(ctx, else_start, &pos, parse_block, "I expected a body for this 'else'");
}
- return NewAST(ctx->file, start, pos, If, .condition=condition, .body=body, .else_body=else_body);
+ return NewAST(ctx->file, start, pos, If, .condition = condition, .body = body, .else_body = else_body);
}
PARSER(parse_when) {
@@ -1008,12 +971,10 @@ PARSER(parse_when) {
const char *start = pos;
int64_t starting_indent = get_indent(ctx, pos);
- if (!match_word(&pos, "when"))
- return NULL;
+ if (!match_word(&pos, "when")) return NULL;
ast_t *subject = optional(ctx, &pos, parse_declaration);
- if (!subject) subject = expect(ctx, start, &pos, parse_expr,
- "I expected to find an expression for this 'when'");
+ if (!subject) subject = expect(ctx, start, &pos, parse_expr, "I expected to find an expression for this 'when'");
when_clause_t *clauses = NULL;
const char *tmp = pos;
@@ -1023,14 +984,14 @@ PARSER(parse_when) {
spaces(&pos);
ast_t *pattern = expect(ctx, start, &pos, parse_expr, "I expected a pattern to match here");
spaces(&pos);
- when_clause_t *new_clauses = new(when_clause_t, .pattern=pattern, .next=clauses);
+ when_clause_t *new_clauses = new (when_clause_t, .pattern = pattern, .next = clauses);
while (match(&pos, ",")) {
pattern = expect(ctx, start, &pos, parse_expr, "I expected a pattern to match here");
- new_clauses = new(when_clause_t, .pattern=pattern, .next=new_clauses);
+ new_clauses = new (when_clause_t, .pattern = pattern, .next = new_clauses);
spaces(&pos);
}
(void)match_word(&pos, "then"); // Optional 'then'
- ast_t *body = expect(ctx, start, &pos, parse_block, "I expected a body for this 'when' clause");
+ ast_t *body = expect(ctx, start, &pos, parse_block, "I expected a body for this 'when' clause");
for (when_clause_t *c = new_clauses; c && c != clauses; c = c->next) {
c->body = body;
}
@@ -1044,9 +1005,9 @@ PARSER(parse_when) {
const char *else_start = pos;
if (get_indent(ctx, tmp) == starting_indent && match_word(&tmp, "else")) {
pos = tmp;
- else_body = expect(ctx, else_start, &pos, parse_block, "I expected a body for this 'else'");
+ else_body = expect(ctx, else_start, &pos, parse_block, "I expected a body for this 'else'");
}
- return NewAST(ctx->file, start, pos, When, .subject=subject, .clauses=clauses, .else_body=else_body);
+ return NewAST(ctx->file, start, pos, When, .subject = subject, .clauses = clauses, .else_body = else_body);
}
PARSER(parse_for) {
@@ -1058,12 +1019,10 @@ PARSER(parse_for) {
ast_list_t *vars = NULL;
for (;;) {
ast_t *var = optional(ctx, &pos, parse_var);
- if (var)
- vars = new(ast_list_t, .ast=var, .next=vars);
+ if (var) vars = new (ast_list_t, .ast = var, .next = vars);
spaces(&pos);
- if (!match(&pos, ","))
- break;
+ if (!match(&pos, ",")) break;
}
spaces(&pos);
@@ -1073,7 +1032,7 @@ PARSER(parse_for) {
(void)match_word(&pos, "do"); // Optional 'do'
- ast_t *body = expect(ctx, start, &pos, parse_block, "I expected a body for this 'for'");
+ ast_t *body = expect(ctx, start, &pos, parse_block, "I expected a body for this 'for'");
const char *else_start = pos;
whitespace(&else_start);
@@ -1083,15 +1042,15 @@ PARSER(parse_for) {
empty = expect(ctx, pos, &pos, parse_block, "I expected a body for this 'else'");
}
REVERSE_LIST(vars);
- return NewAST(ctx->file, start, pos, For, .vars=vars, .iter=iter, .body=body, .empty=empty);
+ return NewAST(ctx->file, start, pos, For, .vars = vars, .iter = iter, .body = body, .empty = empty);
}
PARSER(parse_do) {
// do [<indent>] body
const char *start = pos;
if (!match_word(&pos, "do")) return NULL;
- ast_t *body = expect(ctx, start, &pos, parse_block, "I expected a body for this 'do'");
- return NewAST(ctx->file, start, pos, Block, .statements=Match(body, Block)->statements);
+ ast_t *body = expect(ctx, start, &pos, parse_block, "I expected a body for this 'do'");
+ return NewAST(ctx->file, start, pos, Block, .statements = Match(body, Block)->statements);
}
PARSER(parse_while) {
@@ -1104,22 +1063,22 @@ PARSER(parse_while) {
if (match_word(&tmp, "when")) {
ast_t *when = expect(ctx, start, &pos, parse_when, "I expected a 'when' block after this");
if (!when->__data.When.else_body) when->__data.When.else_body = NewAST(ctx->file, pos, pos, Stop);
- return NewAST(ctx->file, start, pos, While, .body=when);
+ return NewAST(ctx->file, start, pos, While, .body = when);
}
(void)match_word(&pos, "do"); // Optional 'do'
ast_t *condition = expect(ctx, start, &pos, parse_expr, "I don't see a viable condition for this 'while'");
- ast_t *body = expect(ctx, start, &pos, parse_block, "I expected a body for this 'while'");
- return NewAST(ctx->file, start, pos, While, .condition=condition, .body=body);
+ ast_t *body = expect(ctx, start, &pos, parse_block, "I expected a body for this 'while'");
+ return NewAST(ctx->file, start, pos, While, .condition = condition, .body = body);
}
PARSER(parse_repeat) {
// repeat [<indent>] body
const char *start = pos;
if (!match_word(&pos, "repeat")) return NULL;
- ast_t *body = expect(ctx, start, &pos, parse_block, "I expected a body for this 'repeat'");
- return NewAST(ctx->file, start, pos, Repeat, .body=body);
+ ast_t *body = expect(ctx, start, &pos, parse_block, "I expected a body for this 'repeat'");
+ return NewAST(ctx->file, start, pos, Repeat, .body = body);
}
PARSER(parse_heap_alloc) {
@@ -1130,16 +1089,14 @@ PARSER(parse_heap_alloc) {
for (;;) {
ast_t *new_term;
- if ((new_term=parse_index_suffix(ctx, val))
- || (new_term=parse_fncall_suffix(ctx, val))
- || (new_term=parse_method_call_suffix(ctx, val))
- || (new_term=parse_field_suffix(ctx, val))) {
+ if ((new_term = parse_index_suffix(ctx, val)) || (new_term = parse_fncall_suffix(ctx, val))
+ || (new_term = parse_method_call_suffix(ctx, val)) || (new_term = parse_field_suffix(ctx, val))) {
val = new_term;
} else break;
}
pos = val->end;
- ast_t *ast = NewAST(ctx->file, start, pos, HeapAllocate, .value=val);
+ ast_t *ast = NewAST(ctx->file, start, pos, HeapAllocate, .value = val);
for (;;) {
ast_t *next = parse_optional_suffix(ctx, ast);
if (!next) next = parse_non_optional_suffix(ctx, ast);
@@ -1157,16 +1114,14 @@ PARSER(parse_stack_reference) {
for (;;) {
ast_t *new_term;
- if ((new_term=parse_index_suffix(ctx, val))
- || (new_term=parse_fncall_suffix(ctx, val))
- || (new_term=parse_method_call_suffix(ctx, val))
- || (new_term=parse_field_suffix(ctx, val))) {
+ if ((new_term = parse_index_suffix(ctx, val)) || (new_term = parse_fncall_suffix(ctx, val))
+ || (new_term = parse_method_call_suffix(ctx, val)) || (new_term = parse_field_suffix(ctx, val))) {
val = new_term;
} else break;
}
pos = val->end;
- ast_t *ast = NewAST(ctx->file, start, pos, StackReference, .value=val);
+ ast_t *ast = NewAST(ctx->file, start, pos, StackReference, .value = val);
for (;;) {
ast_t *next = parse_optional_suffix(ctx, ast);
if (!next) next = parse_non_optional_suffix(ctx, ast);
@@ -1181,7 +1136,7 @@ PARSER(parse_not) {
if (!match_word(&pos, "not")) return NULL;
spaces(&pos);
ast_t *val = expect(ctx, start, &pos, parse_term, "I expected an expression for this 'not'");
- return NewAST(ctx->file, start, pos, Not, .value=val);
+ return NewAST(ctx->file, start, pos, Not, .value = val);
}
PARSER(parse_negative) {
@@ -1189,21 +1144,18 @@ PARSER(parse_negative) {
if (!match(&pos, "-")) return NULL;
spaces(&pos);
ast_t *val = expect(ctx, start, &pos, parse_term, "I expected an expression for this '-'");
- return NewAST(ctx->file, start, pos, Negative, .value=val);
+ return NewAST(ctx->file, start, pos, Negative, .value = val);
}
PARSER(parse_bool) {
const char *start = pos;
- if (match_word(&pos, "yes"))
- return NewAST(ctx->file, start, pos, Bool, .b=true);
- else if (match_word(&pos, "no"))
- return NewAST(ctx->file, start, pos, Bool, .b=false);
- else
- return NULL;
+ if (match_word(&pos, "yes")) return NewAST(ctx->file, start, pos, Bool, .b = true);
+ else if (match_word(&pos, "no")) return NewAST(ctx->file, start, pos, Bool, .b = false);
+ else return NULL;
}
-ast_list_t *_parse_text_helper(parse_ctx_t *ctx, const char **out_pos, char open_quote, char close_quote, char open_interp, bool allow_escapes)
-{
+ast_list_t *_parse_text_helper(parse_ctx_t *ctx, const char **out_pos, char open_quote, char close_quote,
+ char open_interp, bool allow_escapes) {
const char *pos = *out_pos;
int64_t starting_indent = get_indent(ctx, pos);
int64_t string_indent = starting_indent + SPACES_PER_INDENT;
@@ -1213,27 +1165,29 @@ ast_list_t *_parse_text_helper(parse_ctx_t *ctx, const char **out_pos, char open
int depth = 1;
bool leading_newline = false;
int64_t plain_span_len = 0;
-#define FLUSH_PLAIN_SPAN() do { \
- if (plain_span_len > 0) { \
- chunk = Texts(chunk, Text$from_strn(pos - plain_span_len, (size_t)plain_span_len)); \
- plain_span_len = 0; \
- } } while (0)
- for (const char *end = ctx->file->text + ctx->file->len; pos < end && depth > 0; ) {
+#define FLUSH_PLAIN_SPAN() \
+ do { \
+ if (plain_span_len > 0) { \
+ chunk = Texts(chunk, Text$from_strn(pos - plain_span_len, (size_t)plain_span_len)); \
+ plain_span_len = 0; \
+ } \
+ } while (0)
+ for (const char *end = ctx->file->text + ctx->file->len; pos < end && depth > 0;) {
const char *after_indentation = pos;
if (*pos == open_interp) { // Interpolation
FLUSH_PLAIN_SPAN();
const char *interp_start = pos;
if (chunk.length > 0) {
- ast_t *literal = NewAST(ctx->file, chunk_start, pos, TextLiteral, .text=chunk);
- chunks = new(ast_list_t, .ast=literal, .next=chunks);
+ ast_t *literal = NewAST(ctx->file, chunk_start, pos, TextLiteral, .text = chunk);
+ chunks = new (ast_list_t, .ast = literal, .next = chunks);
chunk = EMPTY_TEXT;
}
++pos;
ast_t *interp;
if (*pos == ' ' || *pos == '\t')
- parser_err(ctx, pos, pos+1, "Whitespace is not allowed before an interpolation here");
+ parser_err(ctx, pos, pos + 1, "Whitespace is not allowed before an interpolation here");
interp = expect(ctx, interp_start, &pos, parse_term_no_suffix, "I expected an interpolation term here");
- chunks = new(ast_list_t, .ast=interp, .next=chunks);
+ chunks = new (ast_list_t, .ast = interp, .next = chunks);
chunk_start = pos;
} else if (allow_escapes && *pos == '\\') {
FLUSH_PLAIN_SPAN();
@@ -1248,8 +1202,7 @@ ast_list_t *_parse_text_helper(parse_ctx_t *ctx, const char **out_pos, char open
} else if (!leading_newline && *pos == close_quote) { // Nested pair end
if (get_indent(ctx, pos) == starting_indent) {
--depth;
- if (depth == 0)
- break;
+ if (depth == 0) break;
}
plain_span_len += 1;
++pos;
@@ -1270,14 +1223,14 @@ ast_list_t *_parse_text_helper(parse_ctx_t *ctx, const char **out_pos, char open
// Multi-line split
continue;
} else {
- parser_err(ctx, pos, eol(pos), "This multi-line string should be either indented or have '..' at the front");
+ parser_err(ctx, pos, eol(pos),
+ "This multi-line string should be either indented or have '..' at the front");
}
} else { // Plain character
ucs4_t codepoint;
- const char *next = (const char*)u8_next(&codepoint, (const uint8_t*)pos);
+ const char *next = (const char *)u8_next(&codepoint, (const uint8_t *)pos);
plain_span_len += (int64_t)(next - pos);
- if (next == NULL)
- break;
+ if (next == NULL) break;
pos = next;
}
}
@@ -1286,8 +1239,8 @@ ast_list_t *_parse_text_helper(parse_ctx_t *ctx, const char **out_pos, char open
#undef FLUSH_PLAIN_SPAN
if (chunk.length > 0) {
- ast_t *literal = NewAST(ctx->file, chunk_start, pos, TextLiteral, .text=chunk);
- chunks = new(ast_list_t, .ast=literal, .next=chunks);
+ ast_t *literal = NewAST(ctx->file, chunk_start, pos, TextLiteral, .text = chunk);
+ chunks = new (ast_list_t, .ast = literal, .next = chunks);
chunk = EMPTY_TEXT;
}
@@ -1323,7 +1276,8 @@ PARSER(parse_text) {
}
static const char *quote_chars = "\"'`|/;([{<";
if (!strchr(quote_chars, *pos))
- parser_err(ctx, pos, pos+1, "This is not a valid string quotation character. Valid characters are: \"'`|/;([{<");
+ parser_err(ctx, pos, pos + 1,
+ "This is not a valid string quotation character. Valid characters are: \"'`|/;([{<");
open_quote = *pos;
++pos;
close_quote = closing[(int)open_quote] ? closing[(int)open_quote] : open_quote;
@@ -1334,18 +1288,16 @@ PARSER(parse_text) {
bool allow_escapes = (open_quote != '`');
ast_list_t *chunks = _parse_text_helper(ctx, &pos, open_quote, close_quote, open_interp, allow_escapes);
bool colorize = match(&pos, "~") && match_word(&pos, "colorized");
- return NewAST(ctx->file, start, pos, TextJoin, .lang=lang, .children=chunks, .colorize=colorize);
+ return NewAST(ctx->file, start, pos, TextJoin, .lang = lang, .children = chunks, .colorize = colorize);
}
PARSER(parse_path) {
// "(" ("~/" / "./" / "../" / "/") ... ")"
const char *start = pos;
- if (!match(&pos, "("))
- return NULL;
+ if (!match(&pos, "(")) return NULL;
- if (!(*pos == '~' || *pos == '.' || *pos == '/'))
- return NULL;
+ if (!(*pos == '~' || *pos == '.' || *pos == '/')) return NULL;
const char *path_start = pos;
size_t len = 1;
@@ -1360,13 +1312,13 @@ PARSER(parse_path) {
paren_depth -= 1;
if (paren_depth <= 0) break;
} else if (pos[len] == '\r' || pos[len] == '\n') {
- parser_err(ctx, path_start, &pos[len-1], "This path was not closed");
+ parser_err(ctx, path_start, &pos[len - 1], "This path was not closed");
}
len += 1;
}
pos += len + 1;
- char *path = String(string_slice(path_start, .length=len));
- for (char *src = path, *dest = path; ; ) {
+ char *path = String(string_slice(path_start, .length = len));
+ for (char *src = path, *dest = path;;) {
if (src[0] == '\\') {
*(dest++) = src[1];
src += 2;
@@ -1377,7 +1329,7 @@ PARSER(parse_path) {
break;
}
}
- return NewAST(ctx->file, start, pos, Path, .path=path);
+ return NewAST(ctx->file, start, pos, Path, .path = path);
}
PARSER(parse_pass) {
@@ -1389,7 +1341,7 @@ PARSER(parse_defer) {
const char *start = pos;
if (!match_word(&pos, "defer")) return NULL;
ast_t *body = expect(ctx, start, &pos, parse_block, "I expected a block to be deferred here");
- return NewAST(ctx->file, start, pos, Defer, .body=body);
+ return NewAST(ctx->file, start, pos, Defer, .body = body);
}
PARSER(parse_skip) {
@@ -1399,7 +1351,7 @@ PARSER(parse_skip) {
if (match_word(&pos, "for")) target = "for";
else if (match_word(&pos, "while")) target = "while";
else target = get_id(&pos);
- ast_t *skip = NewAST(ctx->file, start, pos, Skip, .target=target);
+ ast_t *skip = NewAST(ctx->file, start, pos, Skip, .target = target);
skip = parse_optional_conditional_suffix(ctx, skip);
return skip;
}
@@ -1411,7 +1363,7 @@ PARSER(parse_stop) {
if (match_word(&pos, "for")) target = "for";
else if (match_word(&pos, "while")) target = "while";
else target = get_id(&pos);
- ast_t *stop = NewAST(ctx->file, start, pos, Stop, .target=target);
+ ast_t *stop = NewAST(ctx->file, start, pos, Stop, .target = target);
stop = parse_optional_conditional_suffix(ctx, stop);
return stop;
}
@@ -1420,112 +1372,87 @@ PARSER(parse_return) {
const char *start = pos;
if (!match_word(&pos, "return")) return NULL;
ast_t *value = optional(ctx, &pos, parse_expr);
- ast_t *ret = NewAST(ctx->file, start, pos, Return, .value=value);
+ ast_t *ret = NewAST(ctx->file, start, pos, Return, .value = value);
ret = parse_optional_conditional_suffix(ctx, ret);
return ret;
}
PARSER(parse_lambda) {
const char *start = pos;
- if (!match_word(&pos, "func"))
- return NULL;
+ if (!match_word(&pos, "func")) return NULL;
spaces(&pos);
- if (!match(&pos, "("))
- return NULL;
+ if (!match(&pos, "(")) return NULL;
arg_ast_t *args = parse_args(ctx, &pos);
spaces(&pos);
type_ast_t *ret = match(&pos, "->") ? optional(ctx, &pos, parse_type) : NULL;
spaces(&pos);
expect_closing(ctx, &pos, ")", "I was expecting a ')' to finish this anonymous function's arguments");
ast_t *body = optional(ctx, &pos, parse_block);
- if (!body) body = NewAST(ctx->file, pos, pos, Block, .statements=NULL);
- return NewAST(ctx->file, start, pos, Lambda, .id=ctx->next_lambda_id++, .args=args, .ret_type=ret, .body=body);
+ if (!body) body = NewAST(ctx->file, pos, pos, Block, .statements = NULL);
+ return NewAST(ctx->file, start, pos, Lambda, .id = ctx->next_lambda_id++, .args = args, .ret_type = ret,
+ .body = body);
}
PARSER(parse_none) {
const char *start = pos;
- if (!match_word(&pos, "none"))
- return NULL;
+ if (!match_word(&pos, "none")) return NULL;
return NewAST(ctx->file, start, pos, None);
}
PARSER(parse_deserialize) {
const char *start = pos;
- if (!match_word(&pos, "deserialize"))
- return NULL;
+ if (!match_word(&pos, "deserialize")) return NULL;
spaces(&pos);
expect_str(ctx, start, &pos, "(", "I expected arguments for this `deserialize` call");
whitespace(&pos);
ast_t *value = expect(ctx, start, &pos, parse_extended_expr, "I expected an expression here");
whitespace(&pos);
- expect_str(ctx, start, &pos, "->", "I expected a `-> Type` for this `deserialize` call so I know what it deserializes to");
+ expect_str(ctx, start, &pos, "->",
+ "I expected a `-> Type` for this `deserialize` call so I know what it deserializes to");
whitespace(&pos);
type_ast_t *type = expect(ctx, start, &pos, parse_type, "I couldn't parse the type for this deserialization");
whitespace(&pos);
expect_closing(ctx, &pos, ")", "I expected a closing ')' for this `deserialize` call");
- return NewAST(ctx->file, start, pos, Deserialize, .value=value, .type=type);
+ return NewAST(ctx->file, start, pos, Deserialize, .value = value, .type = type);
}
PARSER(parse_var) {
const char *start = pos;
- const char* name = get_id(&pos);
+ const char *name = get_id(&pos);
if (!name) return NULL;
- return NewAST(ctx->file, start, pos, Var, .name=name);
+ return NewAST(ctx->file, start, pos, Var, .name = name);
}
PARSER(parse_term_no_suffix) {
spaces(&pos);
ast_t *term = NULL;
- (void)(
- false
- || (term=parse_none(ctx, pos))
- || (term=parse_num(ctx, pos)) // Must come before int
- || (term=parse_int(ctx, pos))
- || (term=parse_negative(ctx, pos)) // Must come after num/int
- || (term=parse_heap_alloc(ctx, pos))
- || (term=parse_stack_reference(ctx, pos))
- || (term=parse_bool(ctx, pos))
- || (term=parse_text(ctx, pos))
- || (term=parse_path(ctx, pos))
- || (term=parse_lambda(ctx, pos))
- || (term=parse_parens(ctx, pos))
- || (term=parse_table(ctx, pos))
- || (term=parse_set(ctx, pos))
- || (term=parse_deserialize(ctx, pos))
- || (term=parse_var(ctx, pos))
- || (term=parse_list(ctx, pos))
- || (term=parse_reduction(ctx, pos))
- || (term=parse_pass(ctx, pos))
- || (term=parse_defer(ctx, pos))
- || (term=parse_skip(ctx, pos))
- || (term=parse_stop(ctx, pos))
- || (term=parse_return(ctx, pos))
- || (term=parse_not(ctx, pos))
- || (term=parse_extern(ctx, pos))
- || (term=parse_inline_c(ctx, pos))
- );
+ (void)(false || (term = parse_none(ctx, pos)) || (term = parse_num(ctx, pos)) // Must come before int
+ || (term = parse_int(ctx, pos)) || (term = parse_negative(ctx, pos)) // Must come after num/int
+ || (term = parse_heap_alloc(ctx, pos)) || (term = parse_stack_reference(ctx, pos))
+ || (term = parse_bool(ctx, pos)) || (term = parse_text(ctx, pos)) || (term = parse_path(ctx, pos))
+ || (term = parse_lambda(ctx, pos)) || (term = parse_parens(ctx, pos)) || (term = parse_table(ctx, pos))
+ || (term = parse_set(ctx, pos)) || (term = parse_deserialize(ctx, pos)) || (term = parse_var(ctx, pos))
+ || (term = parse_list(ctx, pos)) || (term = parse_reduction(ctx, pos)) || (term = parse_pass(ctx, pos))
+ || (term = parse_defer(ctx, pos)) || (term = parse_skip(ctx, pos)) || (term = parse_stop(ctx, pos))
+ || (term = parse_return(ctx, pos)) || (term = parse_not(ctx, pos)) || (term = parse_extern(ctx, pos))
+ || (term = parse_inline_c(ctx, pos)));
return term;
}
PARSER(parse_term) {
const char *start = pos;
- if (match(&pos, "???"))
- parser_err(ctx, start, pos, "This value needs to be filled in!");
+ if (match(&pos, "???")) parser_err(ctx, start, pos, "This value needs to be filled in!");
ast_t *term = parse_term_no_suffix(ctx, pos);
if (!term) return NULL;
- for (bool progress = true; progress; ) {
+ for (bool progress = true; progress;) {
ast_t *new_term;
- progress = (false
- || (new_term=parse_index_suffix(ctx, term))
- || (new_term=parse_method_call_suffix(ctx, term))
- || (new_term=parse_field_suffix(ctx, term))
- || (new_term=parse_fncall_suffix(ctx, term))
- || (new_term=parse_optional_suffix(ctx, term))
- || (new_term=parse_non_optional_suffix(ctx, term))
- );
+ progress =
+ (false || (new_term = parse_index_suffix(ctx, term)) || (new_term = parse_method_call_suffix(ctx, term))
+ || (new_term = parse_field_suffix(ctx, term)) || (new_term = parse_fncall_suffix(ctx, term))
+ || (new_term = parse_optional_suffix(ctx, term)) || (new_term = parse_non_optional_suffix(ctx, term)));
if (progress) term = new_term;
}
return term;
@@ -1560,18 +1487,16 @@ ast_t *parse_method_call_suffix(parse_ctx_t *ctx, ast_t *self) {
if (name) parser_err(ctx, arg_start, pos, "I expected an argument here");
break;
}
- args = new(arg_ast_t, .name=name, .value=arg, .next=args);
- if (!match_separator(&pos))
- break;
+ args = new (arg_ast_t, .name = name, .value = arg, .next = args);
+ if (!match_separator(&pos)) break;
}
REVERSE_LIST(args);
whitespace(&pos);
- if (!match(&pos, ")"))
- parser_err(ctx, start, pos, "This parenthesis is unclosed");
+ if (!match(&pos, ")")) parser_err(ctx, start, pos, "This parenthesis is unclosed");
- return NewAST(ctx->file, start, pos, MethodCall, .self=self, .name=fn, .args=args);
+ return NewAST(ctx->file, start, pos, MethodCall, .self = self, .name = fn, .args = args);
}
ast_t *parse_fncall_suffix(parse_ctx_t *ctx, ast_t *fn) {
@@ -1596,26 +1521,22 @@ ast_t *parse_fncall_suffix(parse_ctx_t *ctx, ast_t *fn) {
ast_t *arg = optional(ctx, &pos, parse_expr);
if (!arg) {
- if (name)
- parser_err(ctx, arg_start, pos, "I expected an argument here");
+ if (name) parser_err(ctx, arg_start, pos, "I expected an argument here");
break;
}
- args = new(arg_ast_t, .name=name, .value=arg, .next=args);
- if (!match_separator(&pos))
- break;
+ args = new (arg_ast_t, .name = name, .value = arg, .next = args);
+ if (!match_separator(&pos)) break;
}
whitespace(&pos);
- if (!match(&pos, ")"))
- parser_err(ctx, start, pos, "This parenthesis is unclosed");
+ if (!match(&pos, ")")) parser_err(ctx, start, pos, "This parenthesis is unclosed");
REVERSE_LIST(args);
- return NewAST(ctx->file, start, pos, FunctionCall, .fn=fn, .args=args);
+ return NewAST(ctx->file, start, pos, FunctionCall, .fn = fn, .args = args);
}
-ast_e match_binary_operator(const char **pos)
-{
+ast_e match_binary_operator(const char **pos) {
switch (**pos) {
case '+': {
*pos += 1;
@@ -1633,20 +1554,18 @@ ast_e match_binary_operator(const char **pos)
case '<': {
*pos += 1;
if (match(pos, "=")) return LessThanOrEquals; // "<="
- else if (match(pos, ">")) return Compare; // "<>"
+ else if (match(pos, ">")) return Compare; // "<>"
else if (match(pos, "<")) {
- if (match(pos, "<"))
- return UnsignedLeftShift; // "<<<"
- return LeftShift; // "<<"
+ if (match(pos, "<")) return UnsignedLeftShift; // "<<<"
+ return LeftShift; // "<<"
} else return LessThan;
}
case '>': {
*pos += 1;
if (match(pos, "=")) return GreaterThanOrEquals; // ">="
if (match(pos, ">")) {
- if (match(pos, ">"))
- return UnsignedRightShift; // ">>>"
- return RightShift; // ">>"
+ if (match(pos, ">")) return UnsignedRightShift; // ">>>"
+ return RightShift; // ">>"
}
return GreaterThan;
}
@@ -1672,20 +1591,17 @@ static ast_t *parse_infix_expr(parse_ctx_t *ctx, const char *pos, int min_tightn
int64_t starting_line = get_line_number(ctx->file, pos);
int64_t starting_indent = get_indent(ctx, pos);
spaces(&pos);
- for (ast_e op; (op=match_binary_operator(&pos)) != Unknown && op_tightness[op] >= min_tightness; spaces(&pos)) {
+ for (ast_e op; (op = match_binary_operator(&pos)) != Unknown && op_tightness[op] >= min_tightness; spaces(&pos)) {
ast_t *key = NULL;
if (op == Min || op == Max) {
- key = NewAST(ctx->file, pos, pos, Var, .name="$");
- for (bool progress = true; progress; ) {
+ key = NewAST(ctx->file, pos, pos, Var, .name = "$");
+ for (bool progress = true; progress;) {
ast_t *new_term;
- progress = (false
- || (new_term=parse_index_suffix(ctx, key))
- || (new_term=parse_method_call_suffix(ctx, key))
- || (new_term=parse_field_suffix(ctx, key))
- || (new_term=parse_fncall_suffix(ctx, key))
- || (new_term=parse_optional_suffix(ctx, key))
- || (new_term=parse_non_optional_suffix(ctx, key))
- );
+ progress =
+ (false || (new_term = parse_index_suffix(ctx, key))
+ || (new_term = parse_method_call_suffix(ctx, key)) || (new_term = parse_field_suffix(ctx, key))
+ || (new_term = parse_fncall_suffix(ctx, key)) || (new_term = parse_optional_suffix(ctx, key))
+ || (new_term = parse_non_optional_suffix(ctx, key)));
if (progress) key = new_term;
}
if (key && key->tag == Var) key = NULL;
@@ -1699,21 +1615,20 @@ static ast_t *parse_infix_expr(parse_ctx_t *ctx, const char *pos, int min_tightn
ast_t *rhs = parse_infix_expr(ctx, pos, op_tightness[op] + 1);
if (!rhs) break;
pos = rhs->end;
-
+
if (op == Min) {
- return NewAST(ctx->file, lhs->start, rhs->end, Min, .lhs=lhs, .rhs=rhs, .key=key);
+ return NewAST(ctx->file, lhs->start, rhs->end, Min, .lhs = lhs, .rhs = rhs, .key = key);
} else if (op == Max) {
- return NewAST(ctx->file, lhs->start, rhs->end, Max, .lhs=lhs, .rhs=rhs, .key=key);
+ return NewAST(ctx->file, lhs->start, rhs->end, Max, .lhs = lhs, .rhs = rhs, .key = key);
} else {
- lhs = new(ast_t, .file=ctx->file, .start=lhs->start, .end=rhs->end, .tag=op, .__data.Plus.lhs=lhs, .__data.Plus.rhs=rhs);
+ lhs = new (ast_t, .file = ctx->file, .start = lhs->start, .end = rhs->end, .tag = op,
+ .__data.Plus.lhs = lhs, .__data.Plus.rhs = rhs);
}
}
return lhs;
}
-PARSER(parse_expr) {
- return parse_infix_expr(ctx, pos, 0);
-}
+PARSER(parse_expr) { return parse_infix_expr(ctx, pos, 0); }
PARSER(parse_declaration) {
const char *start = pos;
@@ -1731,17 +1646,15 @@ PARSER(parse_declaration) {
if (!val) {
if (optional(ctx, &pos, parse_use))
parser_err(ctx, start, pos, "'use' statements are only allowed at the top level of a file");
- else
- parser_err(ctx, pos, eol(pos), "This is not a valid expression");
+ else parser_err(ctx, pos, eol(pos), "This is not a valid expression");
}
}
- return NewAST(ctx->file, start, pos, Declare, .var=var, .type=type, .value=val);
+ return NewAST(ctx->file, start, pos, Declare, .var = var, .type = type, .value = val);
}
PARSER(parse_top_declaration) {
ast_t *declaration = parse_declaration(ctx, pos);
- if (declaration)
- declaration->__data.Declare.top_level = true;
+ if (declaration) declaration->__data.Declare.top_level = true;
return declaration;
}
@@ -1766,7 +1679,8 @@ PARSER(parse_update) {
else if (match(&pos, "xor=")) op = XorUpdate;
else return NULL;
ast_t *rhs = expect(ctx, start, &pos, parse_extended_expr, "I expected an expression here");
- return new(ast_t, .file=ctx->file, .start=start, .end=pos, .tag=op, .__data.PlusUpdate.lhs=lhs, .__data.PlusUpdate.rhs=rhs);
+ return new (ast_t, .file = ctx->file, .start = start, .end = pos, .tag = op, .__data.PlusUpdate.lhs = lhs,
+ .__data.PlusUpdate.rhs = rhs);
}
PARSER(parse_assignment) {
@@ -1775,7 +1689,7 @@ PARSER(parse_assignment) {
for (;;) {
ast_t *lhs = optional(ctx, &pos, parse_term);
if (!lhs) break;
- targets = new(ast_list_t, .ast=lhs, .next=targets);
+ targets = new (ast_list_t, .ast = lhs, .next = targets);
spaces(&pos);
if (!match(&pos, ",")) break;
whitespace(&pos);
@@ -1791,7 +1705,7 @@ PARSER(parse_assignment) {
for (;;) {
ast_t *rhs = optional(ctx, &pos, parse_extended_expr);
if (!rhs) break;
- values = new(ast_list_t, .ast=rhs, .next=values);
+ values = new (ast_list_t, .ast = rhs, .next = values);
spaces(&pos);
if (!match(&pos, ",")) break;
whitespace(&pos);
@@ -1800,30 +1714,23 @@ PARSER(parse_assignment) {
REVERSE_LIST(targets);
REVERSE_LIST(values);
- return NewAST(ctx->file, start, pos, Assign, .targets=targets, .values=values);
+ return NewAST(ctx->file, start, pos, Assign, .targets = targets, .values = values);
}
PARSER(parse_statement) {
ast_t *stmt = NULL;
- if ((stmt=parse_declaration(ctx, pos))
- || (stmt=parse_doctest(ctx, pos))
- || (stmt=parse_assert(ctx, pos)))
+ if ((stmt = parse_declaration(ctx, pos)) || (stmt = parse_doctest(ctx, pos)) || (stmt = parse_assert(ctx, pos)))
return stmt;
- if (!(false
- || (stmt=parse_update(ctx, pos))
- || (stmt=parse_assignment(ctx, pos))
- ))
+ if (!(false || (stmt = parse_update(ctx, pos)) || (stmt = parse_assignment(ctx, pos))))
stmt = parse_extended_expr(ctx, pos);
-
- for (bool progress = (stmt != NULL); progress; ) {
+
+ for (bool progress = (stmt != NULL); progress;) {
ast_t *new_stmt;
progress = false;
if (stmt->tag == Var) {
- progress = (false
- || (new_stmt=parse_method_call_suffix(ctx, stmt))
- || (new_stmt=parse_fncall_suffix(ctx, stmt))
- );
+ progress = (false || (new_stmt = parse_method_call_suffix(ctx, stmt))
+ || (new_stmt = parse_fncall_suffix(ctx, stmt)));
} else if (stmt->tag == FunctionCall) {
new_stmt = parse_optional_conditional_suffix(ctx, stmt);
progress = (new_stmt != stmt);
@@ -1832,20 +1739,14 @@ PARSER(parse_statement) {
if (progress) stmt = new_stmt;
}
return stmt;
-
}
PARSER(parse_extended_expr) {
ast_t *expr = NULL;
- if (false
- || (expr=optional(ctx, &pos, parse_for))
- || (expr=optional(ctx, &pos, parse_while))
- || (expr=optional(ctx, &pos, parse_if))
- || (expr=optional(ctx, &pos, parse_when))
- || (expr=optional(ctx, &pos, parse_repeat))
- || (expr=optional(ctx, &pos, parse_do))
- )
+ if (false || (expr = optional(ctx, &pos, parse_for)) || (expr = optional(ctx, &pos, parse_while))
+ || (expr = optional(ctx, &pos, parse_if)) || (expr = optional(ctx, &pos, parse_when))
+ || (expr = optional(ctx, &pos, parse_repeat)) || (expr = optional(ctx, &pos, parse_do)))
return expr;
return parse_expr(ctx, pos);
@@ -1863,7 +1764,7 @@ PARSER(parse_block) {
spaces(&pos);
ast_t *stmt = optional(ctx, &pos, parse_statement);
if (!stmt) break;
- statements = new(ast_list_t, .ast=stmt, .next=statements);
+ statements = new (ast_list_t, .ast = stmt, .next = statements);
spaces(&pos);
if (!match(&pos, ";")) break;
}
@@ -1872,7 +1773,7 @@ PARSER(parse_block) {
}
if (indent(ctx, &pos)) {
- indented:;
+ indented:;
int64_t block_indent = get_indent(ctx, pos);
whitespace(&pos);
while (*pos) {
@@ -1889,17 +1790,15 @@ PARSER(parse_block) {
parser_err(ctx, line_start, eol(pos), "'use' statements are only allowed at the top level");
spaces(&pos);
- if (*pos && *pos != '\r' && *pos != '\n')
- parser_err(ctx, pos, eol(pos), "I couldn't parse this line");
+ if (*pos && *pos != '\r' && *pos != '\n') parser_err(ctx, pos, eol(pos), "I couldn't parse this line");
break;
}
- statements = new(ast_list_t, .ast=stmt, .next=statements);
+ statements = new (ast_list_t, .ast = stmt, .next = statements);
whitespace(&pos);
// Guard against having two valid statements on the same line, separated by spaces (but no newlines):
if (!memchr(stmt->end, '\n', (size_t)(pos - stmt->end))) {
- if (*pos)
- parser_err(ctx, pos, eol(pos), "I don't know how to parse the rest of this line");
+ if (*pos) parser_err(ctx, pos, eol(pos), "I don't know how to parse the rest of this line");
pos = stmt->end;
break;
}
@@ -1911,7 +1810,7 @@ PARSER(parse_block) {
}
}
REVERSE_LIST(statements);
- return NewAST(ctx->file, start, pos, Block, .statements=statements);
+ return NewAST(ctx->file, start, pos, Block, .statements = statements);
}
PARSER(parse_namespace) {
@@ -1924,18 +1823,12 @@ PARSER(parse_namespace) {
whitespace(&next);
if (get_indent(ctx, next) != indent) break;
ast_t *stmt;
- if ((stmt=optional(ctx, &pos, parse_struct_def))
- ||(stmt=optional(ctx, &pos, parse_func_def))
- ||(stmt=optional(ctx, &pos, parse_enum_def))
- ||(stmt=optional(ctx, &pos, parse_lang_def))
- ||(stmt=optional(ctx, &pos, parse_extend))
- ||(stmt=optional(ctx, &pos, parse_convert_def))
- ||(stmt=optional(ctx, &pos, parse_use))
- ||(stmt=optional(ctx, &pos, parse_extern))
- ||(stmt=optional(ctx, &pos, parse_inline_c))
- ||(stmt=optional(ctx, &pos, parse_declaration)))
- {
- statements = new(ast_list_t, .ast=stmt, .next=statements);
+ if ((stmt = optional(ctx, &pos, parse_struct_def)) || (stmt = optional(ctx, &pos, parse_func_def))
+ || (stmt = optional(ctx, &pos, parse_enum_def)) || (stmt = optional(ctx, &pos, parse_lang_def))
+ || (stmt = optional(ctx, &pos, parse_extend)) || (stmt = optional(ctx, &pos, parse_convert_def))
+ || (stmt = optional(ctx, &pos, parse_use)) || (stmt = optional(ctx, &pos, parse_extern))
+ || (stmt = optional(ctx, &pos, parse_inline_c)) || (stmt = optional(ctx, &pos, parse_declaration))) {
+ statements = new (ast_list_t, .ast = stmt, .next = statements);
pos = stmt->end;
whitespace(&pos); // TODO: check for newline
// if (!(space_types & WHITESPACE_NEWLINES)) {
@@ -1949,7 +1842,7 @@ PARSER(parse_namespace) {
}
}
REVERSE_LIST(statements);
- return NewAST(ctx->file, start, pos, Block, .statements=statements);
+ return NewAST(ctx->file, start, pos, Block, .statements = statements);
}
PARSER(parse_file_body) {
@@ -1961,18 +1854,12 @@ PARSER(parse_file_body) {
whitespace(&next);
if (get_indent(ctx, next) != 0) break;
ast_t *stmt;
- if ((stmt=optional(ctx, &pos, parse_struct_def))
- ||(stmt=optional(ctx, &pos, parse_func_def))
- ||(stmt=optional(ctx, &pos, parse_enum_def))
- ||(stmt=optional(ctx, &pos, parse_lang_def))
- ||(stmt=optional(ctx, &pos, parse_extend))
- ||(stmt=optional(ctx, &pos, parse_convert_def))
- ||(stmt=optional(ctx, &pos, parse_use))
- ||(stmt=optional(ctx, &pos, parse_extern))
- ||(stmt=optional(ctx, &pos, parse_inline_c))
- ||(stmt=optional(ctx, &pos, parse_top_declaration)))
- {
- statements = new(ast_list_t, .ast=stmt, .next=statements);
+ if ((stmt = optional(ctx, &pos, parse_struct_def)) || (stmt = optional(ctx, &pos, parse_func_def))
+ || (stmt = optional(ctx, &pos, parse_enum_def)) || (stmt = optional(ctx, &pos, parse_lang_def))
+ || (stmt = optional(ctx, &pos, parse_extend)) || (stmt = optional(ctx, &pos, parse_convert_def))
+ || (stmt = optional(ctx, &pos, parse_use)) || (stmt = optional(ctx, &pos, parse_extern))
+ || (stmt = optional(ctx, &pos, parse_inline_c)) || (stmt = optional(ctx, &pos, parse_top_declaration))) {
+ statements = new (ast_list_t, .ast = stmt, .next = statements);
pos = stmt->end;
whitespace(&pos); // TODO: check for newline
} else {
@@ -1984,7 +1871,7 @@ PARSER(parse_file_body) {
parser_err(ctx, pos, eol(pos), "I expect all top-level statements to be declarations of some kind");
}
REVERSE_LIST(statements);
- return NewAST(ctx->file, start, pos, Block, .statements=statements);
+ return NewAST(ctx->file, start, pos, Block, .statements = statements);
}
PARSER(parse_struct_def) {
@@ -1999,8 +1886,7 @@ PARSER(parse_struct_def) {
if (!name) parser_err(ctx, start, pos, "I expected a name for this struct");
spaces(&pos);
- if (!match(&pos, "("))
- parser_err(ctx, pos, pos, "I expected a '(' and a list of fields here");
+ if (!match(&pos, "(")) parser_err(ctx, pos, pos, "I expected a '(' and a list of fields here");
arg_ast_t *fields = parse_args(ctx, &pos);
@@ -2015,18 +1901,16 @@ PARSER(parse_struct_def) {
external = true;
} else if (match_word(&pos, "opaque")) {
if (fields)
- parser_err(ctx, pos-strlen("opaque"), pos, "A struct can't be opaque if it has fields defined");
+ parser_err(ctx, pos - strlen("opaque"), pos, "A struct can't be opaque if it has fields defined");
opaque = true;
} else {
break;
}
- if (!match_separator(&pos))
- break;
+ if (!match_separator(&pos)) break;
}
}
-
expect_closing(ctx, &pos, ")", "I wasn't able to parse the rest of this struct");
ast_t *namespace = NULL;
@@ -2037,10 +1921,9 @@ PARSER(parse_struct_def) {
pos = ns_pos;
namespace = optional(ctx, &pos, parse_namespace);
}
- if (!namespace)
- namespace = NewAST(ctx->file, pos, pos, Block, .statements=NULL);
- return NewAST(ctx->file, start, pos, StructDef, .name=name, .fields=fields, .namespace=namespace,
- .secret=secret, .external=external, .opaque=opaque);
+ if (!namespace) namespace = NewAST(ctx->file, pos, pos, Block, .statements = NULL);
+ return NewAST(ctx->file, start, pos, StructDef, .name = name, .fields = fields, .namespace = namespace,
+ .secret = secret, .external = external, .opaque = opaque);
}
PARSER(parse_enum_def) {
@@ -2050,8 +1933,7 @@ PARSER(parse_enum_def) {
int64_t starting_indent = get_indent(ctx, pos);
spaces(&pos);
const char *name = get_id(&pos);
- if (!name)
- parser_err(ctx, start, pos, "I expected a name for this enum");
+ if (!name) parser_err(ctx, start, pos, "I expected a name for this enum");
spaces(&pos);
if (!match(&pos, "(")) return NULL;
@@ -2079,10 +1961,9 @@ PARSER(parse_enum_def) {
fields = NULL;
}
- tags = new(tag_ast_t, .name=tag_name, .fields=fields, .secret=secret, .next=tags);
+ tags = new (tag_ast_t, .name = tag_name, .fields = fields, .secret = secret, .next = tags);
- if (!match_separator(&pos))
- break;
+ if (!match_separator(&pos)) break;
}
whitespace(&pos);
@@ -2090,8 +1971,7 @@ PARSER(parse_enum_def) {
REVERSE_LIST(tags);
- if (tags == NULL)
- parser_err(ctx, start, pos, "This enum does not have any tags!");
+ if (tags == NULL) parser_err(ctx, start, pos, "This enum does not have any tags!");
ast_t *namespace = NULL;
const char *ns_pos = pos;
@@ -2101,10 +1981,9 @@ PARSER(parse_enum_def) {
pos = ns_pos;
namespace = optional(ctx, &pos, parse_namespace);
}
- if (!namespace)
- namespace = NewAST(ctx->file, pos, pos, Block, .statements=NULL);
+ if (!namespace) namespace = NewAST(ctx->file, pos, pos, Block, .statements = NULL);
- return NewAST(ctx->file, start, pos, EnumDef, .name=name, .tags=tags, .namespace=namespace);
+ return NewAST(ctx->file, start, pos, EnumDef, .name = name, .tags = tags, .namespace = namespace);
}
PARSER(parse_lang_def) {
@@ -2114,8 +1993,7 @@ PARSER(parse_lang_def) {
int64_t starting_indent = get_indent(ctx, pos);
spaces(&pos);
const char *name = get_id(&pos);
- if (!name)
- parser_err(ctx, start, pos, "I expected a name for this lang");
+ if (!name) parser_err(ctx, start, pos, "I expected a name for this lang");
spaces(&pos);
ast_t *namespace = NULL;
@@ -2126,10 +2004,9 @@ PARSER(parse_lang_def) {
pos = ns_pos;
namespace = optional(ctx, &pos, parse_namespace);
}
- if (!namespace)
- namespace = NewAST(ctx->file, pos, pos, Block, .statements=NULL);
+ if (!namespace) namespace = NewAST(ctx->file, pos, pos, Block, .statements = NULL);
- return NewAST(ctx->file, start, pos, LangDef, .name=name, .namespace=namespace);
+ return NewAST(ctx->file, start, pos, LangDef, .name = name, .namespace = namespace);
}
PARSER(parse_extend) {
@@ -2139,8 +2016,7 @@ PARSER(parse_extend) {
int64_t starting_indent = get_indent(ctx, pos);
spaces(&pos);
const char *name = get_id(&pos);
- if (!name)
- parser_err(ctx, start, pos, "I expected a name for this lang");
+ if (!name) parser_err(ctx, start, pos, "I expected a name for this lang");
ast_t *body = NULL;
const char *ns_pos = pos;
@@ -2150,14 +2026,12 @@ PARSER(parse_extend) {
pos = ns_pos;
body = optional(ctx, &pos, parse_namespace);
}
- if (!body)
- body = NewAST(ctx->file, pos, pos, Block, .statements=NULL);
+ if (!body) body = NewAST(ctx->file, pos, pos, Block, .statements = NULL);
- return NewAST(ctx->file, start, pos, Extend, .name=name, .body=body);
+ return NewAST(ctx->file, start, pos, Extend, .name = name, .body = body);
}
-arg_ast_t *parse_args(parse_ctx_t *ctx, const char **pos)
-{
+arg_ast_t *parse_args(parse_ctx_t *ctx, const char **pos) {
arg_ast_t *args = NULL;
for (;;) {
const char *batch_start = *pos;
@@ -2177,18 +2051,18 @@ arg_ast_t *parse_args(parse_ctx_t *ctx, const char **pos)
whitespace(pos);
if (match(pos, ":")) {
- type = expect(ctx, *pos-1, pos, parse_type, "I expected a type here");
- names = new(name_list_t, .name=name, .next=names);
+ type = expect(ctx, *pos - 1, pos, parse_type, "I expected a type here");
+ names = new (name_list_t, .name = name, .next = names);
whitespace(pos);
if (match(pos, "="))
- default_val = expect(ctx, *pos-1, pos, parse_term, "I expected a value after this '='");
+ default_val = expect(ctx, *pos - 1, pos, parse_term, "I expected a value after this '='");
break;
} else if (strncmp(*pos, "==", 2) != 0 && match(pos, "=")) {
- default_val = expect(ctx, *pos-1, pos, parse_term, "I expected a value after this '='");
- names = new(name_list_t, .name=name, .next=names);
+ default_val = expect(ctx, *pos - 1, pos, parse_term, "I expected a value after this '='");
+ names = new (name_list_t, .name = name, .next = names);
break;
} else if (name) {
- names = new(name_list_t, .name=name, .next=names);
+ names = new (name_list_t, .name = name, .next = names);
spaces(pos);
if (!match(pos, ",")) break;
} else {
@@ -2197,14 +2071,15 @@ arg_ast_t *parse_args(parse_ctx_t *ctx, const char **pos)
}
if (!names) break;
if (!default_val && !type)
- parser_err(ctx, batch_start, *pos, "I expected a ':' and type, or '=' and a default value after this parameter (", names->name, ")");
+ parser_err(ctx, batch_start, *pos,
+ "I expected a ':' and type, or '=' and a default value after this parameter (", names->name,
+ ")");
REVERSE_LIST(names);
for (; names; names = names->next)
- args = new(arg_ast_t, .name=names->name, .type=type, .value=default_val, .next=args);
+ args = new (arg_ast_t, .name = names->name, .type = type, .value = default_val, .next = args);
- if (!match_separator(pos))
- break;
+ if (!match_separator(pos)) break;
}
REVERSE_LIST(args);
@@ -2233,22 +2108,19 @@ 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, .str="-1");
+ if (!cache_ast) cache_ast = NewAST(ctx->file, pos, pos, Int, .str = "-1");
} else if (match_word(&pos, "cache_size")) {
whitespace(&pos);
- if (!match(&pos, "="))
- parser_err(ctx, flag_start, pos, "I expected a value for 'cache_size'");
+ if (!match(&pos, "=")) parser_err(ctx, flag_start, pos, "I expected a value for 'cache_size'");
whitespace(&pos);
cache_ast = expect(ctx, start, &pos, parse_expr, "I expected a maximum size for the cache");
}
}
expect_closing(ctx, &pos, ")", "I wasn't able to parse the rest of this function definition");
- ast_t *body = expect(ctx, start, &pos, parse_block,
- "This function needs a body block");
- return NewAST(ctx->file, start, pos, FunctionDef,
- .name=name, .args=args, .ret_type=ret_type, .body=body, .cache=cache_ast,
- .is_inline=is_inline);
+ ast_t *body = expect(ctx, start, &pos, parse_block, "This function needs a body block");
+ return NewAST(ctx->file, start, pos, FunctionDef, .name = name, .args = args, .ret_type = ret_type, .body = body,
+ .cache = cache_ast, .is_inline = is_inline);
}
PARSER(parse_convert_def) {
@@ -2270,33 +2142,30 @@ PARSER(parse_convert_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, .str="-1");
+ if (!cache_ast) cache_ast = NewAST(ctx->file, pos, pos, Int, .str = "-1");
} else if (match_word(&pos, "cache_size")) {
whitespace(&pos);
- if (!match(&pos, "="))
- parser_err(ctx, flag_start, pos, "I expected a value for 'cache_size'");
+ if (!match(&pos, "=")) parser_err(ctx, flag_start, pos, "I expected a value for 'cache_size'");
whitespace(&pos);
cache_ast = expect(ctx, start, &pos, parse_expr, "I expected a maximum size for the cache");
}
}
expect_closing(ctx, &pos, ")", "I wasn't able to parse the rest of this function definition");
- ast_t *body = expect(ctx, start, &pos, parse_block,
- "This function needs a body block");
- return NewAST(ctx->file, start, pos, ConvertDef,
- .args=args, .ret_type=ret_type, .body=body, .cache=cache_ast, .is_inline=is_inline);
+ ast_t *body = expect(ctx, start, &pos, parse_block, "This function needs a body block");
+ return NewAST(ctx->file, start, pos, ConvertDef, .args = args, .ret_type = ret_type, .body = body,
+ .cache = cache_ast, .is_inline = is_inline);
}
PARSER(parse_extern) {
const char *start = pos;
if (!match_word(&pos, "extern")) return NULL;
spaces(&pos);
- const char* name = get_id(&pos);
+ const char *name = get_id(&pos);
spaces(&pos);
- if (!match(&pos, ":"))
- parser_err(ctx, start, pos, "I couldn't get a type for this extern");
+ if (!match(&pos, ":")) parser_err(ctx, start, pos, "I couldn't get a type for this extern");
type_ast_t *type = expect(ctx, start, &pos, parse_type, "I couldn't parse the type for this extern");
- return NewAST(ctx->file, start, pos, Extern, .name=name, .type=type);
+ return NewAST(ctx->file, start, pos, Extern, .name = name, .type = type);
}
PARSER(parse_inline_c) {
@@ -2309,22 +2178,20 @@ PARSER(parse_inline_c) {
if (match(&pos, ":")) {
type = expect(ctx, start, &pos, parse_type, "I couldn't parse the type for this C_code code");
spaces(&pos);
- if (!match(&pos, "("))
- parser_err(ctx, start, pos, "I expected a '(' here");
- chunks = new(ast_list_t, .ast=NewAST(ctx->file, pos, pos, TextLiteral, Text("({")),
- .next=_parse_text_helper(ctx, &pos, '(', ')', '@', false));
+ if (!match(&pos, "(")) parser_err(ctx, start, pos, "I expected a '(' here");
+ chunks = new (ast_list_t, .ast = NewAST(ctx->file, pos, pos, TextLiteral, Text("({")),
+ .next = _parse_text_helper(ctx, &pos, '(', ')', '@', false));
if (type) {
REVERSE_LIST(chunks);
- chunks = new(ast_list_t, .ast=NewAST(ctx->file, pos, pos, TextLiteral, Text("; })")), .next=chunks);
+ chunks = new (ast_list_t, .ast = NewAST(ctx->file, pos, pos, TextLiteral, Text("; })")), .next = chunks);
REVERSE_LIST(chunks);
}
} else {
- if (!match(&pos, "{"))
- parser_err(ctx, start, pos, "I expected a '{' here");
+ if (!match(&pos, "{")) parser_err(ctx, start, pos, "I expected a '{' here");
chunks = _parse_text_helper(ctx, &pos, '{', '}', '@', false);
}
- return NewAST(ctx->file, start, pos, InlineCCode, .chunks=chunks, .type_ast=type);
+ return NewAST(ctx->file, start, pos, InlineCCode, .chunks = chunks, .type_ast = type);
}
PARSER(parse_doctest) {
@@ -2340,7 +2207,7 @@ PARSER(parse_doctest) {
} else {
pos = expr->end;
}
- return NewAST(ctx->file, start, pos, DocTest, .expr=expr, .expected=expected);
+ return NewAST(ctx->file, start, pos, DocTest, .expr = expr, .expected = expected);
}
PARSER(parse_assert) {
@@ -2356,7 +2223,7 @@ PARSER(parse_assert) {
} else {
pos = expr->end;
}
- return NewAST(ctx->file, start, pos, Assert, .expr=expr, .message=message);
+ return NewAST(ctx->file, start, pos, Assert, .expr = expr, .message = message);
}
PARSER(parse_use) {
@@ -2373,12 +2240,12 @@ PARSER(parse_use) {
if (!match_word(&pos, "use")) return NULL;
spaces(&pos);
size_t name_len = strcspn(pos, " \t\r\n;");
- if (name_len < 1)
- parser_err(ctx, start, pos, "There is no module name here to use");
+ if (name_len < 1) parser_err(ctx, start, pos, "There is no module name here to use");
char *name = GC_strndup(pos, name_len);
pos += name_len;
- while (match(&pos, ";")) continue;
- int what;
+ while (match(&pos, ";"))
+ continue;
+ int what;
if (name[0] == '<' || ends_with(name, ".h")) {
what = USE_HEADER;
} else if (starts_with(name, "-l")) {
@@ -2387,17 +2254,17 @@ PARSER(parse_use) {
what = USE_C_CODE;
} else if (ends_with(name, ".S") || ends_with(name, ".s")) {
what = USE_ASM;
- } else if (starts_with(name, "./") || starts_with(name, "/") || starts_with(name, "../") || starts_with(name, "~/")) {
+ } else if (starts_with(name, "./") || starts_with(name, "/") || starts_with(name, "../")
+ || starts_with(name, "~/")) {
what = USE_LOCAL;
} else {
what = USE_MODULE;
}
- return NewAST(ctx->file, start, pos, Use, .var=var, .path=name, .what=what);
+ return NewAST(ctx->file, start, pos, Use, .var = var, .path = name, .what = what);
}
ast_t *parse_file(const char *path, jmp_buf *on_err) {
- if (path[0] != '<' && path[0] != '/')
- fail("Path is not fully resolved: ", path);
+ if (path[0] != '<' && path[0] != '/') fail("Path is not fully resolved: ", path);
// NOTE: this cache leaks a bounded amount of memory. The cache will never
// hold more than PARSE_CACHE_SIZE entries (see below), but each entry's
// AST holds onto a reference to the file it came from, so they could
@@ -2417,8 +2284,8 @@ ast_t *parse_file(const char *path, jmp_buf *on_err) {
}
parse_ctx_t ctx = {
- .file=file,
- .on_err=on_err,
+ .file = file,
+ .on_err = on_err,
};
const char *pos = file->text;
@@ -2437,7 +2304,10 @@ ast_t *parse_file(const char *path, jmp_buf *on_err) {
if (cached.entries.length > PARSE_CACHE_SIZE) {
// FIXME: this currently evicts the first entry, but it should be more like
// an LRU cache
- struct {const char *path; ast_t *ast; } *to_remove = Table$entry(cached, 1);
+ struct {
+ const char *path;
+ ast_t *ast;
+ } *to_remove = Table$entry(cached, 1);
Table$str_remove(&cached, to_remove->path);
}
@@ -2449,8 +2319,8 @@ ast_t *parse_file(const char *path, jmp_buf *on_err) {
type_ast_t *parse_type_str(const char *str) {
file_t *file = spoof_file("<type>", str);
parse_ctx_t ctx = {
- .file=file,
- .on_err=NULL,
+ .file = file,
+ .on_err = NULL,
};
const char *pos = file->text;
@@ -2468,8 +2338,8 @@ type_ast_t *parse_type_str(const char *str) {
ast_t *parse(const char *str) {
file_t *file = spoof_file("<string>", str);
parse_ctx_t ctx = {
- .file=file,
- .on_err=NULL,
+ .file = file,
+ .on_err = NULL,
};
const char *pos = file->text;
@@ -2485,8 +2355,8 @@ ast_t *parse(const char *str) {
ast_t *parse_expression(const char *str) {
file_t *file = spoof_file("<string>", str);
parse_ctx_t ctx = {
- .file=file,
- .on_err=NULL,
+ .file = file,
+ .on_err = NULL,
};
const char *pos = file->text;