diff options
| author | Vexu <git@vexu.eu> | 2020-05-14 19:56:55 +0300 |
|---|---|---|
| committer | Vexu <git@vexu.eu> | 2020-05-14 19:56:55 +0300 |
| commit | c77fee03448817366a2cda98915bc31ba8f2b451 (patch) | |
| tree | 01adc52f94627b21c6f212f8a0babd8de7dea63e /lib/std | |
| parent | c4552ee8edec961defb161e1b828a818f8d407bb (diff) | |
| download | zig-c77fee03448817366a2cda98915bc31ba8f2b451.tar.gz zig-c77fee03448817366a2cda98915bc31ba8f2b451.zip | |
fix infinite loop
findToken wasn't as generic as I thought it was
Diffstat (limited to 'lib/std')
| -rw-r--r-- | lib/std/zig/parse.zig | 28 | ||||
| -rw-r--r-- | lib/std/zig/parser_test.zig | 10 |
2 files changed, 26 insertions, 12 deletions
diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig index 98b1e9d329..74945b1b33 100644 --- a/lib/std/zig/parse.zig +++ b/lib/std/zig/parse.zig @@ -213,7 +213,7 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) All .ExpectedToken = .{ .token = index, .expected_id = .Comma }, }); continue; - } + }, } }; if (try parseAppendedDocComment(arena, it, tree, comma)) |appended_comment| @@ -245,6 +245,7 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) All return list; } +/// Attempts to find next container member by searching for certain tokens fn findNextContainerMember(it: *TokenIterator) void { var level: u32 = 0; while (true) { @@ -294,27 +295,30 @@ fn findNextContainerMember(it: *TokenIterator) void { } } -/// Attempts to find `wanted` token, keeps track of parentheses. -fn findToken(it: *TokenIterator, wanted: Token.Id) void { - var count: u32 = 0; +/// Attempts to find the next statement by searching for a semicolon +fn findNextStmt(it: *TokenIterator) void { + var level: u32 = 0; while (true) { const tok = nextToken(it); switch (tok.ptr.id) { - .LParen, .LBracket, .LBrace => count += 1, - .RParen, .RBracket, .RBrace => { - if (count == 0) { + .LBrace => level += 1, + .RBrace => { + if (level == 0) { putBackToken(it, tok.index); return; } - count -= 1; + level -= 1; + }, + .Semicolon => { + if (level == 0) { + return; + } }, .Eof => { putBackToken(it, tok.index); return; }, - else => { - if (tok.ptr.id == wanted and count == 0) return; - }, + else => {}, } } } @@ -1186,7 +1190,7 @@ fn parseBlock(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { error.OutOfMemory => return error.OutOfMemory, error.ParseError => { // try to skip to the next statement - findToken(it, .Semicolon); + findNextStmt(it); continue; }, }) orelse break; diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig index 8cbf2d4610..f92cc5a222 100644 --- a/lib/std/zig/parser_test.zig +++ b/lib/std/zig/parser_test.zig @@ -138,6 +138,16 @@ test "recovery: invalid container members" { }); } +test "recovery: invalid parameter" { + try testError( + \\fn main() void { + \\ a(comptime T: type) + \\} + , &[_]Error{ + .ExpectedToken, + }); +} + test "zig fmt: top-level fields" { try testCanonical( \\a: did_you_know, |
