diff options
| author | Ginger Bill <bill@gingerbill.org> | 2016-09-03 18:18:45 +0100 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2016-09-03 18:18:45 +0100 |
| commit | 7f884ed25187416bb3994e498eae30fe65233940 (patch) | |
| tree | d7386614920f6d56ea184efd638d9132a34ea682 /src/parser.cpp | |
| parent | 11205f968ad2bf4893fa75df3fc3331f960039d1 (diff) | |
Start implementing Tagged Unions
Diffstat (limited to 'src/parser.cpp')
| -rw-r--r-- | src/parser.cpp | 41 |
1 files changed, 35 insertions, 6 deletions
diff --git a/src/parser.cpp b/src/parser.cpp index 8ba398020..b2e4aba93 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -240,6 +240,11 @@ AST_NODE_KIND(_TypeBegin, "", struct{}) \ isize decl_count; \ b32 is_packed; \ }) \ + AST_NODE_KIND(UnionType, "union type", struct { \ + Token token; \ + AstNode *decl_list; \ + isize decl_count; \ + }) \ AST_NODE_KIND(RawUnionType, "raw union type", struct { \ Token token; \ AstNode *decl_list; \ @@ -395,6 +400,8 @@ Token ast_node_token(AstNode *node) { return node->VectorType.token; case AstNode_StructType: return node->StructType.token; + case AstNode_UnionType: + return node->UnionType.token; case AstNode_RawUnionType: return node->RawUnionType.token; case AstNode_EnumType: @@ -815,6 +822,15 @@ gb_inline AstNode *make_struct_type(AstFile *f, Token token, AstNode *decl_list, return result; } + +gb_inline AstNode *make_union_type(AstFile *f, Token token, AstNode *decl_list, isize decl_count) { + AstNode *result = make_node(f, AstNode_UnionType); + result->UnionType.token = token; + result->UnionType.decl_list = decl_list; + result->UnionType.decl_count = decl_count; + return result; +} + gb_inline AstNode *make_raw_union_type(AstFile *f, Token token, AstNode *decl_list, isize decl_count) { AstNode *result = make_node(f, AstNode_RawUnionType); result->RawUnionType.token = token; @@ -1674,8 +1690,7 @@ AstNode *parse_field_decl(AstFile *f) { type = make_bad_expr(f, ellipsis, f->cursor[0]); } else { if (name_count > 1) { - ast_file_err(f, f->cursor[0], "mutliple variadic parameters, only 1 is allowed"); - type = make_bad_expr(f, ellipsis, f->cursor[0]); + ast_file_err(f, f->cursor[0], "mutliple variadic parameters, only `..`"); } else { type = make_ellipsis(f, ellipsis, type); } @@ -1711,7 +1726,7 @@ AstNode *parse_parameter_list(AstFile *f, isize *param_count_) { } -AstNode *parse_struct_params(AstFile *f, isize *decl_count_) { +AstNode *parse_struct_params(AstFile *f, isize *decl_count_, b32 using_allowed) { AstNode *decls = NULL; AstNode *decls_curr = NULL; isize decl_count = 0; @@ -1728,6 +1743,10 @@ AstNode *parse_struct_params(AstFile *f, isize *decl_count_) { ast_file_err(f, f->cursor[0], "Empty field declaration"); } + if (!using_allowed && is_using) { + ast_file_err(f, f->cursor[0], "Cannot apply `using` to members of a union"); + is_using = false; + } if (name_count > 1 && is_using) { ast_file_err(f, f->cursor[0], "Cannot apply `using` to more than one of the same type"); } @@ -1752,7 +1771,7 @@ AstNode *parse_struct_params(AstFile *f, isize *decl_count_) { DLIST_APPEND(decls, decls_curr, decl); if (decl->kind == AstNode_VarDecl) { decl_count += decl->VarDecl.name_count; - decl->VarDecl.is_using = is_using; + decl->VarDecl.is_using = is_using && using_allowed; if (decl->VarDecl.kind == Declaration_Mutable) { if (decl->VarDecl.value_count > 0) { @@ -1829,17 +1848,27 @@ AstNode *parse_identifier_or_type(AstFile *f) { Token open = expect_token(f, Token_OpenBrace); isize decl_count = 0; - AstNode *decls = parse_struct_params(f, &decl_count); + AstNode *decls = parse_struct_params(f, &decl_count, true); Token close = expect_token(f, Token_CloseBrace); return make_struct_type(f, token, decls, decl_count, is_packed); } break; + case Token_union: { + Token token = expect_token(f, Token_union); + Token open = expect_token(f, Token_OpenBrace); + isize decl_count = 0; + AstNode *decls = parse_struct_params(f, &decl_count, false); + Token close = expect_token(f, Token_CloseBrace); + + return make_union_type(f, token, decls, decl_count); + } + case Token_raw_union: { Token token = expect_token(f, Token_raw_union); Token open = expect_token(f, Token_OpenBrace); isize decl_count = 0; - AstNode *decls = parse_struct_params(f, &decl_count); + AstNode *decls = parse_struct_params(f, &decl_count, true); Token close = expect_token(f, Token_CloseBrace); return make_raw_union_type(f, token, decls, decl_count); |