aboutsummaryrefslogtreecommitdiff
path: root/src/parser.cpp
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2017-07-20 23:57:56 +0100
committerGinger Bill <bill@gingerbill.org>2017-07-20 23:57:56 +0100
commitdbddec33c8247beb5984d0c3fbcdf86a94054248 (patch)
tree6f711915422e3a2b76013d4bf6d488ce1221d84e /src/parser.cpp
parent401a5955a4ed1746e96f29db8e521cb4831a863d (diff)
Internal changes; thread.odin for windows only
Diffstat (limited to 'src/parser.cpp')
-rw-r--r--src/parser.cpp31
1 files changed, 22 insertions, 9 deletions
diff --git a/src/parser.cpp b/src/parser.cpp
index 9b848ca7e..4e764d2a6 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -427,8 +427,9 @@ AST_NODE_KIND(_TypeBegin, "", i32) \
AstNode * align; \
}) \
AST_NODE_KIND(UnionType, "union type", struct { \
- Token token; \
- Array<AstNode *> variants; \
+ Token token; \
+ Array<AstNode *> variants; \
+ AstNode * align; \
}) \
AST_NODE_KIND(EnumType, "enum type", struct { \
Token token; \
@@ -1460,10 +1461,11 @@ AstNode *ast_struct_type(AstFile *f, Token token, Array<AstNode *> fields, isize
}
-AstNode *ast_union_type(AstFile *f, Token token, Array<AstNode *> variants) {
+AstNode *ast_union_type(AstFile *f, Token token, Array<AstNode *> variants, AstNode *align) {
AstNode *result = make_ast_node(f, AstNode_UnionType);
- result->UnionType.token = token;
- result->UnionType.variants = variants;
+ result->UnionType.token = token;
+ result->UnionType.variants = variants;
+ result->UnionType.align = align;
return result;
}
@@ -2496,10 +2498,23 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
Token open = expect_token_after(f, Token_OpenBrace, "union");
Array<AstNode *> variants = make_ast_node_array(f);
isize total_decl_name_count = 0;
+ AstNode *align = nullptr;
CommentGroup docs = f->lead_comment;
Token start_token = f->curr_token;
+ while (allow_token(f, Token_Hash)) {
+ Token tag = expect_token_after(f, Token_Ident, "#");
+ if (tag.string == "align") {
+ if (align) {
+ syntax_error(tag, "Duplicate union tag `#%.*s`", LIT(tag.string));
+ }
+ align = parse_expr(f, true);
+ } else {
+ syntax_error(tag, "Invalid union tag `#%.*s`", LIT(tag.string));
+ }
+ }
+
while (f->curr_token.kind != Token_CloseBrace &&
f->curr_token.kind != Token_EOF) {
@@ -2514,7 +2529,7 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
Token close = expect_token(f, Token_CloseBrace);
- return ast_union_type(f, token, variants);
+ return ast_union_type(f, token, variants, align);
} break;
case Token_enum: {
@@ -3009,15 +3024,13 @@ AstNode *parse_gen_decl(AstFile *f, Token token, ParseSpecFunc *func) {
if (f->curr_token.kind == Token_OpenParen) {
specs = make_ast_node_array(f);
open = expect_token(f, Token_OpenParen);
- bool require_semicolon_after_paren = false;
while (f->curr_token.kind != Token_CloseParen &&
f->curr_token.kind != Token_EOF) {
AstNode *spec = func(f, docs, token);
array_add(&specs, spec);
}
close = expect_token(f, Token_CloseParen);
- if (require_semicolon_after_paren ||
- f->curr_token.pos.line == close.pos.line ||
+ if (f->curr_token.pos.line == close.pos.line ||
open.pos.line == close.pos.line) {
expect_semicolon(f, nullptr);
}