authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-05-14 19:56:55+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-05-14 19:56:55+03:00
logc77fee03448817366a2cda98915bc31ba8f2b451
tree01adc52f94627b21c6f212f8a0babd8de7dea63e
parentc4552ee8edec961defb161e1b828a818f8d407bb
signaturelock-open Commit is signed but in an unrecognized format.

fix infinite loop

findToken wasn't as generic as I thought it was

2 files changed, 26 insertions(+), 12 deletions(-)

lib/std/zig/parse.zig+16-12
...@@ -213,7 +213,7 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) All...@@ -213,7 +213,7 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) All
213 .ExpectedToken = .{ .token = index, .expected_id = .Comma },213 .ExpectedToken = .{ .token = index, .expected_id = .Comma },
214 });214 });
215 continue;215 continue;
216 }216 },
217 }217 }
218 };218 };
219 if (try parseAppendedDocComment(arena, it, tree, comma)) |appended_comment|219 if (try parseAppendedDocComment(arena, it, tree, comma)) |appended_comment|
...@@ -245,6 +245,7 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) All...@@ -245,6 +245,7 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) All
245 return list;245 return list;
246}246}
247247
248/// Attempts to find next container member by searching for certain tokens
248fn findNextContainerMember(it: *TokenIterator) void {249fn findNextContainerMember(it: *TokenIterator) void {
249 var level: u32 = 0;250 var level: u32 = 0;
250 while (true) {251 while (true) {
...@@ -294,27 +295,30 @@ fn findNextContainerMember(it: *TokenIterator) void {...@@ -294,27 +295,30 @@ fn findNextContainerMember(it: *TokenIterator) void {
294 }295 }
295}296}
296297
297/// Attempts to find `wanted` token, keeps track of parentheses.298/// Attempts to find the next statement by searching for a semicolon
298fn findToken(it: *TokenIterator, wanted: Token.Id) void {299fn findNextStmt(it: *TokenIterator) void {
299 var count: u32 = 0;300 var level: u32 = 0;
300 while (true) {301 while (true) {
301 const tok = nextToken(it);302 const tok = nextToken(it);
302 switch (tok.ptr.id) {303 switch (tok.ptr.id) {
303 .LParen, .LBracket, .LBrace => count += 1,304 .LBrace => level += 1,
304 .RParen, .RBracket, .RBrace => {305 .RBrace => {
305 if (count == 0) {306 if (level == 0) {
306 putBackToken(it, tok.index);307 putBackToken(it, tok.index);
307 return;308 return;
308 }309 }
309 count -= 1;310 level -= 1;
311 },
312 .Semicolon => {
313 if (level == 0) {
314 return;
315 }
310 },316 },
311 .Eof => {317 .Eof => {
312 putBackToken(it, tok.index);318 putBackToken(it, tok.index);
313 return;319 return;
314 },320 },
315 else => {321 else => {},
316 if (tok.ptr.id == wanted and count == 0) return;
317 },
318 }322 }
319 }323 }
320}324}
...@@ -1186,7 +1190,7 @@ fn parseBlock(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {...@@ -1186,7 +1190,7 @@ fn parseBlock(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
1186 error.OutOfMemory => return error.OutOfMemory,1190 error.OutOfMemory => return error.OutOfMemory,
1187 error.ParseError => {1191 error.ParseError => {
1188 // try to skip to the next statement1192 // try to skip to the next statement
1189 findToken(it, .Semicolon);1193 findNextStmt(it);
1190 continue;1194 continue;
1191 },1195 },
1192 }) orelse break;1196 }) orelse break;
lib/std/zig/parser_test.zig+10
...@@ -138,6 +138,16 @@ test "recovery: invalid container members" {...@@ -138,6 +138,16 @@ test "recovery: invalid container members" {
138 });138 });
139}139}
140140
141test "recovery: invalid parameter" {
142 try testError(
143 \\fn main() void {
144 \\ a(comptime T: type)
145 \\}
146 , &[_]Error{
147 .ExpectedToken,
148 });
149}
150
141test "zig fmt: top-level fields" {151test "zig fmt: top-level fields" {
142 try testCanonical(152 try testCanonical(
143 \\a: did_you_know,153 \\a: did_you_know,