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