From 7749ffd797e927f93051060db49b76c595879697 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 5 Feb 2017 18:58:58 -0500 Subject: [PATCH] try expression can omit variable assignments --- doc/langref.md | 2 +- src/parser.cpp | 27 ++++++++++++++++----------- test/cases/try.zig | 26 ++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 12 deletions(-) diff --git a/doc/langref.md b/doc/langref.md index f3eb6b99f6..b8a6a5775a 100644 --- a/doc/langref.md +++ b/doc/langref.md @@ -93,7 +93,7 @@ IfExpression = IfVarExpression | IfBoolExpression IfBoolExpression = "if" "(" Expression ")" Expression option(Else) -TryExpression = "try" "(" ("const" | "var") option("*") Symbol "=" Expression ")" Expression option("else" option("|" Symbol "|") Expression) +TryExpression = "try" "(" option(("const" | "var") option("*") Symbol "=") Expression ")" Expression option("else" option("|" Symbol "|") Expression) IfVarExpression = "if" "(" ("const" | "var") option("*") Symbol option(":" TypeExpr) "?=" Expression ")" Expression Option(Else) diff --git a/src/parser.cpp b/src/parser.cpp index 68ccd6aff4..57b226270a 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -628,7 +628,7 @@ 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) +TryExpression = "try" "(" option(("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); @@ -646,27 +646,32 @@ static AstNode *ast_parse_try_expr(ParseContext *pc, size_t *token_index, bool m ast_eat_token(pc, token_index, TokenIdLParen); Token *var_token = &pc->tokens->at(*token_index); + bool have_vars; if (var_token->id == TokenIdKeywordVar) { node->data.try_expr.var_is_const = false; *token_index += 1; + have_vars = true; } else if (var_token->id == TokenIdKeywordConst) { node->data.try_expr.var_is_const = true; *token_index += 1; + have_vars = true; } else { - ast_invalid_token_error(pc, var_token); + have_vars = false; } - Token *star_token = &pc->tokens->at(*token_index); - if (star_token->id == TokenIdStar) { - node->data.try_expr.var_is_ptr = true; - *token_index += 1; + if (have_vars) { + 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); } - 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); diff --git a/test/cases/try.zig b/test/cases/try.zig index 17b78b2115..cf1bf49157 100644 --- a/test/cases/try.zig +++ b/test/cases/try.zig @@ -31,3 +31,29 @@ error CrappedOut; fn returnsTen() -> %i32 { 10 } + +fn tryWithoutVars() { + @setFnTest(this); + + const result1 = try (failIfTrue(true)) { + 1 + } else { + i32(2) + }; + assert(result1 == 2); + + const result2 = try (failIfTrue(false)) { + 1 + } else { + i32(2) + }; + assert(result2 == 1); +} + +fn failIfTrue(ok: bool) -> %void { + if (ok) { + return error.ItBroke; + } else { + return; + } +}