aboutsummaryrefslogtreecommitdiff
path: root/src/parser.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2016-01-15 17:40:12 -0700
committerAndrew Kelley <superjoe30@gmail.com>2016-01-15 17:40:12 -0700
commit0311b35a21e9896772cb982750be680b0ef71f1f (patch)
tree11ad9a19e13d0a4c4f6fd7853a3a0b25f2eb282b /src/parser.cpp
parent74b1665586bafe0fcd063480b9480a77cbf93ab2 (diff)
downloadzig-0311b35a21e9896772cb982750be680b0ef71f1f.tar.gz
zig-0311b35a21e9896772cb982750be680b0ef71f1f.zip
reduce precedence of {} suffix operator
this makes []u8 {1, 2, 3, 4} work for array literal
Diffstat (limited to 'src/parser.cpp')
-rw-r--r--src/parser.cpp164
1 files changed, 91 insertions, 73 deletions
diff --git a/src/parser.cpp b/src/parser.cpp
index 2886c5e8f7..adcbeae830 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -903,6 +903,7 @@ static AstNode *ast_parse_block(ParseContext *pc, int *token_index, bool mandato
static AstNode *ast_parse_if_expr(ParseContext *pc, int *token_index, bool mandatory);
static AstNode *ast_parse_block_expr(ParseContext *pc, int *token_index, bool mandatory);
static AstNode *ast_parse_unwrap_maybe_expr(ParseContext *pc, int *token_index, bool mandatory);
+static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, int *token_index, bool mandatory);
static void ast_expect_token(ParseContext *pc, Token *token, TokenId token_id) {
if (token->id == token_id) {
@@ -998,7 +999,7 @@ static AstNode *ast_parse_param_decl(ParseContext *pc, int *token_index) {
*token_index += 1;
ast_expect_token(pc, colon, TokenIdColon);
- node->data.param_decl.type = ast_parse_unwrap_maybe_expr(pc, token_index, true);
+ node->data.param_decl.type = ast_parse_prefix_op_expr(pc, token_index, true);
return node;
}
@@ -1114,7 +1115,7 @@ static AstNode *ast_parse_array_type_expr(ParseContext *pc, int *token_index, bo
node->data.array_type.is_const = true;
}
- node->data.array_type.child_type = ast_parse_unwrap_maybe_expr(pc, token_index, true);
+ node->data.array_type.child_type = ast_parse_prefix_op_expr(pc, token_index, true);
return node;
}
@@ -1159,7 +1160,7 @@ static void ast_parse_asm_output_item(ParseContext *pc, int *token_index, AstNod
if (token->id == TokenIdSymbol) {
ast_buf_from_token(pc, token, &asm_output->variable_name);
} else if (token->id == TokenIdArrow) {
- asm_output->return_type = ast_parse_unwrap_maybe_expr(pc, token_index, true);
+ asm_output->return_type = ast_parse_prefix_op_expr(pc, token_index, true);
} else {
ast_invalid_token_error(pc, token);
}
@@ -1402,81 +1403,23 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool
}
/*
-SuffixOpExpression : PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression | ContainerInitExpression)
-FnCallExpression : token(LParen) list(Expression, token(Comma)) token(RParen)
-ArrayAccessExpression : token(LBracket) Expression token(RBracket)
-SliceExpression : token(LBracket) Expression token(Ellipsis) option(Expression) token(RBracket) option(token(Const))
-FieldAccessExpression : token(Dot) token(Symbol)
+CurlySuffixExpression : PrefixOpExpression option(ContainerInitExpression)
ContainerInitExpression : token(LBrace) ContainerInitBody token(RBrace)
ContainerInitBody : list(StructLiteralField, token(Comma)) | list(Expression, token(Comma))
-StructLiteralField : token(Dot) token(Symbol) token(Eq) Expression
*/
-static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, int *token_index, bool mandatory) {
- AstNode *primary_expr = ast_parse_primary_expr(pc, token_index, mandatory);
- if (!primary_expr) {
+static AstNode *ast_parse_curly_suffix_expr(ParseContext *pc, int *token_index, bool mandatory) {
+ AstNode *prefix_op_expr = ast_parse_prefix_op_expr(pc, token_index, mandatory);
+ if (!prefix_op_expr) {
return nullptr;
}
while (true) {
Token *first_token = &pc->tokens->at(*token_index);
- if (first_token->id == TokenIdLParen) {
- *token_index += 1;
-
- AstNode *node = ast_create_node(pc, NodeTypeFnCallExpr, first_token);
- node->data.fn_call_expr.fn_ref_expr = primary_expr;
- ast_parse_fn_call_param_list(pc, token_index, &node->data.fn_call_expr.params);
-
- primary_expr = node;
- } else if (first_token->id == TokenIdLBracket) {
- *token_index += 1;
-
- AstNode *expr_node = ast_parse_expression(pc, token_index, true);
-
- Token *ellipsis_or_r_bracket = &pc->tokens->at(*token_index);
-
- if (ellipsis_or_r_bracket->id == TokenIdEllipsis) {
- *token_index += 1;
-
- AstNode *node = ast_create_node(pc, NodeTypeSliceExpr, first_token);
- node->data.slice_expr.array_ref_expr = primary_expr;
- node->data.slice_expr.start = expr_node;
- node->data.slice_expr.end = ast_parse_expression(pc, token_index, false);
-
- ast_eat_token(pc, token_index, TokenIdRBracket);
-
- Token *const_tok = &pc->tokens->at(*token_index);
- if (const_tok->id == TokenIdKeywordConst) {
- *token_index += 1;
- node->data.slice_expr.is_const = true;
- }
-
- primary_expr = node;
- } else if (ellipsis_or_r_bracket->id == TokenIdRBracket) {
- *token_index += 1;
-
- AstNode *node = ast_create_node(pc, NodeTypeArrayAccessExpr, first_token);
- node->data.array_access_expr.array_ref_expr = primary_expr;
- node->data.array_access_expr.subscript = expr_node;
-
- primary_expr = node;
- } else {
- ast_invalid_token_error(pc, first_token);
- }
- } else if (first_token->id == TokenIdDot) {
- *token_index += 1;
-
- Token *name_token = ast_eat_token(pc, token_index, TokenIdSymbol);
-
- AstNode *node = ast_create_node(pc, NodeTypeFieldAccessExpr, first_token);
- node->data.field_access_expr.struct_expr = primary_expr;
- ast_buf_from_token(pc, name_token, &node->data.field_access_expr.field_name);
-
- primary_expr = node;
- } else if (first_token->id == TokenIdLBrace) {
+ if (first_token->id == TokenIdLBrace) {
*token_index += 1;
AstNode *node = ast_create_node(pc, NodeTypeContainerInitExpr, first_token);
- node->data.container_init_expr.type = primary_expr;
+ node->data.container_init_expr.type = prefix_op_expr;
Token *token = &pc->tokens->at(*token_index);
if (token->id == TokenIdDot) {
@@ -1536,6 +1479,81 @@ static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, int *token_index, boo
}
}
+ prefix_op_expr = node;
+ } else {
+ return prefix_op_expr;
+ }
+ }
+}
+
+/*
+SuffixOpExpression : PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression)
+FnCallExpression : token(LParen) list(Expression, token(Comma)) token(RParen)
+ArrayAccessExpression : token(LBracket) Expression token(RBracket)
+SliceExpression : token(LBracket) Expression token(Ellipsis) option(Expression) token(RBracket) option(token(Const))
+FieldAccessExpression : token(Dot) token(Symbol)
+StructLiteralField : token(Dot) token(Symbol) token(Eq) Expression
+*/
+static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, int *token_index, bool mandatory) {
+ AstNode *primary_expr = ast_parse_primary_expr(pc, token_index, mandatory);
+ if (!primary_expr) {
+ return nullptr;
+ }
+
+ while (true) {
+ Token *first_token = &pc->tokens->at(*token_index);
+ if (first_token->id == TokenIdLParen) {
+ *token_index += 1;
+
+ AstNode *node = ast_create_node(pc, NodeTypeFnCallExpr, first_token);
+ node->data.fn_call_expr.fn_ref_expr = primary_expr;
+ ast_parse_fn_call_param_list(pc, token_index, &node->data.fn_call_expr.params);
+
+ primary_expr = node;
+ } else if (first_token->id == TokenIdLBracket) {
+ *token_index += 1;
+
+ AstNode *expr_node = ast_parse_expression(pc, token_index, true);
+
+ Token *ellipsis_or_r_bracket = &pc->tokens->at(*token_index);
+
+ if (ellipsis_or_r_bracket->id == TokenIdEllipsis) {
+ *token_index += 1;
+
+ AstNode *node = ast_create_node(pc, NodeTypeSliceExpr, first_token);
+ node->data.slice_expr.array_ref_expr = primary_expr;
+ node->data.slice_expr.start = expr_node;
+ node->data.slice_expr.end = ast_parse_expression(pc, token_index, false);
+
+ ast_eat_token(pc, token_index, TokenIdRBracket);
+
+ Token *const_tok = &pc->tokens->at(*token_index);
+ if (const_tok->id == TokenIdKeywordConst) {
+ *token_index += 1;
+ node->data.slice_expr.is_const = true;
+ }
+
+ primary_expr = node;
+ } else if (ellipsis_or_r_bracket->id == TokenIdRBracket) {
+ *token_index += 1;
+
+ AstNode *node = ast_create_node(pc, NodeTypeArrayAccessExpr, first_token);
+ node->data.array_access_expr.array_ref_expr = primary_expr;
+ node->data.array_access_expr.subscript = expr_node;
+
+ primary_expr = node;
+ } else {
+ ast_invalid_token_error(pc, first_token);
+ }
+ } else if (first_token->id == TokenIdDot) {
+ *token_index += 1;
+
+ Token *name_token = ast_eat_token(pc, token_index, TokenIdSymbol);
+
+ AstNode *node = ast_create_node(pc, NodeTypeFieldAccessExpr, first_token);
+ node->data.field_access_expr.struct_expr = primary_expr;
+ ast_buf_from_token(pc, name_token, &node->data.field_access_expr.field_name);
+
primary_expr = node;
} else {
return primary_expr;
@@ -1623,10 +1641,10 @@ static BinOpType ast_parse_mult_op(ParseContext *pc, int *token_index, bool mand
}
/*
-MultiplyExpression : PrefixOpExpression MultiplyOperator MultiplyExpression | PrefixOpExpression
+MultiplyExpression : CurlySuffixExpression MultiplyOperator MultiplyExpression | CurlySuffixExpression
*/
static AstNode *ast_parse_mult_expr(ParseContext *pc, int *token_index, bool mandatory) {
- AstNode *operand_1 = ast_parse_prefix_op_expr(pc, token_index, mandatory);
+ AstNode *operand_1 = ast_parse_curly_suffix_expr(pc, token_index, mandatory);
if (!operand_1)
return nullptr;
@@ -1636,7 +1654,7 @@ static AstNode *ast_parse_mult_expr(ParseContext *pc, int *token_index, bool man
if (mult_op == BinOpTypeInvalid)
return operand_1;
- AstNode *operand_2 = ast_parse_prefix_op_expr(pc, token_index, true);
+ AstNode *operand_2 = ast_parse_curly_suffix_expr(pc, token_index, true);
AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
node->data.bin_op_expr.op1 = operand_1;
@@ -1948,7 +1966,7 @@ static AstNode *ast_parse_if_expr(ParseContext *pc, int *token_index, bool manda
node->data.if_var_expr.var_decl.expr = ast_parse_expression(pc, token_index, true);
} else if (eq_or_colon->id == TokenIdColon) {
*token_index += 1;
- node->data.if_var_expr.var_decl.type = ast_parse_unwrap_maybe_expr(pc, token_index, true);
+ node->data.if_var_expr.var_decl.type = ast_parse_prefix_op_expr(pc, token_index, true);
ast_eat_token(pc, token_index, TokenIdMaybeAssign);
node->data.if_var_expr.var_decl.expr = ast_parse_expression(pc, token_index, true);
@@ -2028,7 +2046,7 @@ static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, int *token
node->data.variable_declaration.expr = ast_parse_expression(pc, token_index, true);
return node;
} else if (eq_or_colon->id == TokenIdColon) {
- node->data.variable_declaration.type = ast_parse_unwrap_maybe_expr(pc, token_index, true);
+ node->data.variable_declaration.type = ast_parse_prefix_op_expr(pc, token_index, true);
Token *eq_token = &pc->tokens->at(*token_index);
if (eq_token->id == TokenIdEq) {
*token_index += 1;
@@ -2394,7 +2412,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, int *token_index, bool mand
ast_parse_param_decl_list(pc, token_index, &node->data.fn_proto.params, &node->data.fn_proto.is_var_args);
Token *next_token = &pc->tokens->at(*token_index);
- node->data.fn_proto.return_type = ast_parse_unwrap_maybe_expr(pc, token_index, false);
+ node->data.fn_proto.return_type = ast_parse_prefix_op_expr(pc, token_index, false);
if (!node->data.fn_proto.return_type) {
node->data.fn_proto.return_type = ast_create_void_type_node(pc, next_token);
}