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
signaturelock-open 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) {
166166 ExpectedDerefOrUnwrap: ExpectedDerefOrUnwrap,
167167 ExpectedSuffixOp: ExpectedSuffixOp,
168168 DeclBetweenFields: DeclBetweenFields,
169 MissingComma: MissingComma,
170169 InvalidAnd: InvalidAnd,
171170
172171 pub fn render(self: *const Error, tokens: *Tree.TokenList, stream: var) !void {
......@@ -217,7 +216,6 @@ pub const Error = union(enum) {
217216 .ExpectedDerefOrUnwrap => |*x| return x.render(tokens, stream),
218217 .ExpectedSuffixOp => |*x| return x.render(tokens, stream),
219218 .DeclBetweenFields => |*x| return x.render(tokens, stream),
220 .MissingComma => |*x| return x.render(tokens, stream),
221219 .InvalidAnd => |*x| return x.render(tokens, stream),
222220 }
223221 }
......@@ -270,7 +268,6 @@ pub const Error = union(enum) {
270268 .ExpectedDerefOrUnwrap => |x| return x.token,
271269 .ExpectedSuffixOp => |x| return x.token,
272270 .DeclBetweenFields => |x| return x.token,
273 .MissingComma => |x| return x.token,
274271 .InvalidAnd => |x| return x.token,
275272 }
276273 }
......@@ -318,7 +315,6 @@ pub const Error = union(enum) {
318315 pub const ExtraVolatileQualifier = SimpleError("Extra volatile qualifier");
319316 pub const ExtraAllowZeroQualifier = SimpleError("Extra allowzero qualifier");
320317 pub const DeclBetweenFields = SimpleError("Declarations are not allowed between container fields");
321 pub const MissingComma = SimpleError("Expected comma between items");
322318 pub const InvalidAnd = SimpleError("`&&` is invalid. Note that `and` is boolean AND.");
323319
324320 pub const ExpectedCall = struct {
......@@ -926,7 +922,7 @@ pub const Node = struct {
926922 if (i < 1) return node;
927923 i -= 1;
928924 },
929 .Invalid => unreachable,
925 .Invalid => {},
930926 }
931927
932928 if (self.body_node) |body_node| {
......@@ -948,7 +944,7 @@ pub const Node = struct {
948944 if (self.body_node) |body_node| return body_node.lastToken();
949945 switch (self.return_type) {
950946 .Explicit, .InferErrorSet => |node| return node.lastToken(),
951 .Invalid => unreachable,
947 .Invalid => |tok| return tok,
952948 }
953949 }
954950 };
lib/std/zig/parse.zig+9-29
......@@ -78,7 +78,7 @@ fn parseRoot(arena: *Allocator, it: *TokenIterator, tree: *Tree) Allocator.Error
7878/// / KEYWORD_pub? ContainerField COMMA ContainerMembers
7979/// / KEYWORD_pub? ContainerField
8080/// /
81fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) Allocator.Error!Node.Root.DeclList {
81fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !Node.Root.DeclList {
8282 var list = Node.Root.DeclList.init(arena);
8383
8484 var field_state: union(enum) {
......@@ -136,7 +136,7 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) All
136136 if (parseTopLevelDecl(arena, it, tree) catch |err| switch (err) {
137137 error.OutOfMemory => return error.OutOfMemory,
138138 error.ParseError => {
139 // try again
139 findNextContainerMember(it);
140140 continue;
141141 },
142142 }) |node| {
......@@ -324,7 +324,7 @@ fn findNextStmt(it: *TokenIterator) void {
324324}
325325
326326/// 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 {
328328 var lines = Node.DocComment.LineList.init(arena);
329329 while (eatToken(it, .ContainerDocComment)) |line| {
330330 try lines.push(line);
......@@ -384,7 +384,7 @@ fn parseTopLevelComptime(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*
384384/// <- (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE? / (KEYWORD_inline / KEYWORD_noinline))? FnProto (SEMICOLON / Block)
385385/// / (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE?)? KEYWORD_threadlocal? VarDecl
386386/// / KEYWORD_usingnamespace Expr SEMICOLON
387fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?*Node {
387fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
388388 var lib_name: ?*Node = null;
389389 const extern_export_inline_token = blk: {
390390 if (eatToken(it, .Keyword_export)) |token| break :blk token;
......@@ -397,13 +397,7 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?
397397 break :blk null;
398398 };
399399
400 if (parseFnProto(arena, it, tree) catch |err| switch (err) {
401 error.OutOfMemory => return error.OutOfMemory,
402 error.ParseError => {
403 findNextContainerMember(it);
404 return error.ParseError;
405 },
406 }) |node| {
400 if (try parseFnProto(arena, it, tree)) |node| {
407401 const fn_node = node.cast(Node.FnProto).?;
408402 fn_node.*.extern_export_inline_token = extern_export_inline_token;
409403 fn_node.*.lib_name = lib_name;
......@@ -413,7 +407,7 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?
413407 // since parseBlock only return error.ParseError on
414408 // a missing '}' we can assume this function was
415409 // supposed to end here.
416 error.ParseError => null,
410 error.ParseError => return node,
417411 }) |body_node| {
418412 fn_node.body_node = body_node;
419413 return node;
......@@ -437,14 +431,7 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?
437431
438432 const thread_local_token = eatToken(it, .Keyword_threadlocal);
439433
440 if (parseVarDecl(arena, it, tree) catch |err| switch (err) {
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| {
434 if (try parseVarDecl(arena, it, tree)) |node| {
448435 var var_decl = node.cast(Node.VarDecl).?;
449436 var_decl.*.thread_local_token = thread_local_token;
450437 var_decl.*.comptime_token = null;
......@@ -469,14 +456,7 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?
469456 return error.ParseError;
470457 }
471458
472 return parseUse(arena, it, tree) catch |err| switch (err) {
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 };
459 return try parseUse(arena, it, tree);
480460}
481461
482462/// 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) {
29262906 // this is likely just a missing comma,
29272907 // continue parsing this list and give an error
29282908 try tree.errors.push(.{
2929 .MissingComma = .{ .token = it.index },
2909 .ExpectedToken = .{ .token = it.index, .expected_id = .Comma },
29302910 });
29312911 },
29322912 }
lib/std/zig/parser_test.zig+2-3
......@@ -32,8 +32,8 @@ test "recovery: missing comma" {
3232 \\ }
3333 \\}
3434 , &[_]Error{
35 .MissingComma,
36 .MissingComma,
35 .ExpectedToken,
36 .ExpectedToken,
3737 .InvalidAnd,
3838 .InvalidToken,
3939 });
......@@ -2983,7 +2983,6 @@ test "zig fmt: extern without container keyword returns error" {
29832983 , &[_]Error{
29842984 .ExpectedExpr,
29852985 .ExpectedVarDeclOrFn,
2986 .ExpectedContainerMembers,
29872986 });
29882987}
29892988
lib/std/zig/render.zig+3
......@@ -13,6 +13,9 @@ pub const Error = error{
1313
1414/// Returns whether anything changed
1515pub 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
1619 // make a passthrough stream that checks whether something changed
1720 const MyStream = struct {
1821 const MyStream = @This();