aboutsummaryrefslogtreecommitdiff
path: root/src/parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser.cpp')
-rw-r--r--src/parser.cpp158
1 files changed, 84 insertions, 74 deletions
diff --git a/src/parser.cpp b/src/parser.cpp
index 28519f7e4..6b14e375e 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -131,7 +131,7 @@ AST_NODE_KIND(_ExprBegin, "", struct{}) \
AST_NODE_KIND(DerefExpr, "dereference expression", struct { Token op; AstNode *expr; }) \
AST_NODE_KIND(CallExpr, "call expression", struct { \
AstNode *proc; \
- gbArray(AstNode *) args; \
+ AstNodeArray args; \
Token open, close; \
Token ellipsis; \
CallExprKind kind; \
@@ -256,7 +256,7 @@ AST_NODE_KIND(_DeclBegin, "", struct{}) \
AST_NODE_KIND(ForeignSystemLibrary, "foreign system library", struct { Token token, filepath; }) \
AST_NODE_KIND(_DeclEnd, "", struct{}) \
AST_NODE_KIND(_TypeBegin, "", struct{}) \
- AST_NODE_KIND(Field, "field", struct { \
+ AST_NODE_KIND(Parameter, "parameter", struct { \
AstNodeArray names; \
AstNode *type; \
b32 is_using; \
@@ -444,11 +444,11 @@ Token ast_node_token(AstNode *node) {
return node->ImportDecl.token;
case AstNode_ForeignSystemLibrary:
return node->ForeignSystemLibrary.token;
- case AstNode_Field: {
- if (node->Field.names)
- return ast_node_token(node->Field.names[0]);
+ case AstNode_Parameter: {
+ if (node->Parameter.names)
+ return ast_node_token(node->Parameter.names[0]);
else
- return ast_node_token(node->Field.type);
+ return ast_node_token(node->Parameter.type);
}
case AstNode_ProcType:
return node->ProcType.token;
@@ -545,7 +545,7 @@ gb_inline AstNode *make_paren_expr(AstFile *f, AstNode *expr, Token open, Token
return result;
}
-gb_inline AstNode *make_call_expr(AstFile *f, AstNode *proc, gbArray(AstNode *)args, Token open, Token close, Token ellipsis) {
+gb_inline AstNode *make_call_expr(AstFile *f, AstNode *proc, AstNodeArray args, Token open, Token close, Token ellipsis) {
AstNode *result = make_node(f, AstNode_CallExpr);
result->CallExpr.proc = proc;
result->CallExpr.args = args;
@@ -823,11 +823,11 @@ gb_inline AstNode *make_const_decl(AstFile *f, AstNodeArray names, AstNode *type
return result;
}
-gb_inline AstNode *make_field(AstFile *f, AstNodeArray names, AstNode *type, b32 is_using) {
- AstNode *result = make_node(f, AstNode_Field);
- result->Field.names = names;
- result->Field.type = type;
- result->Field.is_using = is_using;
+gb_inline AstNode *make_parameter(AstFile *f, AstNodeArray names, AstNode *type, b32 is_using) {
+ AstNode *result = make_node(f, AstNode_Parameter);
+ result->Parameter.names = names;
+ result->Parameter.type = type;
+ result->Parameter.is_using = is_using;
return result;
}
@@ -961,6 +961,19 @@ gb_inline Token expect_token(AstFile *f, TokenKind kind) {
return prev;
}
+gb_inline Token expect_token_after(AstFile *f, TokenKind kind, char *msg) {
+ Token prev = f->curr_token;
+ if (prev.kind != kind) {
+ syntax_error(f->curr_token, "Expected `%.*s` after %s, got `%.*s`",
+ LIT(token_strings[kind]),
+ msg,
+ LIT(token_strings[prev.kind]));
+ }
+ next_token(f);
+ return prev;
+}
+
+
gb_inline Token expect_operator(AstFile *f) {
Token prev = f->curr_token;
if (!gb_is_between(prev.kind, Token__OperatorBegin+1, Token__OperatorEnd-1)) {
@@ -1650,7 +1663,7 @@ AstNode *parse_binary_expr(AstFile *f, b32 lhs, i32 prec_in) {
expression = call;
} else */{
- AstNode *right = parse_binary_expr(f, false, prec+1);
+ right = parse_binary_expr(f, false, prec+1);
gbArray(AstNode *) args;
gb_array_init_reserve(args, gb_arena_allocator(&f->arena), 2);
gb_array_append(args, expression);
@@ -1841,58 +1854,54 @@ AstNode *parse_proc_type(AstFile *f) {
return make_proc_type(f, proc_token, params, results);
}
-AstNode *parse_field_decl(AstFile *f) {
- b32 is_using = false;
- if (allow_token(f, Token_using)) {
- is_using = true;
- }
- AstNodeArray names = parse_lhs_expr_list(f);
- if (gb_array_count(names) == 0) {
- syntax_error(f->curr_token, "Empty field declaration");
- }
+AstNodeArray parse_parameter_list(AstFile *f) {
+ AstNodeArray params = make_ast_node_array(f);
- if (gb_array_count(names) > 1 && is_using) {
- syntax_error(f->curr_token, "Cannot apply `using` to more than one of the same type");
- is_using = false;
- }
+ while (f->curr_token.kind == Token_Identifier ||
+ f->curr_token.kind == Token_using) {
+ b32 is_using = false;
+ if (allow_token(f, Token_using)) {
+ is_using = true;
+ }
+ AstNodeArray names = parse_lhs_expr_list(f);
+ if (gb_array_count(names) == 0) {
+ syntax_error(f->curr_token, "Empty parameter declaration");
+ }
+
+ if (gb_array_count(names) > 1 && is_using) {
+ syntax_error(f->curr_token, "Cannot apply `using` to more than one of the same type");
+ is_using = false;
+ }
- expect_token(f, Token_Colon);
+ expect_token_after(f, Token_Colon, "parameter list");
- AstNode *type = NULL;
- if (f->curr_token.kind == Token_Ellipsis) {
- Token ellipsis = f->curr_token;
- next_token(f);
- type = parse_type_attempt(f);
- if (type == NULL) {
- syntax_error(f->curr_token, "variadic parameter is missing a type after `..`");
- type = make_bad_expr(f, ellipsis, f->curr_token);
- } else {
- if (gb_array_count(names) > 1) {
- syntax_error(f->curr_token, "mutliple variadic parameters, only `..`");
+ AstNode *type = NULL;
+ if (f->curr_token.kind == Token_Ellipsis) {
+ Token ellipsis = f->curr_token;
+ next_token(f);
+ type = parse_type_attempt(f);
+ if (type == NULL) {
+ syntax_error(f->curr_token, "variadic parameter is missing a type after `..`");
+ type = make_bad_expr(f, ellipsis, f->curr_token);
} else {
- type = make_ellipsis(f, ellipsis, type);
+ if (gb_array_count(names) > 1) {
+ syntax_error(f->curr_token, "mutliple variadic parameters, only `..`");
+ } else {
+ type = make_ellipsis(f, ellipsis, type);
+ }
}
+ } else {
+ type = parse_type_attempt(f);
}
- } else {
- type = parse_type_attempt(f);
- }
- if (type == NULL) {
- syntax_error(f->curr_token, "Expected a type for this field declaration");
- }
- AstNode *field = make_field(f, names, type, is_using);
- return field;
-}
+ if (type == NULL) {
+ syntax_error(f->curr_token, "Expected a type for this parameter declaration");
+ }
-AstNodeArray parse_parameter_list(AstFile *f) {
- AstNodeArray params = make_ast_node_array(f);
- while (f->curr_token.kind == Token_Identifier ||
- f->curr_token.kind == Token_using) {
- AstNode *field = parse_field_decl(f);
- gb_array_append(params, field);
+ gb_array_append(params, make_parameter(f, names, type, is_using));
if (f->curr_token.kind != Token_Comma) {
break;
}
@@ -2011,7 +2020,7 @@ AstNode *parse_identifier_or_type(AstFile *f, u32 flags) {
b32 is_packed = false;
b32 is_ordered = false;
while (allow_token(f, Token_Hash)) {
- Token tag = expect_token(f, Token_Identifier);
+ Token tag = expect_token_after(f, Token_Identifier, "`#`");
if (tag.string == "packed") {
if (is_packed) {
syntax_error(tag, "Duplicate struct tag `#%.*s`", LIT(tag.string));
@@ -2031,7 +2040,7 @@ AstNode *parse_identifier_or_type(AstFile *f, u32 flags) {
syntax_error(token, "`#ordered` is not needed with `#packed` which implies ordering");
}
- Token open = expect_token(f, Token_OpenBrace);
+ Token open = expect_token_after(f, Token_OpenBrace, "`struct`");
isize decl_count = 0;
AstNodeArray decls = parse_struct_params(f, &decl_count, true);
Token close = expect_token(f, Token_CloseBrace);
@@ -2041,7 +2050,7 @@ AstNode *parse_identifier_or_type(AstFile *f, u32 flags) {
case Token_union: {
Token token = expect_token(f, Token_union);
- Token open = expect_token(f, Token_OpenBrace);
+ Token open = expect_token_after(f, Token_OpenBrace, "`union`");
isize decl_count = 0;
AstNodeArray decls = parse_struct_params(f, &decl_count, false);
Token close = expect_token(f, Token_CloseBrace);
@@ -2050,7 +2059,7 @@ AstNode *parse_identifier_or_type(AstFile *f, u32 flags) {
}
case Token_raw_union: {
- Token token = expect_token(f, Token_raw_union);
+ Token token = expect_token_after(f, Token_OpenBrace, "`raw_union`");
Token open = expect_token(f, Token_OpenBrace);
isize decl_count = 0;
AstNodeArray decls = parse_struct_params(f, &decl_count, true);
@@ -2070,7 +2079,7 @@ AstNode *parse_identifier_or_type(AstFile *f, u32 flags) {
AstNodeArray fields = make_ast_node_array(f);
- open = expect_token(f, Token_OpenBrace);
+ open = expect_token_after(f, Token_OpenBrace, "`enum`");
while (f->curr_token.kind != Token_CloseBrace &&
f->curr_token.kind != Token_EOF) {
@@ -2161,7 +2170,7 @@ Token parse_procedure_signature(AstFile *f,
Token proc_token = expect_token(f, Token_proc);
expect_token(f, Token_OpenParen);
*params = parse_parameter_list(f);
- expect_token(f, Token_CloseParen);
+ expect_token_after(f, Token_CloseParen, "parameter list");
*results = parse_results(f);
return proc_token;
}
@@ -2210,17 +2219,17 @@ AstNode *parse_decl(AstFile *f, AstNodeArray names) {
AstNodeArray values = NULL;
AstNode *type = NULL;
- gb_for_array(i, names) {
- AstNode *name = names[i];
- if (name->kind == AstNode_Ident) {
- String n = name->Ident.string;
- // NOTE(bill): Check for reserved identifiers
- if (n == "context") {
- syntax_error(ast_node_token(name), "`context` is a reserved identifier");
- break;
- }
- }
- }
+ // gb_for_array(i, names) {
+ // AstNode *name = names[i];
+ // if (name->kind == AstNode_Ident) {
+ // String n = name->Ident.string;
+ // // NOTE(bill): Check for reserved identifiers
+ // if (n == "context") {
+ // syntax_error(ast_node_token(name), "`context` is a reserved identifier");
+ // break;
+ // }
+ // }
+ // }
if (allow_token(f, Token_Colon)) {
if (!allow_token(f, Token_type)) {
@@ -2258,8 +2267,7 @@ AstNode *parse_decl(AstFile *f, AstNodeArray names) {
// NOTE(bill): Do not fail though
}
- AstNode *type = parse_type(f);
- return make_type_decl(f, token, names[0], type);
+ return make_type_decl(f, token, names[0], parse_type(f));
} else if (f->curr_token.kind == Token_proc &&
is_mutable == false) {
// NOTE(bill): Procedure declarations
@@ -2434,6 +2442,7 @@ AstNode *parse_case_clause(AstFile *f) {
expect_token(f, Token_default);
}
expect_token(f, Token_Colon); // TODO(bill): Is this the best syntax?
+ // expect_token(f, Token_ArrowRight); // TODO(bill): Is this the best syntax?
AstNodeArray stmts = parse_stmt_list(f);
return make_case_clause(f, token, list, stmts);
@@ -2449,6 +2458,7 @@ AstNode *parse_type_case_clause(AstFile *f) {
expect_token(f, Token_default);
}
expect_token(f, Token_Colon); // TODO(bill): Is this the best syntax?
+ // expect_token(f, Token_ArrowRight); // TODO(bill): Is this the best syntax?
AstNodeArray stmts = parse_stmt_list(f);
return make_case_clause(f, token, clause, stmts);
@@ -3069,7 +3079,7 @@ ParseFileError parse_files(Parser *p, char *init_filename) {
p->init_fullpath = init_fullpath;
{
- String s = get_fullpath_core(gb_heap_allocator(), make_string("runtime.odin"));
+ String s = get_fullpath_core(gb_heap_allocator(), make_string("_preload.odin"));
ImportedFile runtime_file = {s, s, init_pos};
gb_array_append(p->imports, runtime_file);
}