diff options
| author | Ginger Bill <bill@gingerbill.org> | 2016-08-24 15:06:36 +0100 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2016-08-24 15:06:36 +0100 |
| commit | 6bd898e552392b1bd11ad16c7476833261c1d4b7 (patch) | |
| tree | add523b133a1c4e0d2189d437ad7a1616c024050 /src/parser.cpp | |
| parent | 975705f1fc68af73b25ff135733c57d8cfd62912 (diff) | |
Untagged (unsafe) unions and unambiguous in|postfix notation.
Diffstat (limited to 'src/parser.cpp')
| -rw-r--r-- | src/parser.cpp | 59 |
1 files changed, 46 insertions, 13 deletions
diff --git a/src/parser.cpp b/src/parser.cpp index 6fb491557..56a90aca9 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -82,9 +82,9 @@ enum VarDeclTag { }; enum CallExprKind { - CallExpr_Normal, - CallExpr_UnaryOp, - CallExpr_BinaryOp, + CallExpr_Prefix, // call(...) + CallExpr_Postfix, // a'call + CallExpr_Infix, // a ''call b }; #define AST_NODE_KINDS \ @@ -225,6 +225,11 @@ AST_NODE_KIND(_TypeBegin, struct{}) \ isize field_count; \ b32 is_packed; \ }) \ + AST_NODE_KIND(UnionType, struct { \ + Token token; \ + AstNode *field_list; \ + isize field_count; \ + }) \ AST_NODE_KIND(EnumType, struct { \ Token token; \ AstNode *base_type; \ @@ -374,6 +379,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_EnumType: return node->EnumType.token; } @@ -778,6 +785,14 @@ gb_inline AstNode *make_struct_type(AstFile *f, Token token, AstNode *field_list return result; } +gb_inline AstNode *make_union_type(AstFile *f, Token token, AstNode *field_list, isize field_count) { + AstNode *result = make_node(f, AstNode_UnionType); + result->UnionType.token = token; + result->UnionType.field_list = field_list; + result->UnionType.field_count = field_count; + return result; +} + gb_inline AstNode *make_enum_type(AstFile *f, Token token, AstNode *base_type, AstNode *field_list, isize field_count) { AstNode *result = make_node(f, AstNode_EnumType); @@ -1194,12 +1209,12 @@ AstNode *parse_atom_expr(AstFile *f, b32 lhs) { while (loop) { switch (f->cursor[0].kind) { - case Token_CustomUnaryOp: { - Token op = expect_token(f, Token_CustomUnaryOp); + case Token_Prime: { + Token op = expect_token(f, Token_Prime); if (lhs) { // TODO(bill): Handle this } - AstNode *proc = make_ident(f, op); + AstNode *proc = parse_identifier(f); operand = make_call_expr(f, proc, operand, 1, ast_node_token(operand), op); } break; @@ -1363,6 +1378,15 @@ AstNode *parse_binary_expr(AstFile *f, b32 lhs, i32 prec_in) { lhs = false; } + + if (op.kind == Token_DoublePrime) { + AstNode *proc = parse_identifier(f); + AstNode *right = parse_binary_expr(f, false, prec+1); + expression->next = right; + expression = make_call_expr(f, proc, expression, 2, op, ast_node_token(right)); + continue; + } + if (op.kind == Token_as || op.kind == Token_transmute) { right = parse_type(f); } else { @@ -1372,13 +1396,7 @@ AstNode *parse_binary_expr(AstFile *f, b32 lhs, i32 prec_in) { } } - if (op.kind == Token_CustomBinaryOp) { - AstNode *proc = make_ident(f, op); - expression->next = right; - expression = make_call_expr(f, proc, expression, 2, ast_node_token(expression), ast_node_token(right)); - } else { - expression = make_binary_expr(f, op, expression, right); - } + expression = make_binary_expr(f, op, expression, right); } } return expression; @@ -1657,6 +1675,20 @@ AstNode *parse_identifier_or_type(AstFile *f) { return make_struct_type(f, token, params, param_count, is_packed); } + case Token_union: { + Token token = expect_token(f, Token_union); + Token open, close; + AstNode *params = NULL; + isize param_count = 0; + AstScope *scope = make_ast_scope(f, NULL); // NOTE(bill): The union needs its own scope with NO parent + + open = expect_token(f, Token_OpenBrace); + params = parse_parameter_list(f, scope, ¶m_count); + close = expect_token(f, Token_CloseBrace); + + return make_union_type(f, token, params, param_count); + } + case Token_enum: { Token token = expect_token(f, Token_enum); AstNode *base_type = NULL; @@ -2055,6 +2087,7 @@ AstNode *parse_stmt(AstFile *f) { if (s->kind != AstNode_ProcDecl && (s->kind == AstNode_TypeDecl && s->TypeDecl.type->kind != AstNode_StructType && + s->TypeDecl.type->kind != AstNode_UnionType && s->TypeDecl.type->kind != AstNode_EnumType && s->TypeDecl.type->kind != AstNode_ProcType) && !allow_token(f, Token_Semicolon)) { |