| ... | ... | @@ -498,6 +498,7 @@ static AstNode *ast_parse_unwrap_expr(ParseContext *pc, int *token_index, bool m |
| 498 | 498 | static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, int *token_index, bool mandatory); |
| 499 | 499 | static AstNode *ast_parse_fn_proto(ParseContext *pc, int *token_index, bool mandatory, |
| 500 | 500 | ZigList<AstNode*> *directives, VisibMod visib_mod); |
| 501 | static AstNode *ast_parse_return_expr(ParseContext *pc, int *token_index); |
| 501 | 502 | |
| 502 | 503 | static void ast_expect_token(ParseContext *pc, Token *token, TokenId token_id) { |
| 503 | 504 | if (token->id == token_id) { |
| ... | ... | @@ -1215,8 +1216,17 @@ static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, int *token_index, boo |
| 1215 | 1216 | if (prefix_op == PrefixOpInvalid) { |
| 1216 | 1217 | return ast_parse_suffix_op_expr(pc, token_index, mandatory); |
| 1217 | 1218 | } |
| 1219 | |
| 1220 | if (prefix_op == PrefixOpError || prefix_op == PrefixOpMaybe) { |
| 1221 | Token *maybe_return = &pc->tokens->at(*token_index + 1); |
| 1222 | if (maybe_return->id == TokenIdKeywordReturn) { |
| 1223 | return ast_parse_return_expr(pc, token_index); |
| 1224 | } |
| 1225 | } |
| 1226 | |
| 1218 | 1227 | *token_index += 1; |
| 1219 | 1228 | |
| 1229 | |
| 1220 | 1230 | AstNode *node = ast_create_node(pc, NodeTypePrefixOpExpr, token); |
| 1221 | 1231 | AstNode *parent_node = node; |
| 1222 | 1232 | if (token->id == TokenIdBoolAnd) { |
| ... | ... | @@ -1635,9 +1645,8 @@ static AstNode *ast_parse_if_expr(ParseContext *pc, int *token_index, bool manda |
| 1635 | 1645 | |
| 1636 | 1646 | /* |
| 1637 | 1647 | ReturnExpression : option("%" | "?") "return" option(Expression) |
| 1638 | | DeferExpression = option("%" | "?") "defer" option(Expression) |
| 1639 | 1648 | */ |
| 1640 | | static AstNode *ast_parse_return_or_defer_expr(ParseContext *pc, int *token_index) { |
| 1649 | static AstNode *ast_parse_return_expr(ParseContext *pc, int *token_index) { |
| 1641 | 1650 | Token *token = &pc->tokens->at(*token_index); |
| 1642 | 1651 | |
| 1643 | 1652 | NodeType node_type; |
| ... | ... | @@ -1649,10 +1658,6 @@ static AstNode *ast_parse_return_or_defer_expr(ParseContext *pc, int *token_inde |
| 1649 | 1658 | kind = ReturnKindError; |
| 1650 | 1659 | node_type = NodeTypeReturnExpr; |
| 1651 | 1660 | *token_index += 2; |
| 1652 | | } else if (next_token->id == TokenIdKeywordDefer) { |
| 1653 | | kind = ReturnKindError; |
| 1654 | | node_type = NodeTypeDefer; |
| 1655 | | *token_index += 2; |
| 1656 | 1661 | } else { |
| 1657 | 1662 | return nullptr; |
| 1658 | 1663 | } |
| ... | ... | @@ -1662,10 +1667,6 @@ static AstNode *ast_parse_return_or_defer_expr(ParseContext *pc, int *token_inde |
| 1662 | 1667 | kind = ReturnKindMaybe; |
| 1663 | 1668 | node_type = NodeTypeReturnExpr; |
| 1664 | 1669 | *token_index += 2; |
| 1665 | | } else if (next_token->id == TokenIdKeywordDefer) { |
| 1666 | | kind = ReturnKindMaybe; |
| 1667 | | node_type = NodeTypeDefer; |
| 1668 | | *token_index += 2; |
| 1669 | 1670 | } else { |
| 1670 | 1671 | return nullptr; |
| 1671 | 1672 | } |
| ... | ... | @@ -1673,6 +1674,45 @@ static AstNode *ast_parse_return_or_defer_expr(ParseContext *pc, int *token_inde |
| 1673 | 1674 | kind = ReturnKindUnconditional; |
| 1674 | 1675 | node_type = NodeTypeReturnExpr; |
| 1675 | 1676 | *token_index += 1; |
| 1677 | } else { |
| 1678 | return nullptr; |
| 1679 | } |
| 1680 | |
| 1681 | AstNode *node = ast_create_node(pc, node_type, token); |
| 1682 | node->data.return_expr.kind = kind; |
| 1683 | node->data.return_expr.expr = ast_parse_expression(pc, token_index, false); |
| 1684 | |
| 1685 | normalize_parent_ptrs(node); |
| 1686 | return node; |
| 1687 | } |
| 1688 | |
| 1689 | /* |
| 1690 | Defer = option("%" | "?") "defer" option(Expression) |
| 1691 | */ |
| 1692 | static AstNode *ast_parse_defer_expr(ParseContext *pc, int *token_index) { |
| 1693 | Token *token = &pc->tokens->at(*token_index); |
| 1694 | |
| 1695 | NodeType node_type; |
| 1696 | ReturnKind kind; |
| 1697 | |
| 1698 | if (token->id == TokenIdPercent) { |
| 1699 | Token *next_token = &pc->tokens->at(*token_index + 1); |
| 1700 | if (next_token->id == TokenIdKeywordDefer) { |
| 1701 | kind = ReturnKindError; |
| 1702 | node_type = NodeTypeDefer; |
| 1703 | *token_index += 2; |
| 1704 | } else { |
| 1705 | return nullptr; |
| 1706 | } |
| 1707 | } else if (token->id == TokenIdMaybe) { |
| 1708 | Token *next_token = &pc->tokens->at(*token_index + 1); |
| 1709 | if (next_token->id == TokenIdKeywordDefer) { |
| 1710 | kind = ReturnKindMaybe; |
| 1711 | node_type = NodeTypeDefer; |
| 1712 | *token_index += 2; |
| 1713 | } else { |
| 1714 | return nullptr; |
| 1715 | } |
| 1676 | 1716 | } else if (token->id == TokenIdKeywordDefer) { |
| 1677 | 1717 | kind = ReturnKindUnconditional; |
| 1678 | 1718 | node_type = NodeTypeDefer; |
| ... | ... | @@ -1682,8 +1722,8 @@ static AstNode *ast_parse_return_or_defer_expr(ParseContext *pc, int *token_inde |
| 1682 | 1722 | } |
| 1683 | 1723 | |
| 1684 | 1724 | AstNode *node = ast_create_node(pc, node_type, token); |
| 1685 | | node->data.return_expr.kind = kind; |
| 1686 | | node->data.return_expr.expr = ast_parse_expression(pc, token_index, false); |
| 1725 | node->data.defer.kind = kind; |
| 1726 | node->data.defer.expr = ast_parse_expression(pc, token_index, false); |
| 1687 | 1727 | |
| 1688 | 1728 | normalize_parent_ptrs(node); |
| 1689 | 1729 | return node; |
| ... | ... | @@ -2068,7 +2108,7 @@ NonBlockExpression : ReturnExpression | AssignmentExpression |
| 2068 | 2108 | static AstNode *ast_parse_non_block_expr(ParseContext *pc, int *token_index, bool mandatory) { |
| 2069 | 2109 | Token *token = &pc->tokens->at(*token_index); |
| 2070 | 2110 | |
| 2071 | | AstNode *return_expr = ast_parse_return_or_defer_expr(pc, token_index); |
| 2111 | AstNode *return_expr = ast_parse_return_expr(pc, token_index); |
| 2072 | 2112 | if (return_expr) |
| 2073 | 2113 | return return_expr; |
| 2074 | 2114 | |
| ... | ... | @@ -2142,7 +2182,7 @@ static AstNode *ast_create_void_expr(ParseContext *pc, Token *token) { |
| 2142 | 2182 | |
| 2143 | 2183 | /* |
| 2144 | 2184 | Block : token(LBrace) list(option(Statement), token(Semicolon)) token(RBrace) |
| 2145 | | Statement : Label | VariableDeclaration token(Semicolon) | NonBlockExpression token(Semicolon) | BlockExpression |
| 2185 | Statement = Label | VariableDeclaration ";" | Defer ";" | NonBlockExpression ";" | BlockExpression |
| 2146 | 2186 | */ |
| 2147 | 2187 | static AstNode *ast_parse_block(ParseContext *pc, int *token_index, bool mandatory) { |
| 2148 | 2188 | Token *last_token = &pc->tokens->at(*token_index); |
| ... | ... | @@ -2171,6 +2211,9 @@ static AstNode *ast_parse_block(ParseContext *pc, int *token_index, bool mandato |
| 2171 | 2211 | } else { |
| 2172 | 2212 | statement_node = ast_parse_variable_declaration_expr(pc, token_index, false, |
| 2173 | 2213 | nullptr, VisibModPrivate); |
| 2214 | if (!statement_node) { |
| 2215 | statement_node = ast_parse_defer_expr(pc, token_index); |
| 2216 | } |
| 2174 | 2217 | if (statement_node) { |
| 2175 | 2218 | semicolon_expected = true; |
| 2176 | 2219 | } else { |