aboutsummaryrefslogtreecommitdiff
path: root/src/parser.cpp
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2016-08-24 15:06:36 +0100
committerGinger Bill <bill@gingerbill.org>2016-08-24 15:06:36 +0100
commit6bd898e552392b1bd11ad16c7476833261c1d4b7 (patch)
treeadd523b133a1c4e0d2189d437ad7a1616c024050 /src/parser.cpp
parent975705f1fc68af73b25ff135733c57d8cfd62912 (diff)
Untagged (unsafe) unions and unambiguous in|postfix notation.
Diffstat (limited to 'src/parser.cpp')
-rw-r--r--src/parser.cpp59
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, &param_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)) {