authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-05-15 11:06:34+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-05-15 11:35:37+03:00
log440189a04ae4baa4a20114fe1d30f0eb585bacc4
tree29be79c9e31b52099e4861eb68048769d66d6caf
parentc77fee03448817366a2cda98915bc31ba8f2b451
signature Commit is signed but in an unrecognized format.

cleanup* remove unecessary error* properly handle ReturnTypeInvalid in ast.zig functions* assert that the tree is clean in render.zig* simplify parser recovery with top level decls


4 files changed, 16 insertions(+), 38 deletions(-)

lib/std/zig/ast.zig+2-6
...@@ -166,7 +166,6 @@ pub const Error = union(enum) {...@@ -166,7 +166,6 @@ pub const Error = union(enum) {
166 ExpectedDerefOrUnwrap: ExpectedDerefOrUnwrap,166 ExpectedDerefOrUnwrap: ExpectedDerefOrUnwrap,
167 ExpectedSuffixOp: ExpectedSuffixOp,167 ExpectedSuffixOp: ExpectedSuffixOp,
168 DeclBetweenFields: DeclBetweenFields,168 DeclBetweenFields: DeclBetweenFields,
169 MissingComma: MissingComma,
170 InvalidAnd: InvalidAnd,169 InvalidAnd: InvalidAnd,
171170
172 pub fn render(self: *const Error, tokens: *Tree.TokenList, stream: var) !void {171 pub fn render(self: *const Error, tokens: *Tree.TokenList, stream: var) !void {
...@@ -217,7 +216,6 @@ pub const Error = union(enum) {...@@ -217,7 +216,6 @@ pub const Error = union(enum) {
217 .ExpectedDerefOrUnwrap => |*x| return x.render(tokens, stream),216 .ExpectedDerefOrUnwrap => |*x| return x.render(tokens, stream),
218 .ExpectedSuffixOp => |*x| return x.render(tokens, stream),217 .ExpectedSuffixOp => |*x| return x.render(tokens, stream),
219 .DeclBetweenFields => |*x| return x.render(tokens, stream),218 .DeclBetweenFields => |*x| return x.render(tokens, stream),
220 .MissingComma => |*x| return x.render(tokens, stream),
221 .InvalidAnd => |*x| return x.render(tokens, stream),219 .InvalidAnd => |*x| return x.render(tokens, stream),
222 }220 }
223 }221 }
...@@ -270,7 +268,6 @@ pub const Error = union(enum) {...@@ -270,7 +268,6 @@ pub const Error = union(enum) {
270 .ExpectedDerefOrUnwrap => |x| return x.token,268 .ExpectedDerefOrUnwrap => |x| return x.token,
271 .ExpectedSuffixOp => |x| return x.token,269 .ExpectedSuffixOp => |x| return x.token,
272 .DeclBetweenFields => |x| return x.token,270 .DeclBetweenFields => |x| return x.token,
273 .MissingComma => |x| return x.token,
274 .InvalidAnd => |x| return x.token,271 .InvalidAnd => |x| return x.token,
275 }272 }
276 }273 }
...@@ -318,7 +315,6 @@ pub const Error = union(enum) {...@@ -318,7 +315,6 @@ pub const Error = union(enum) {
318 pub const ExtraVolatileQualifier = SimpleError("Extra volatile qualifier");315 pub const ExtraVolatileQualifier = SimpleError("Extra volatile qualifier");
319 pub const ExtraAllowZeroQualifier = SimpleError("Extra allowzero qualifier");316 pub const ExtraAllowZeroQualifier = SimpleError("Extra allowzero qualifier");
320 pub const DeclBetweenFields = SimpleError("Declarations are not allowed between container fields");317 pub const DeclBetweenFields = SimpleError("Declarations are not allowed between container fields");
321 pub const MissingComma = SimpleError("Expected comma between items");
322 pub const InvalidAnd = SimpleError("`&&` is invalid. Note that `and` is boolean AND.");318 pub const InvalidAnd = SimpleError("`&&` is invalid. Note that `and` is boolean AND.");
323319
324 pub const ExpectedCall = struct {320 pub const ExpectedCall = struct {
...@@ -926,7 +922,7 @@ pub const Node = struct {...@@ -926,7 +922,7 @@ pub const Node = struct {
926 if (i < 1) return node;922 if (i < 1) return node;
927 i -= 1;923 i -= 1;
928 },924 },
929 .Invalid => unreachable,925 .Invalid => {},
930 }926 }
931927
932 if (self.body_node) |body_node| {928 if (self.body_node) |body_node| {
...@@ -948,7 +944,7 @@ pub const Node = struct {...@@ -948,7 +944,7 @@ pub const Node = struct {
948 if (self.body_node) |body_node| return body_node.lastToken();944 if (self.body_node) |body_node| return body_node.lastToken();
949 switch (self.return_type) {945 switch (self.return_type) {
950 .Explicit, .InferErrorSet => |node| return node.lastToken(),946 .Explicit, .InferErrorSet => |node| return node.lastToken(),
951 .Invalid => unreachable,947 .Invalid => |tok| return tok,
952 }948 }
953 }949 }
954 };950 };
lib/std/zig/parse.zig+9-29
...@@ -78,7 +78,7 @@ fn parseRoot(arena: *Allocator, it: *TokenIterator, tree: *Tree) Allocator.Error...@@ -78,7 +78,7 @@ fn parseRoot(arena: *Allocator, it: *TokenIterator, tree: *Tree) Allocator.Error
78/// / KEYWORD_pub? ContainerField COMMA ContainerMembers78/// / KEYWORD_pub? ContainerField COMMA ContainerMembers
79/// / KEYWORD_pub? ContainerField79/// / KEYWORD_pub? ContainerField
80/// /80/// /
81fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) Allocator.Error!Node.Root.DeclList {81fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !Node.Root.DeclList {
82 var list = Node.Root.DeclList.init(arena);82 var list = Node.Root.DeclList.init(arena);
8383
84 var field_state: union(enum) {84 var field_state: union(enum) {
...@@ -136,7 +136,7 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) All...@@ -136,7 +136,7 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) All
136 if (parseTopLevelDecl(arena, it, tree) catch |err| switch (err) {136 if (parseTopLevelDecl(arena, it, tree) catch |err| switch (err) {
137 error.OutOfMemory => return error.OutOfMemory,137 error.OutOfMemory => return error.OutOfMemory,
138 error.ParseError => {138 error.ParseError => {
139 // try again139 findNextContainerMember(it);
140 continue;140 continue;
141 },141 },
142 }) |node| {142 }) |node| {
...@@ -324,7 +324,7 @@ fn findNextStmt(it: *TokenIterator) void {...@@ -324,7 +324,7 @@ fn findNextStmt(it: *TokenIterator) void {
324}324}
325325
326/// Eat a multiline container doc comment326/// Eat a multiline container doc comment
327fn parseContainerDocComments(arena: *Allocator, it: *TokenIterator, tree: *Tree) Allocator.Error!?*Node {327fn parseContainerDocComments(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
328 var lines = Node.DocComment.LineList.init(arena);328 var lines = Node.DocComment.LineList.init(arena);
329 while (eatToken(it, .ContainerDocComment)) |line| {329 while (eatToken(it, .ContainerDocComment)) |line| {
330 try lines.push(line);330 try lines.push(line);
...@@ -384,7 +384,7 @@ fn parseTopLevelComptime(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*...@@ -384,7 +384,7 @@ fn parseTopLevelComptime(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*
384/// <- (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE? / (KEYWORD_inline / KEYWORD_noinline))? FnProto (SEMICOLON / Block)384/// <- (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE? / (KEYWORD_inline / KEYWORD_noinline))? FnProto (SEMICOLON / Block)
385/// / (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE?)? KEYWORD_threadlocal? VarDecl385/// / (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE?)? KEYWORD_threadlocal? VarDecl
386/// / KEYWORD_usingnamespace Expr SEMICOLON386/// / KEYWORD_usingnamespace Expr SEMICOLON
387fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?*Node {387fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
388 var lib_name: ?*Node = null;388 var lib_name: ?*Node = null;
389 const extern_export_inline_token = blk: {389 const extern_export_inline_token = blk: {
390 if (eatToken(it, .Keyword_export)) |token| break :blk token;390 if (eatToken(it, .Keyword_export)) |token| break :blk token;
...@@ -397,13 +397,7 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?...@@ -397,13 +397,7 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?
397 break :blk null;397 break :blk null;
398 };398 };
399399
400 if (parseFnProto(arena, it, tree) catch |err| switch (err) {400 if (try parseFnProto(arena, it, tree)) |node| {
401 error.OutOfMemory => return error.OutOfMemory,
402 error.ParseError => {
403 findNextContainerMember(it);
404 return error.ParseError;
405 },
406 }) |node| {
407 const fn_node = node.cast(Node.FnProto).?;401 const fn_node = node.cast(Node.FnProto).?;
408 fn_node.*.extern_export_inline_token = extern_export_inline_token;402 fn_node.*.extern_export_inline_token = extern_export_inline_token;
409 fn_node.*.lib_name = lib_name;403 fn_node.*.lib_name = lib_name;
...@@ -413,7 +407,7 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?...@@ -413,7 +407,7 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?
413 // since parseBlock only return error.ParseError on407 // since parseBlock only return error.ParseError on
414 // a missing '}' we can assume this function was408 // a missing '}' we can assume this function was
415 // supposed to end here.409 // supposed to end here.
416 error.ParseError => null,410 error.ParseError => return node,
417 }) |body_node| {411 }) |body_node| {
418 fn_node.body_node = body_node;412 fn_node.body_node = body_node;
419 return node;413 return node;
...@@ -437,14 +431,7 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?...@@ -437,14 +431,7 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?
437431
438 const thread_local_token = eatToken(it, .Keyword_threadlocal);432 const thread_local_token = eatToken(it, .Keyword_threadlocal);
439433
440 if (parseVarDecl(arena, it, tree) catch |err| switch (err) {434 if (try parseVarDecl(arena, it, tree)) |node| {
441 error.OutOfMemory => return error.OutOfMemory,
442 error.ParseError => {
443 // try to skip to next decl
444 findNextContainerMember(it);
445 return error.ParseError;
446 },
447 }) |node| {
448 var var_decl = node.cast(Node.VarDecl).?;435 var var_decl = node.cast(Node.VarDecl).?;
449 var_decl.*.thread_local_token = thread_local_token;436 var_decl.*.thread_local_token = thread_local_token;
450 var_decl.*.comptime_token = null;437 var_decl.*.comptime_token = null;
...@@ -469,14 +456,7 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?...@@ -469,14 +456,7 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?
469 return error.ParseError;456 return error.ParseError;
470 }457 }
471458
472 return parseUse(arena, it, tree) catch |err| switch (err) {459 return try parseUse(arena, it, tree);
473 error.OutOfMemory => return error.OutOfMemory,
474 error.ParseError => {
475 // try to skip to next decl
476 findNextContainerMember(it);
477 return error.ParseError;
478 },
479 };
480}460}
481461
482/// FnProto <- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)462/// FnProto <- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)
...@@ -2926,7 +2906,7 @@ fn ListParseFn(comptime L: type, comptime nodeParseFn: var) ParseFn(L) {...@@ -2926,7 +2906,7 @@ fn ListParseFn(comptime L: type, comptime nodeParseFn: var) ParseFn(L) {
2926 // this is likely just a missing comma,2906 // this is likely just a missing comma,
2927 // continue parsing this list and give an error2907 // continue parsing this list and give an error
2928 try tree.errors.push(.{2908 try tree.errors.push(.{
2929 .MissingComma = .{ .token = it.index },2909 .ExpectedToken = .{ .token = it.index, .expected_id = .Comma },
2930 });2910 });
2931 },2911 },
2932 }2912 }
lib/std/zig/parser_test.zig+2-3
...@@ -32,8 +32,8 @@ test "recovery: missing comma" {...@@ -32,8 +32,8 @@ test "recovery: missing comma" {
32 \\ }32 \\ }
33 \\}33 \\}
34 , &[_]Error{34 , &[_]Error{
35 .MissingComma,35 .ExpectedToken,
36 .MissingComma,36 .ExpectedToken,
37 .InvalidAnd,37 .InvalidAnd,
38 .InvalidToken,38 .InvalidToken,
39 });39 });
...@@ -2983,7 +2983,6 @@ test "zig fmt: extern without container keyword returns error" {...@@ -2983,7 +2983,6 @@ test "zig fmt: extern without container keyword returns error" {
2983 , &[_]Error{2983 , &[_]Error{
2984 .ExpectedExpr,2984 .ExpectedExpr,
2985 .ExpectedVarDeclOrFn,2985 .ExpectedVarDeclOrFn,
2986 .ExpectedContainerMembers,
2987 });2986 });
2988}2987}
29892988
lib/std/zig/render.zig+3
...@@ -13,6 +13,9 @@ pub const Error = error{...@@ -13,6 +13,9 @@ pub const Error = error{
1313
14/// Returns whether anything changed14/// Returns whether anything changed
15pub fn render(allocator: *mem.Allocator, stream: var, tree: *ast.Tree) (@TypeOf(stream).Error || Error)!bool {15pub fn render(allocator: *mem.Allocator, stream: var, tree: *ast.Tree) (@TypeOf(stream).Error || Error)!bool {
16 // cannot render an invalid tree
17 std.debug.assert(tree.errors.len == 0);
18
16 // make a passthrough stream that checks whether something changed19 // make a passthrough stream that checks whether something changed
17 const MyStream = struct {20 const MyStream = struct {
18 const MyStream = @This();21 const MyStream = @This();