| ... | ... | @@ -950,13 +950,15 @@ const Parser = struct { |
| 950 | 950 | /// / LabeledStatement |
| 951 | 951 | /// / SwitchExpr |
| 952 | 952 | /// / AssignExpr SEMICOLON |
| 953 | | fn parseStatement(p: *Parser) Error!Node.Index { |
| 953 | fn parseStatement(p: *Parser, allow_defer_var: bool) Error!Node.Index { |
| 954 | 954 | const comptime_token = p.eatToken(.keyword_comptime); |
| 955 | 955 | |
| 956 | | const var_decl = try p.parseVarDecl(); |
| 957 | | if (var_decl != 0) { |
| 958 | | try p.expectSemicolon(.expected_semi_after_decl, true); |
| 959 | | return var_decl; |
| 956 | if (allow_defer_var) { |
| 957 | const var_decl = try p.parseVarDecl(); |
| 958 | if (var_decl != 0) { |
| 959 | try p.expectSemicolon(.expected_semi_after_decl, true); |
| 960 | return var_decl; |
| 961 | } |
| 960 | 962 | } |
| 961 | 963 | |
| 962 | 964 | if (comptime_token) |token| { |
| ... | ... | @@ -993,7 +995,7 @@ const Parser = struct { |
| 993 | 995 | }, |
| 994 | 996 | }); |
| 995 | 997 | }, |
| 996 | | .keyword_defer => return p.addNode(.{ |
| 998 | .keyword_defer => if (allow_defer_var) return p.addNode(.{ |
| 997 | 999 | .tag = .@"defer", |
| 998 | 1000 | .main_token = p.nextToken(), |
| 999 | 1001 | .data = .{ |
| ... | ... | @@ -1001,7 +1003,7 @@ const Parser = struct { |
| 1001 | 1003 | .rhs = try p.expectBlockExprStatement(), |
| 1002 | 1004 | }, |
| 1003 | 1005 | }), |
| 1004 | | .keyword_errdefer => return p.addNode(.{ |
| 1006 | .keyword_errdefer => if (allow_defer_var) return p.addNode(.{ |
| 1005 | 1007 | .tag = .@"errdefer", |
| 1006 | 1008 | .main_token = p.nextToken(), |
| 1007 | 1009 | .data = .{ |
| ... | ... | @@ -1040,8 +1042,8 @@ const Parser = struct { |
| 1040 | 1042 | return null_node; |
| 1041 | 1043 | } |
| 1042 | 1044 | |
| 1043 | | fn expectStatement(p: *Parser) !Node.Index { |
| 1044 | | const statement = try p.parseStatement(); |
| 1045 | fn expectStatement(p: *Parser, allow_defer_var: bool) !Node.Index { |
| 1046 | const statement = try p.parseStatement(allow_defer_var); |
| 1045 | 1047 | if (statement == 0) { |
| 1046 | 1048 | return p.fail(.expected_statement); |
| 1047 | 1049 | } |
| ... | ... | @@ -1053,7 +1055,7 @@ const Parser = struct { |
| 1053 | 1055 | /// statement, returns 0. |
| 1054 | 1056 | fn expectStatementRecoverable(p: *Parser) Error!Node.Index { |
| 1055 | 1057 | while (true) { |
| 1056 | | return p.expectStatement() catch |err| switch (err) { |
| 1058 | return p.expectStatement(true) catch |err| switch (err) { |
| 1057 | 1059 | error.OutOfMemory => return error.OutOfMemory, |
| 1058 | 1060 | error.ParseError => { |
| 1059 | 1061 | p.findNextStmt(); // Try to skip to the next statement. |
| ... | ... | @@ -1114,7 +1116,7 @@ const Parser = struct { |
| 1114 | 1116 | }); |
| 1115 | 1117 | }; |
| 1116 | 1118 | _ = try p.parsePayload(); |
| 1117 | | const else_expr = try p.expectStatement(); |
| 1119 | const else_expr = try p.expectStatement(false); |
| 1118 | 1120 | return p.addNode(.{ |
| 1119 | 1121 | .tag = .@"if", |
| 1120 | 1122 | .main_token = if_token, |
| ... | ... | @@ -1226,7 +1228,7 @@ const Parser = struct { |
| 1226 | 1228 | .lhs = array_expr, |
| 1227 | 1229 | .rhs = try p.addExtra(Node.If{ |
| 1228 | 1230 | .then_expr = then_expr, |
| 1229 | | .else_expr = try p.expectStatement(), |
| 1231 | .else_expr = try p.expectStatement(false), |
| 1230 | 1232 | }), |
| 1231 | 1233 | }, |
| 1232 | 1234 | }); |
| ... | ... | @@ -1309,7 +1311,7 @@ const Parser = struct { |
| 1309 | 1311 | } |
| 1310 | 1312 | }; |
| 1311 | 1313 | _ = try p.parsePayload(); |
| 1312 | | const else_expr = try p.expectStatement(); |
| 1314 | const else_expr = try p.expectStatement(false); |
| 1313 | 1315 | return p.addNode(.{ |
| 1314 | 1316 | .tag = .@"while", |
| 1315 | 1317 | .main_token = while_token, |