Commit ca0085c46d
Changed files (2)
std
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;
}
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" {