diff options
| author | Jimmi Holst Christensen <jhc@liab.dk> | 2018-04-04 10:54:48 +0200 |
|---|---|---|
| committer | Jimmi Holst Christensen <jhc@liab.dk> | 2018-04-04 10:54:48 +0200 |
| commit | ca0085c46dc5acb6ea93e35192b7b52294381d75 (patch) | |
| tree | 980962cb2ba08744b3ce4299a91f11d576043204 /std | |
| parent | 020724cfa0677bf42f48957d0ca7a474f6fe31e0 (diff) | |
| download | zig-ca0085c46dc5acb6ea93e35192b7b52294381d75.tar.gz zig-ca0085c46dc5acb6ea93e35192b7b52294381d75.zip | |
std.zig.parser now parses error set declarations
Diffstat (limited to 'std')
| -rw-r--r-- | std/zig/ast.zig | 47 | ||||
| -rw-r--r-- | std/zig/parser.zig | 111 |
2 files changed, 137 insertions, 21 deletions
diff --git a/std/zig/ast.zig b/std/zig/ast.zig index 1d42d721d9..efb959c7f2 100644 --- a/std/zig/ast.zig +++ b/std/zig/ast.zig @@ -11,6 +11,7 @@ pub const Node = struct { pub const Id = enum { Root, VarDecl, + ErrorSetDecl, ContainerDecl, StructField, UnionTag, @@ -44,6 +45,7 @@ pub const Node = struct { return switch (base.id) { Id.Root => @fieldParentPtr(NodeRoot, "base", base).iterate(index), Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).iterate(index), + Id.ErrorSetDecl => @fieldParentPtr(NodeErrorSetDecl, "base", base).iterate(index), Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).iterate(index), Id.StructField => @fieldParentPtr(NodeStructField, "base", base).iterate(index), Id.UnionTag => @fieldParentPtr(NodeUnionTag, "base", base).iterate(index), @@ -78,6 +80,7 @@ pub const Node = struct { return switch (base.id) { Id.Root => @fieldParentPtr(NodeRoot, "base", base).firstToken(), Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).firstToken(), + Id.ErrorSetDecl => @fieldParentPtr(NodeErrorSetDecl, "base", base).firstToken(), Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).firstToken(), Id.StructField => @fieldParentPtr(NodeStructField, "base", base).firstToken(), Id.UnionTag => @fieldParentPtr(NodeUnionTag, "base", base).firstToken(), @@ -112,6 +115,7 @@ pub const Node = struct { return switch (base.id) { Id.Root => @fieldParentPtr(NodeRoot, "base", base).lastToken(), Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).lastToken(), + Id.ErrorSetDecl => @fieldParentPtr(NodeErrorSetDecl, "base", base).lastToken(), Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).lastToken(), Id.StructField => @fieldParentPtr(NodeStructField, "base", base).lastToken(), Id.UnionTag => @fieldParentPtr(NodeUnionTag, "base", base).lastToken(), @@ -212,6 +216,30 @@ pub const NodeVarDecl = struct { } }; +pub const NodeErrorSetDecl = struct { + base: Node, + error_token: Token, + decls: ArrayList(&NodeIdentifier), + rbrace_token: Token, + + pub fn iterate(self: &NodeErrorSetDecl, index: usize) ?&Node { + var i = index; + + if (i < self.decls.len) return self.decls.at(i); + i -= self.decls.len; + + return null; + } + + pub fn firstToken(self: &NodeErrorSetDecl) Token { + return self.error_token; + } + + pub fn lastToken(self: &NodeErrorSetDecl) Token { + return self.rbrace_token; + } +}; + pub const NodeContainerDecl = struct { base: Node, ltoken: Token, @@ -251,23 +279,8 @@ pub const NodeContainerDecl = struct { InitArg.Enum => { } } - if (i < self.decls.len) return self.decls.at(i); - i -= self.decls.len; - - switch (self.kind) { - Kind.Struct => |fields| { - if (i < fields.len) return fields.at(i); - i -= fields.len; - }, - Kind.Enum => |tags| { - if (i < tags.len) return tags.at(i); - i -= tags.len; - }, - Kind.Union => |tags| { - if (i < tags.len) return tags.at(i); - i -= tags.len; - }, - } + if (i < self.fields_and_decls.len) return self.fields_and_decls.at(i); + i -= self.fields_and_decls.len; return null; } diff --git a/std/zig/parser.zig b/std/zig/parser.zig index f7db8fd93d..8177700fb5 100644 --- a/std/zig/parser.zig +++ b/std/zig/parser.zig @@ -685,11 +685,66 @@ pub const Parser = struct { continue; }, Token.Id.Keyword_error => { - const node = try arena.create(ast.NodeErrorType); - *node = ast.NodeErrorType { - .base = self.initNode(ast.Node.Id.ErrorType), - .token = token, + const next = self.getNextToken(); + + if (next.id != Token.Id.LBrace) { + self.putBackToken(next); + const node = try arena.create(ast.NodeErrorType); + *node = ast.NodeErrorType { + .base = self.initNode(ast.Node.Id.ErrorType), + .token = token, + }; + try stack.append(State { + .Operand = &node.base + }); + try stack.append(State.AfterOperand); + continue; + } + + const node = try arena.create(ast.NodeErrorSetDecl); + *node = ast.NodeErrorSetDecl { + .base = self.initNode(ast.Node.Id.ErrorSetDecl), + .error_token = token, + .decls = ArrayList(&ast.NodeIdentifier).init(arena), + .rbrace_token = undefined, }; + + while (true) { + const t = self.getNextToken(); + switch (t.id) { + Token.Id.RBrace => { + node.rbrace_token = t; + break; + }, + Token.Id.Identifier => { + try node.decls.append( + try self.createIdentifier(arena, t) + ); + }, + else => { + return self.parseError(token, "expected {} or {}, found {}", + @tagName(Token.Id.RBrace), + @tagName(Token.Id.Identifier), + @tagName(token.id)); + } + } + + const t2 = self.getNextToken(); + switch (t2.id) { + Token.Id.RBrace => { + node.rbrace_token = t; + break; + }, + Token.Id.Comma => continue, + else => { + return self.parseError(token, "expected {} or {}, found {}", + @tagName(Token.Id.RBrace), + @tagName(Token.Id.Comma), + @tagName(token.id)); + } + } + } + try stack.append(State { .Operand = &node.base }); @@ -2115,6 +2170,42 @@ pub const Parser = struct { }, } }, + ast.Node.Id.ErrorSetDecl => { + const err_set_decl = @fieldParentPtr(ast.NodeErrorSetDecl, "base", base); + try stream.print("error "); + + try stack.append(RenderState { .Text = "}"}); + try stack.append(RenderState.PrintIndent); + try stack.append(RenderState { .Indent = indent }); + try stack.append(RenderState { .Text = "\n"}); + + const decls = err_set_decl.decls.toSliceConst(); + var i = decls.len; + while (i != 0) { + i -= 1; + const node = decls[i]; + try stack.append(RenderState { .Expression = &node.base}); + try stack.append(RenderState.PrintIndent); + try stack.append(RenderState { + .Text = blk: { + if (i != 0) { + const prev_node = decls[i - 1]; + const loc = self.tokenizer.getTokenLocation(prev_node.lastToken().end, node.firstToken()); + if (loc.line >= 2) { + break :blk "\n\n"; + } + } + break :blk "\n"; + }, + }); + + if (i != 0) { + try stack.append(RenderState { .Text = "," }); + } + } + try stack.append(RenderState { .Indent = indent + indent_delta}); + try stack.append(RenderState { .Text = "{"}); + }, ast.Node.Id.MultilineStringLiteral => { const multiline_str_literal = @fieldParentPtr(ast.NodeMultilineStringLiteral, "base", base); try stream.print("\n"); @@ -2643,6 +2734,18 @@ test "zig fmt: union declaration" { ); } +test "zig fmt: error set declaration" { + try testCanonical( + \\const E = error { + \\ A, + \\ B, + \\ + \\ C + \\}; + \\ + ); +} + test "zig fmt: switch" { try testCanonical( \\test "switch" { |
