aboutsummaryrefslogtreecommitdiff
path: root/src/parser.cpp
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2016-09-03 18:18:45 +0100
committerGinger Bill <bill@gingerbill.org>2016-09-03 18:18:45 +0100
commit7f884ed25187416bb3994e498eae30fe65233940 (patch)
treed7386614920f6d56ea184efd638d9132a34ea682 /src/parser.cpp
parent11205f968ad2bf4893fa75df3fc3331f960039d1 (diff)
Start implementing Tagged Unions
Diffstat (limited to 'src/parser.cpp')
-rw-r--r--src/parser.cpp41
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);