aboutsummaryrefslogtreecommitdiff
path: root/src/parser.cpp
diff options
context:
space:
mode:
authorJosh Wolfe <thejoshwolfe@gmail.com>2017-04-02 15:14:35 -0700
committerJosh Wolfe <thejoshwolfe@gmail.com>2017-04-02 15:15:48 -0700
commit0594487a2e98e18a18c0c6bdb2532c5e36fc6ea7 (patch)
treecb82a82a5d6e20b1f30a53af48822951fc7a1d9d /src/parser.cpp
parenta33be6fc9906e010a44087dc2b7143717d875505 (diff)
downloadzig-0594487a2e98e18a18c0c6bdb2532c5e36fc6ea7.tar.gz
zig-0594487a2e98e18a18c0c6bdb2532c5e36fc6ea7.zip
fix else-if parsing
implicit semicolon rules apply recursively to the "else" clause of if and try if (a) {} else {} // implicit semicolon if (a) {} else if (a) {} // implicit semicolon if (a) {} else while (a) {} // implicit semicolon
Diffstat (limited to 'src/parser.cpp')
-rw-r--r--src/parser.cpp23
1 files changed, 16 insertions, 7 deletions
diff --git a/src/parser.cpp b/src/parser.cpp
index 0c02eaef2a..18452aeb69 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -212,6 +212,7 @@ static void ast_invalid_token_error(ParseContext *pc, Token *token) {
}
static AstNode *ast_parse_block_or_expression(ParseContext *pc, size_t *token_index, bool mandatory);
+static AstNode *ast_parse_block_expr_or_expression(ParseContext *pc, size_t *token_index, bool mandatory);
static AstNode *ast_parse_expression(ParseContext *pc, size_t *token_index, bool mandatory);
static AstNode *ast_parse_block(ParseContext *pc, size_t *token_index, bool mandatory);
static AstNode *ast_parse_if_expr(ParseContext *pc, size_t *token_index, bool mandatory);
@@ -701,7 +702,7 @@ static AstNode *ast_parse_try_expr(ParseContext *pc, size_t *token_index, bool m
ast_eat_token(pc, token_index, TokenIdBinOr);
}
- node->data.try_expr.else_node = ast_parse_block_or_expression(pc, token_index, true);
+ node->data.try_expr.else_node = ast_parse_block_expr_or_expression(pc, token_index, true);
}
return node;
@@ -1439,7 +1440,7 @@ static AstNode *ast_parse_if_expr(ParseContext *pc, size_t *token_index, bool ma
Token *else_token = &pc->tokens->at(*token_index);
if (else_token->id == TokenIdKeywordElse) {
*token_index += 1;
- node->data.if_var_expr.else_node = ast_parse_block_or_expression(pc, token_index, true);
+ node->data.if_var_expr.else_node = ast_parse_block_expr_or_expression(pc, token_index, true);
}
return node;
@@ -1452,7 +1453,7 @@ static AstNode *ast_parse_if_expr(ParseContext *pc, size_t *token_index, bool ma
Token *else_token = &pc->tokens->at(*token_index);
if (else_token->id == TokenIdKeywordElse) {
*token_index += 1;
- node->data.if_bool_expr.else_node = ast_parse_block_or_expression(pc, token_index, true);
+ node->data.if_bool_expr.else_node = ast_parse_block_expr_or_expression(pc, token_index, true);
}
return node;
@@ -1860,15 +1861,15 @@ static bool statement_has_block_body(AstNode *node) {
switch (node->type) {
case NodeTypeIfBoolExpr:
if (node->data.if_bool_expr.else_node)
- return node->data.if_bool_expr.else_node->type == NodeTypeBlock;
+ return statement_has_block_body(node->data.if_bool_expr.else_node);
return node->data.if_bool_expr.then_block->type == NodeTypeBlock;
case NodeTypeIfVarExpr:
if (node->data.if_var_expr.else_node)
- return node->data.if_var_expr.else_node->type == NodeTypeBlock;
+ return statement_has_block_body(node->data.if_var_expr.else_node);
return node->data.if_var_expr.then_block->type == NodeTypeBlock;
case NodeTypeTryExpr:
if (node->data.try_expr.else_node)
- return node->data.try_expr.else_node->type == NodeTypeBlock;
+ return statement_has_block_body(node->data.try_expr.else_node);
return node->data.try_expr.then_node->type == NodeTypeBlock;
case NodeTypeWhileExpr:
return node->data.while_expr.body->type == NodeTypeBlock;
@@ -1882,7 +1883,7 @@ static bool statement_has_block_body(AstNode *node) {
case NodeTypeDefer:
return node->data.defer.expr->type == NodeTypeBlock;
default:
- zig_unreachable();
+ return false;
}
}
@@ -2030,6 +2031,14 @@ static AstNode *ast_parse_ass_expr(ParseContext *pc, size_t *token_index, bool m
return node;
}
+static AstNode *ast_parse_block_expr_or_expression(ParseContext *pc, size_t *token_index, bool mandatory) {
+ AstNode *block_expr = ast_parse_block_expr(pc, token_index, false);
+ if (block_expr)
+ return block_expr;
+
+ return ast_parse_expression(pc, token_index, mandatory);
+}
+
/*
BlockOrExpression = Block | Expression
*/