aboutsummaryrefslogtreecommitdiff
path: root/src/parser.c
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2016-11-29 23:57:06 +0000
committerGinger Bill <bill@gingerbill.org>2016-11-29 23:57:06 +0000
commitd9c686b53d63023c432293fa906d96224cc36a23 (patch)
treeb454abb47a57cb320ebb343a955c813389339693 /src/parser.c
parentb232b9d5ea23fdd4d53f8e93cdfeb1f962811331 (diff)
`when` statement; Better entity collection system (for both local and global); Better parsing for record declarations
Diffstat (limited to 'src/parser.c')
-rw-r--r--src/parser.c107
1 files changed, 55 insertions, 52 deletions
diff --git a/src/parser.c b/src/parser.c
index e2b046a69..f46bae4da 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -1086,6 +1086,7 @@ void fix_advance_to_next_stmt(AstFile *f) {
return;
case Token_if:
+ case Token_when:
case Token_return:
case Token_for:
case Token_match:
@@ -1966,55 +1967,61 @@ AstNodeArray parse_parameter_list(AstFile *f) {
}
-AstNodeArray parse_struct_params(AstFile *f, isize *decl_count_, bool using_allowed) {
+AstNodeArray parse_record_params(AstFile *f, isize *decl_count_, bool using_allowed, String context) {
AstNodeArray decls = make_ast_node_array(f);
isize decl_count = 0;
- while (f->curr_token.kind == Token_Identifier ||
- f->curr_token.kind == Token_using) {
- bool is_using = false;
- if (allow_token(f, Token_using)) {
- is_using = true;
- }
- AstNodeArray names = parse_lhs_expr_list(f);
- if (names.count == 0) {
- syntax_error(f->curr_token, "Empty field declaration");
- }
-
- if (!using_allowed && is_using) {
- syntax_error(f->curr_token, "Cannot apply `using` to members of a union");
- is_using = false;
- }
- if (names.count > 1 && is_using) {
- syntax_error(f->curr_token, "Cannot apply `using` to more than one of the same type");
- }
+ while (f->curr_token.kind != Token_CloseBrace &&
+ f->curr_token.kind != Token_EOF) {
+ AstNode *decl = parse_stmt(f);
+ if (is_ast_node_decl(decl) ||
+ decl->kind == AstNode_UsingStmt ||
+ decl->kind == AstNode_EmptyStmt) {
+ switch (decl->kind) {
+ case AstNode_EmptyStmt:
+ break;
- AstNode *decl = NULL;
+ case AstNode_ProcDecl:
+ syntax_error(f->curr_token, "Procedure declarations are not allowed within a %.*s", LIT(context));
+ break;
- if (f->curr_token.kind == Token_Colon) {
- decl = parse_decl(f, names);
+ case AstNode_UsingStmt: {
+ bool is_using = true;
+ if (!using_allowed) {
+ syntax_error(f->curr_token, "Cannot apply `using` to members of a %.*s", LIT(context));
+ is_using = false;
+ }
+ if (decl->UsingStmt.node->kind == AstNode_VarDecl) {
+ AstNode *vd = decl->UsingStmt.node;
+ vd->VarDecl.is_using = is_using && using_allowed;
+ if (vd->VarDecl.values.count > 0) {
+ syntax_error(f->curr_token, "Default variable assignments within a %.*s will be ignored", LIT(context));
+ }
+ array_add(&decls, vd);
+ } else {
+ syntax_error(ast_node_token(decl), "Illegal %.*s field", LIT(context));
+ }
+ } break;
- if (decl->kind == AstNode_ProcDecl) {
- syntax_error(f->curr_token, "Procedure declarations are not allowed within a structure");
- decl = make_bad_decl(f, ast_node_token(names.e[0]), f->curr_token);
+ case AstNode_VarDecl: {
+ if (decl->VarDecl.values.count > 0) {
+ syntax_error(f->curr_token, "Default variable assignments within a %.*s will be ignored", LIT(context));
+ }
+ array_add(&decls, decl);
}
- } else {
- syntax_error(f->curr_token, "Illegal structure field");
- decl = make_bad_decl(f, ast_node_token(names.e[0]), f->curr_token);
- }
- expect_semicolon_after_stmt(f, decl);
+ case AstNode_BadDecl:
+ break;
- if (is_ast_node_decl(decl)) {
- array_add(&decls, decl);
- if (decl->kind == AstNode_VarDecl) {
- decl->VarDecl.is_using = is_using && using_allowed;
- if (decl->VarDecl.values.count > 0) {
- syntax_error(f->curr_token, "Default variable assignments within a structure will be ignored (at the moment)");
- }
- } else {
+ case AstNode_ConstDecl:
+ case AstNode_TypeDecl:
+ default:
decl_count += 1;
+ array_add(&decls, decl);
+ break;
}
+ } else {
+ syntax_error(ast_node_token(decl), "Illegal record field: %.*s", LIT(ast_node_strings[decl->kind]));
}
}
@@ -2063,7 +2070,11 @@ AstNode *parse_identifier_or_type(AstFile *f, u32 flags) {
next_token(f);
} else if (f->curr_token.kind == Token_vector) {
next_token(f);
- count_expr = parse_expr(f, false);
+ if (f->curr_token.kind != Token_CloseBracket) {
+ count_expr = parse_expr(f, false);
+ } else {
+ syntax_error(f->curr_token, "Vector type missing count");
+ }
is_vector = true;
} else if (f->curr_token.kind != Token_CloseBracket) {
count_expr = parse_expr(f, false);
@@ -2076,15 +2087,6 @@ AstNode *parse_identifier_or_type(AstFile *f, u32 flags) {
return make_array_type(f, token, count_expr, parse_type(f));
}
- // case Token_OpenBrace: {
- // f->expr_level++;
- // Token token = expect_token(f, Token_OpenBrace);
- // AstNode *count_expr = parse_expr(f, false);
- // expect_token(f, Token_CloseBrace);
- // f->expr_level--;
- // return make_vector_type(f, token, count_expr, parse_type(f));
- // }
-
case Token_struct: {
Token token = expect_token(f, Token_struct);
bool is_packed = false;
@@ -2112,7 +2114,7 @@ AstNode *parse_identifier_or_type(AstFile *f, u32 flags) {
Token open = expect_token_after(f, Token_OpenBrace, "`struct`");
isize decl_count = 0;
- AstNodeArray decls = parse_struct_params(f, &decl_count, true);
+ AstNodeArray decls = parse_record_params(f, &decl_count, true, str_lit("struct"));
Token close = expect_token(f, Token_CloseBrace);
return make_struct_type(f, token, decls, decl_count, is_packed, is_ordered);
@@ -2122,7 +2124,7 @@ AstNode *parse_identifier_or_type(AstFile *f, u32 flags) {
Token token = expect_token(f, Token_union);
Token open = expect_token_after(f, Token_OpenBrace, "`union`");
isize decl_count = 0;
- AstNodeArray decls = parse_struct_params(f, &decl_count, false);
+ AstNodeArray decls = parse_record_params(f, &decl_count, false, str_lit("union"));
Token close = expect_token(f, Token_CloseBrace);
return make_union_type(f, token, decls, decl_count);
@@ -2132,7 +2134,7 @@ AstNode *parse_identifier_or_type(AstFile *f, u32 flags) {
Token token = expect_token(f, Token_raw_union);
Token open = expect_token_after(f, Token_OpenBrace, "`raw_union`");
isize decl_count = 0;
- AstNodeArray decls = parse_struct_params(f, &decl_count, true);
+ AstNodeArray decls = parse_record_params(f, &decl_count, true, str_lit("raw_union"));
Token close = expect_token(f, Token_CloseBrace);
return make_raw_union_type(f, token, decls, decl_count);
@@ -2192,8 +2194,9 @@ AstNode *parse_identifier_or_type(AstFile *f, u32 flags) {
break;
case Token_Eq:
- if (f->prev_token.kind == Token_Colon)
+ if (f->prev_token.kind == Token_Colon) {
break;
+ }
// fallthrough
default:
syntax_error(f->curr_token,