parsing code for defer and more

* disable goto and label support see #44
 * refactor the way block contexts work
This commit is contained in:
Andrew Kelley
2016-02-05 23:20:34 -07:00
parent 4339d55562
commit 6a2ede5a6e
11 changed files with 347 additions and 329 deletions

View File

@@ -1635,20 +1635,24 @@ static AstNode *ast_parse_if_expr(ParseContext *pc, int *token_index, bool manda
/*
ReturnExpression : option("%" | "?") "return" option(Expression)
DeferExpression = option("%" | "?") "defer" option(Expression)
*/
static AstNode *ast_parse_return_expr(ParseContext *pc, int *token_index, bool mandatory) {
static AstNode *ast_parse_return_or_defer_expr(ParseContext *pc, int *token_index) {
Token *token = &pc->tokens->at(*token_index);
NodeType node_type;
ReturnKind kind;
if (token->id == TokenIdPercent) {
Token *next_token = &pc->tokens->at(*token_index + 1);
if (next_token->id == TokenIdKeywordReturn) {
kind = ReturnKindError;
node_type = NodeTypeReturnExpr;
*token_index += 2;
} else if (next_token->id == TokenIdKeywordDefer) {
kind = ReturnKindError;
node_type = NodeTypeDeferExpr;
*token_index += 2;
} else if (mandatory) {
ast_expect_token(pc, next_token, TokenIdKeywordReturn);
zig_unreachable();
} else {
return nullptr;
}
@@ -1656,24 +1660,28 @@ static AstNode *ast_parse_return_expr(ParseContext *pc, int *token_index, bool m
Token *next_token = &pc->tokens->at(*token_index + 1);
if (next_token->id == TokenIdKeywordReturn) {
kind = ReturnKindMaybe;
node_type = NodeTypeReturnExpr;
*token_index += 2;
} else if (next_token->id == TokenIdKeywordDefer) {
kind = ReturnKindMaybe;
node_type = NodeTypeDeferExpr;
*token_index += 2;
} else if (mandatory) {
ast_expect_token(pc, next_token, TokenIdKeywordReturn);
zig_unreachable();
} else {
return nullptr;
}
} else if (token->id == TokenIdKeywordReturn) {
kind = ReturnKindUnconditional;
node_type = NodeTypeReturnExpr;
*token_index += 1;
} else if (token->id == TokenIdKeywordDefer) {
kind = ReturnKindUnconditional;
node_type = NodeTypeDeferExpr;
*token_index += 1;
} else if (mandatory) {
ast_expect_token(pc, token, TokenIdKeywordReturn);
zig_unreachable();
} else {
return nullptr;
}
AstNode *node = ast_create_node(pc, NodeTypeReturnExpr, token);
AstNode *node = ast_create_node(pc, node_type, token);
node->data.return_expr.kind = kind;
node->data.return_expr.expr = ast_parse_expression(pc, token_index, false);
@@ -2060,7 +2068,7 @@ NonBlockExpression : ReturnExpression | AssignmentExpression
static AstNode *ast_parse_non_block_expr(ParseContext *pc, int *token_index, bool mandatory) {
Token *token = &pc->tokens->at(*token_index);
AstNode *return_expr = ast_parse_return_expr(pc, token_index, false);
AstNode *return_expr = ast_parse_return_or_defer_expr(pc, token_index);
if (return_expr)
return return_expr;
@@ -2695,6 +2703,9 @@ void normalize_parent_ptrs(AstNode *node) {
case NodeTypeReturnExpr:
set_field(&node->data.return_expr.expr);
break;
case NodeTypeDeferExpr:
set_field(&node->data.defer_expr.expr);
break;
case NodeTypeVariableDeclaration:
set_list_fields(node->data.variable_declaration.directives);
set_field(&node->data.variable_declaration.type);