diff options
| author | Ginger Bill <bill@gingerbill.org> | 2016-11-29 23:57:06 +0000 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2016-11-29 23:57:06 +0000 |
| commit | d9c686b53d63023c432293fa906d96224cc36a23 (patch) | |
| tree | b454abb47a57cb320ebb343a955c813389339693 /src/parser.c | |
| parent | b232b9d5ea23fdd4d53f8e93cdfeb1f962811331 (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.c | 107 |
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, |