authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-04-30 18:20:27-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-04-30 18:20:27-04:00
log1d06915f275ac59918c32206ad944fd10cc997d4
treee64c2f4b132f0fa7de9bddc603420f9c6be573e0
parent7dc8d433abbf697f05eb1ad2003b6335f750557b

zig fmt: support union(enum(tag)) and enum init values


3 files changed, 60 insertions(+), 3 deletions(-)

std/zig/ast.zig+10-1
......@@ -261,7 +261,7 @@ pub const Node = struct {
261261
262262 const InitArg = union(enum) {
263263 None,
264 Enum,
264 Enum: ?&Node,
265265 Type: &Node,
266266 };
267267
......@@ -321,6 +321,7 @@ pub const Node = struct {
321321 base: Node,
322322 name_token: Token,
323323 type_expr: ?&Node,
324 value_expr: ?&Node,
324325
325326 pub fn iterate(self: &UnionTag, index: usize) ?&Node {
326327 var i = index;
......@@ -330,6 +331,11 @@ pub const Node = struct {
330331 i -= 1;
331332 }
332333
334 if (self.value_expr) |value_expr| {
335 if (i < 1) return value_expr;
336 i -= 1;
337 }
338
333339 return null;
334340 }
335341
......@@ -338,6 +344,9 @@ pub const Node = struct {
338344 }
339345
340346 pub fn lastToken(self: &UnionTag) Token {
347 if (self.value_expr) |value_expr| {
348 return value_expr.lastToken();
349 }
341350 if (self.type_expr) |type_expr| {
342351 return type_expr.lastToken();
343352 }
std/zig/parser.zig+38-2
......@@ -242,6 +242,7 @@ pub const Parser = struct {
242242 FieldInitListItemOrEnd: ListSave(&ast.Node.FieldInitializer),
243243 FieldInitListCommaOrEnd: ListSave(&ast.Node.FieldInitializer),
244244 FieldListCommaOrEnd: &ast.Node.ContainerDecl,
245 FieldInitValue: OptionalCtx,
245246 IdentifierListItemOrEnd: ListSave(&ast.Node),
246247 IdentifierListCommaOrEnd: ListSave(&ast.Node),
247248 SwitchCaseOrEnd: ListSave(&ast.Node),
......@@ -653,6 +654,15 @@ pub const Parser = struct {
653654 continue;
654655 },
655656
657 State.FieldInitValue => |ctx| {
658 const eq_tok = self.getNextToken();
659 if (eq_tok.id != Token.Id.Equal) {
660 self.putBackToken(eq_tok);
661 continue;
662 }
663 stack.append(State { .Expression = ctx }) catch unreachable;
664 continue;
665 },
656666
657667 State.ContainerKind => |ctx| {
658668 const token = self.getNextToken();
......@@ -699,7 +709,16 @@ pub const Parser = struct {
699709 const init_arg_token = self.getNextToken();
700710 switch (init_arg_token.id) {
701711 Token.Id.Keyword_enum => {
702 container_decl.init_arg_expr = ast.Node.ContainerDecl.InitArg.Enum;
712 container_decl.init_arg_expr = ast.Node.ContainerDecl.InitArg {.Enum = null};
713 const lparen_tok = self.getNextToken();
714 if (lparen_tok.id == Token.Id.LParen) {
715 try stack.append(State { .ExpectToken = Token.Id.RParen } );
716 try stack.append(State { .Expression = OptionalCtx {
717 .RequiredNull = &container_decl.init_arg_expr.Enum,
718 } });
719 } else {
720 self.putBackToken(lparen_tok);
721 }
703722 },
704723 else => {
705724 self.putBackToken(init_arg_token);
......@@ -709,6 +728,7 @@ pub const Parser = struct {
709728 }
710729 continue;
711730 },
731
712732 State.ContainerDecl => |container_decl| {
713733 while (try self.eatLineComment(arena)) |line_comment| {
714734 try container_decl.fields_and_decls.append(&line_comment.base);
......@@ -744,10 +764,12 @@ pub const Parser = struct {
744764 .base = undefined,
745765 .name_token = token,
746766 .type_expr = null,
767 .value_expr = null,
747768 }
748769 );
749770
750771 stack.append(State { .FieldListCommaOrEnd = container_decl }) catch unreachable;
772 try stack.append(State { .FieldInitValue = OptionalCtx { .RequiredNull = &node.value_expr } });
751773 try stack.append(State { .TypeExprBegin = OptionalCtx { .RequiredNull = &node.type_expr } });
752774 try stack.append(State { .IfToken = Token.Id.Colon });
753775 continue;
......@@ -3515,6 +3537,12 @@ pub const Parser = struct {
35153537 try stream.print("{}", self.tokenizer.getTokenSlice(tag.name_token));
35163538
35173539 try stack.append(RenderState { .Text = "," });
3540
3541 if (tag.value_expr) |value_expr| {
3542 try stack.append(RenderState { .Expression = value_expr });
3543 try stack.append(RenderState { .Text = " = " });
3544 }
3545
35183546 if (tag.type_expr) |type_expr| {
35193547 try stream.print(": ");
35203548 try stack.append(RenderState { .Expression = type_expr});
......@@ -4055,7 +4083,15 @@ pub const Parser = struct {
40554083
40564084 switch (container_decl.init_arg_expr) {
40574085 ast.Node.ContainerDecl.InitArg.None => try stack.append(RenderState { .Text = " "}),
4058 ast.Node.ContainerDecl.InitArg.Enum => try stack.append(RenderState { .Text = "(enum) "}),
4086 ast.Node.ContainerDecl.InitArg.Enum => |enum_tag_type| {
4087 if (enum_tag_type) |expr| {
4088 try stack.append(RenderState { .Text = ")) "});
4089 try stack.append(RenderState { .Expression = expr});
4090 try stack.append(RenderState { .Text = "(enum("});
4091 } else {
4092 try stack.append(RenderState { .Text = "(enum) "});
4093 }
4094 },
40594095 ast.Node.ContainerDecl.InitArg.Type => |type_expr| {
40604096 try stack.append(RenderState { .Text = ") "});
40614097 try stack.append(RenderState { .Expression = type_expr});
std/zig/parser_test.zig+12
......@@ -1,3 +1,15 @@
1test "zig fmt: union(enum(u32)) with assigned enum values" {
2 try testCanonical(
3 \\const MultipleChoice = union(enum(u32)) {
4 \\ A = 20,
5 \\ B = 40,
6 \\ C = 60,
7 \\ D = 1000,
8 \\};
9 \\
10 );
11}
12
113test "zig fmt: labeled suspend" {
214 try testCanonical(
315 \\fn foo() void {