zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit e07b467c7cdca192ff18d5c5550ff07c91a665c5 (tree)
parent 69ff89fd1207bc95adf7a349319973c6070ce540
Author: Vexu <git@vexu.eu>
Date:   Wed, 20 May 2020 11:34:31 +0300

fix missing compile error on while/for missing block

Diffstat:
Mlib/std/zig/ast.zig | 1-
Mlib/std/zig/parse.zig | 81++++++++++++++++++++++++++++++++++++++-----------------------------------------
Mlib/std/zig/parser_test.zig | 13+++++++++++++
3 files changed, 52 insertions(+), 43 deletions(-)

diff --git a/lib/std/zig/ast.zig b/lib/std/zig/ast.zig @@ -13,7 +13,6 @@ pub const Tree = struct { token_ids: []const Token.Id, token_locs: []const Token.Loc, errors: []const Error, - /// undefined on parse error (when errors field is not empty) root_node: *Node.Root, arena: std.heap.ArenaAllocator.State, diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig @@ -878,34 +878,32 @@ const Parser = struct { return node; } - if (try p.parseAssignExpr()) |assign_expr| { - for_prefix.body = assign_expr; - - if (p.eatToken(.Semicolon) != null) return node; - - if (p.eatToken(.Keyword_else)) |else_token| { - const statement_node = try p.expectNode(parseStatement, .{ - .ExpectedStatement = .{ .token = p.tok_i }, - }); + for_prefix.body = try p.expectNode(parseAssignExpr, .{ + .ExpectedBlockOrAssignment = .{ .token = p.tok_i }, + }); - const else_node = try p.arena.allocator.create(Node.Else); - else_node.* = .{ - .else_token = else_token, - .payload = null, - .body = statement_node, - }; - for_prefix.@"else" = else_node; - return node; - } + if (p.eatToken(.Semicolon) != null) return node; - try p.errors.append(p.gpa, .{ - .ExpectedSemiOrElse = .{ .token = p.tok_i }, + if (p.eatToken(.Keyword_else)) |else_token| { + const statement_node = try p.expectNode(parseStatement, .{ + .ExpectedStatement = .{ .token = p.tok_i }, }); + const else_node = try p.arena.allocator.create(Node.Else); + else_node.* = .{ + .else_token = else_token, + .payload = null, + .body = statement_node, + }; + for_prefix.@"else" = else_node; return node; } - return null; + try p.errors.append(p.gpa, .{ + .ExpectedSemiOrElse = .{ .token = p.tok_i }, + }); + + return node; } /// WhileStatement @@ -939,36 +937,35 @@ const Parser = struct { return node; } - if (try p.parseAssignExpr()) |assign_expr_node| { - while_prefix.body = assign_expr_node; - - if (p.eatToken(.Semicolon) != null) return node; - if (p.eatToken(.Keyword_else)) |else_token| { - const payload = try p.parsePayload(); + while_prefix.body = try p.expectNode(parseAssignExpr, .{ + .ExpectedBlockOrAssignment = .{ .token = p.tok_i }, + }); - const statement_node = try p.expectNode(parseStatement, .{ - .ExpectedStatement = .{ .token = p.tok_i }, - }); + if (p.eatToken(.Semicolon) != null) return node; - const else_node = try p.arena.allocator.create(Node.Else); - else_node.* = .{ - .else_token = else_token, - .payload = payload, - .body = statement_node, - }; - while_prefix.@"else" = else_node; - return node; - } + if (p.eatToken(.Keyword_else)) |else_token| { + const payload = try p.parsePayload(); - try p.errors.append(p.gpa, .{ - .ExpectedSemiOrElse = .{ .token = p.tok_i }, + const statement_node = try p.expectNode(parseStatement, .{ + .ExpectedStatement = .{ .token = p.tok_i }, }); + const else_node = try p.arena.allocator.create(Node.Else); + else_node.* = .{ + .else_token = else_token, + .payload = payload, + .body = statement_node, + }; + while_prefix.@"else" = else_node; return node; } - return null; + try p.errors.append(p.gpa, .{ + .ExpectedSemiOrElse = .{ .token = p.tok_i }, + }); + + return node; } /// BlockExprStatement diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig @@ -210,6 +210,19 @@ test "recovery: invalid comptime" { }); } +test "recovery: missing block after for/while loops" { + try testError( + \\test "" { while (foo) } + , &[_]Error{ + .ExpectedBlockOrAssignment, + }); + try testError( + \\test "" { for (foo) |bar| } + , &[_]Error{ + .ExpectedBlockOrAssignment, + }); +} + test "zig fmt: if statment" { try testCanonical( \\test "" {