aboutsummaryrefslogtreecommitdiff
path: root/src/parser.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2017-02-02 17:09:27 -0500
committerAndrew Kelley <superjoe30@gmail.com>2017-02-02 17:09:27 -0500
commitc0b37e8514a26f56e3596f86b01771b1ae2bf299 (patch)
treeb24c7fd04b2e8582d4e79455455e740ef58ca864 /src/parser.cpp
parent8b1c6d8b76ad1861f963fc7a2a079af5d8729a70 (diff)
downloadzig-c0b37e8514a26f56e3596f86b01771b1ae2bf299.tar.gz
zig-c0b37e8514a26f56e3596f86b01771b1ae2bf299.zip
add try expression
See #83
Diffstat (limited to 'src/parser.cpp')
-rw-r--r--src/parser.cpp76
1 files changed, 75 insertions, 1 deletions
diff --git a/src/parser.cpp b/src/parser.cpp
index 1b79da9b2b..54081d91a7 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -624,6 +624,71 @@ static AstNode *ast_parse_comptime_expr(ParseContext *pc, size_t *token_index, b
}
/*
+TryExpression = "try" "(" ("const" | "var") option("*") Symbol "=" Expression ")" Expression option("else" option("|" Symbol "|") Expression)
+*/
+static AstNode *ast_parse_try_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
+ Token *try_token = &pc->tokens->at(*token_index);
+ if (try_token->id == TokenIdKeywordTry) {
+ *token_index += 1;
+ } else if (mandatory) {
+ ast_expect_token(pc, try_token, TokenIdKeywordTry);
+ zig_unreachable();
+ } else {
+ return nullptr;
+ }
+
+ AstNode *node = ast_create_node(pc, NodeTypeTryExpr, try_token);
+
+ ast_eat_token(pc, token_index, TokenIdLParen);
+
+ Token *var_token = &pc->tokens->at(*token_index);
+ if (var_token->id == TokenIdKeywordVar) {
+ node->data.try_expr.var_is_const = false;
+ *token_index += 1;
+ } else if (var_token->id == TokenIdKeywordConst) {
+ node->data.try_expr.var_is_const = true;
+ *token_index += 1;
+ } else {
+ ast_invalid_token_error(pc, var_token);
+ }
+
+ Token *star_token = &pc->tokens->at(*token_index);
+ if (star_token->id == TokenIdStar) {
+ node->data.try_expr.var_is_ptr = true;
+ *token_index += 1;
+ }
+
+ Token *var_name_tok = ast_eat_token(pc, token_index, TokenIdSymbol);
+ node->data.try_expr.var_symbol = token_buf(var_name_tok);
+
+ ast_eat_token(pc, token_index, TokenIdEq);
+
+ node->data.try_expr.target_node = ast_parse_expression(pc, token_index, true);
+
+ ast_eat_token(pc, token_index, TokenIdRParen);
+
+ node->data.try_expr.then_node = ast_parse_expression(pc, token_index, true);
+
+ Token *else_token = &pc->tokens->at(*token_index);
+ if (else_token->id != TokenIdKeywordElse)
+ return node;
+
+ *token_index += 1;
+ Token *open_bar_tok = &pc->tokens->at(*token_index);
+ if (open_bar_tok->id == TokenIdBinOr) {
+ *token_index += 1;
+
+ Token *err_name_tok = ast_eat_token(pc, token_index, TokenIdSymbol);
+ node->data.try_expr.err_symbol = token_buf(err_name_tok);
+
+ ast_eat_token(pc, token_index, TokenIdBinOr);
+ }
+
+ node->data.try_expr.else_node = ast_parse_expression(pc, token_index, true);
+ return node;
+}
+
+/*
PrimaryExpression = Number | String | CharLiteral | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | Symbol | ("@" Symbol FnCallExpression) | ArrayType | (option("extern") FnProto) | AsmExpression | ("error" "." Symbol) | ContainerDecl
KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "error" | "type" | "this"
*/
@@ -1775,7 +1840,7 @@ static AstNode *ast_parse_switch_expr(ParseContext *pc, size_t *token_index, boo
}
/*
-BlockExpression = IfExpression | Block | WhileExpression | ForExpression | SwitchExpression | CompTimeExpression
+BlockExpression = IfExpression | Block | WhileExpression | ForExpression | SwitchExpression | CompTimeExpression | TryExpression
*/
static AstNode *ast_parse_block_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
Token *token = &pc->tokens->at(*token_index);
@@ -1804,6 +1869,10 @@ static AstNode *ast_parse_block_expr(ParseContext *pc, size_t *token_index, bool
if (comptime_node)
return comptime_node;
+ AstNode *try_node = ast_parse_try_expr(pc, token_index, false);
+ if (try_node)
+ return try_node;
+
if (mandatory)
ast_invalid_token_error(pc, token);
@@ -2555,6 +2624,11 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
visit_field(&node->data.if_var_expr.then_block, visit, context);
visit_field(&node->data.if_var_expr.else_node, visit, context);
break;
+ case NodeTypeTryExpr:
+ visit_field(&node->data.try_expr.target_node, visit, context);
+ visit_field(&node->data.try_expr.then_node, visit, context);
+ visit_field(&node->data.try_expr.else_node, visit, context);
+ break;
case NodeTypeWhileExpr:
visit_field(&node->data.while_expr.condition, visit, context);
visit_field(&node->data.while_expr.body, visit, context);