| ... | @@ -59,6 +59,11 @@ pub const Parser = struct { | ... | @@ -59,6 +59,11 @@ pub const Parser = struct { |
| 59 | lib_name: ?&ast.Node, | 59 | lib_name: ?&ast.Node, |
| 60 | }; | 60 | }; |
| 61 | | 61 | |
| | 62 | const ContainerExternCtx = struct { |
| | 63 | ltoken: Token, |
| | 64 | layout: ast.NodeContainerDecl.Layout, |
| | 65 | }; |
| | 66 | |
| 62 | const DestPtr = union(enum) { | 67 | const DestPtr = union(enum) { |
| 63 | Field: &&ast.Node, | 68 | Field: &&ast.Node, |
| 64 | NullableField: &?&ast.Node, | 69 | NullableField: &?&ast.Node, |
| ... | @@ -90,6 +95,7 @@ pub const Parser = struct { | ... | @@ -90,6 +95,7 @@ pub const Parser = struct { |
| 90 | TopLevel, | 95 | TopLevel, |
| 91 | TopLevelExtern: TopLevelDeclCtx, | 96 | TopLevelExtern: TopLevelDeclCtx, |
| 92 | TopLevelDecl: TopLevelDeclCtx, | 97 | TopLevelDecl: TopLevelDeclCtx, |
| | 98 | ContainerExtern: ContainerExternCtx, |
| 93 | ContainerDecl: &ast.NodeContainerDecl, | 99 | ContainerDecl: &ast.NodeContainerDecl, |
| 94 | Expression: DestPtr, | 100 | Expression: DestPtr, |
| 95 | ExpectOperand, | 101 | ExpectOperand, |
| ... | @@ -338,6 +344,63 @@ pub const Parser = struct { | ... | @@ -338,6 +344,63 @@ pub const Parser = struct { |
| 338 | return self.parseError(token, "expected '=' or ';', found {}", @tagName(token.id)); | 344 | return self.parseError(token, "expected '=' or ';', found {}", @tagName(token.id)); |
| 339 | }, | 345 | }, |
| 340 | | 346 | |
| | 347 | State.ContainerExtern => |ctx| { |
| | 348 | const token = self.getNextToken(); |
| | 349 | |
| | 350 | const node = try arena.create(ast.NodeContainerDecl); |
| | 351 | *node = ast.NodeContainerDecl { |
| | 352 | .base = self.initNode(ast.Node.Id.ContainerDecl), |
| | 353 | .ltoken = ctx.ltoken, |
| | 354 | .layout = ctx.layout, |
| | 355 | .kind = switch (token.id) { |
| | 356 | Token.Id.Keyword_struct => ast.NodeContainerDecl.Kind.Struct, |
| | 357 | Token.Id.Keyword_union => ast.NodeContainerDecl.Kind.Union, |
| | 358 | Token.Id.Keyword_enum => ast.NodeContainerDecl.Kind.Enum, |
| | 359 | else => { |
| | 360 | return self.parseError(token, "expected {}, {} or {}, found {}", |
| | 361 | @tagName(Token.Id.Keyword_struct), |
| | 362 | @tagName(Token.Id.Keyword_union), |
| | 363 | @tagName(Token.Id.Keyword_enum), |
| | 364 | @tagName(token.id)); |
| | 365 | }, |
| | 366 | }, |
| | 367 | .init_arg_expr = undefined, |
| | 368 | .fields_and_decls = ArrayList(&ast.Node).init(arena), |
| | 369 | .rbrace_token = undefined, |
| | 370 | }; |
| | 371 | |
| | 372 | try stack.append(State { .Operand = &node.base }); |
| | 373 | try stack.append(State.AfterOperand); |
| | 374 | try stack.append(State { .ContainerDecl = node }); |
| | 375 | try stack.append(State { .ExpectToken = Token.Id.LBrace }); |
| | 376 | |
| | 377 | const lparen = self.getNextToken(); |
| | 378 | if (lparen.id != Token.Id.LParen) { |
| | 379 | self.putBackToken(lparen); |
| | 380 | node.init_arg_expr = ast.NodeContainerDecl.InitArg.None; |
| | 381 | continue; |
| | 382 | } |
| | 383 | |
| | 384 | try stack.append(State { .ExpectToken = Token.Id.RParen }); |
| | 385 | |
| | 386 | const init_arg_token = self.getNextToken(); |
| | 387 | switch (init_arg_token.id) { |
| | 388 | Token.Id.Keyword_enum => { |
| | 389 | node.init_arg_expr = ast.NodeContainerDecl.InitArg.Enum; |
| | 390 | }, |
| | 391 | else => { |
| | 392 | self.putBackToken(init_arg_token); |
| | 393 | node.init_arg_expr = ast.NodeContainerDecl.InitArg { .Type = undefined }; |
| | 394 | try stack.append(State { |
| | 395 | .Expression = DestPtr { |
| | 396 | .Field = &node.init_arg_expr.Type |
| | 397 | } |
| | 398 | }); |
| | 399 | }, |
| | 400 | } |
| | 401 | continue; |
| | 402 | }, |
| | 403 | |
| 341 | State.ContainerDecl => |container_decl| { | 404 | State.ContainerDecl => |container_decl| { |
| 342 | const token = self.getNextToken(); | 405 | const token = self.getNextToken(); |
| 343 | | 406 | |
| ... | @@ -633,52 +696,30 @@ pub const Parser = struct { | ... | @@ -633,52 +696,30 @@ pub const Parser = struct { |
| 633 | try stack.append(State.AfterOperand); | 696 | try stack.append(State.AfterOperand); |
| 634 | continue; | 697 | continue; |
| 635 | }, | 698 | }, |
| 636 | Token.Id.Keyword_struct, Token.Id.Keyword_union, Token.Id.Keyword_enum => { | 699 | Token.Id.Keyword_packed => { |
| 637 | const node = try arena.create(ast.NodeContainerDecl); | 700 | try stack.append(State { |
| 638 | *node = ast.NodeContainerDecl { | 701 | .ContainerExtern = ContainerExternCtx { |
| 639 | .base = self.initNode(ast.Node.Id.ContainerDecl), | 702 | .ltoken = token, |
| 640 | .kind_token = token, | 703 | .layout = ast.NodeContainerDecl.Layout.Packed, |
| 641 | .kind = switch (token.id) { | | |
| 642 | Token.Id.Keyword_struct => ast.NodeContainerDecl.Kind.Struct, | | |
| 643 | Token.Id.Keyword_union => ast.NodeContainerDecl.Kind.Union, | | |
| 644 | Token.Id.Keyword_enum => ast.NodeContainerDecl.Kind.Enum, | | |
| 645 | else => unreachable, | | |
| 646 | }, | 704 | }, |
| 647 | .init_arg_expr = undefined, | 705 | }); |
| 648 | .fields_and_decls = ArrayList(&ast.Node).init(arena), | 706 | }, |
| 649 | .rbrace_token = undefined, | 707 | Token.Id.Keyword_extern => { |
| 650 | }; | 708 | try stack.append(State { |
| 651 | | 709 | .ContainerExtern = ContainerExternCtx { |
| 652 | try stack.append(State { .Operand = &node.base }); | 710 | .ltoken = token, |
| 653 | try stack.append(State.AfterOperand); | 711 | .layout = ast.NodeContainerDecl.Layout.Extern, |
| 654 | try stack.append(State { .ContainerDecl = node }); | | |
| 655 | try stack.append(State { .ExpectToken = Token.Id.LBrace }); | | |
| 656 | | | |
| 657 | const lparen = self.getNextToken(); | | |
| 658 | if (lparen.id != Token.Id.LParen) { | | |
| 659 | self.putBackToken(lparen); | | |
| 660 | node.init_arg_expr = ast.NodeContainerDecl.InitArg.None; | | |
| 661 | continue; | | |
| 662 | } | | |
| 663 | | | |
| 664 | try stack.append(State { .ExpectToken = Token.Id.RParen }); | | |
| 665 | | | |
| 666 | const init_arg_token = self.getNextToken(); | | |
| 667 | switch (init_arg_token.id) { | | |
| 668 | Token.Id.Keyword_enum => { | | |
| 669 | node.init_arg_expr = ast.NodeContainerDecl.InitArg.Enum; | | |
| 670 | }, | 712 | }, |
| 671 | else => { | 713 | }); |
| 672 | self.putBackToken(lparen); | 714 | }, |
| 673 | node.init_arg_expr = ast.NodeContainerDecl.InitArg { .Type = undefined }; | 715 | Token.Id.Keyword_struct, Token.Id.Keyword_union, Token.Id.Keyword_enum => { |
| 674 | try stack.append(State { | 716 | self.putBackToken(token); |
| 675 | .Expression = DestPtr { | 717 | try stack.append(State { |
| 676 | .Field = &node.init_arg_expr.Type | 718 | .ContainerExtern = ContainerExternCtx { |
| 677 | } | 719 | .ltoken = token, |
| 678 | }); | 720 | .layout = ast.NodeContainerDecl.Layout.Auto, |
| 679 | }, | 721 | }, |
| 680 | } | 722 | }); |
| 681 | continue; | | |
| 682 | }, | 723 | }, |
| 683 | Token.Id.Builtin => { | 724 | Token.Id.Builtin => { |
| 684 | const node = try arena.create(ast.NodeBuiltinCall); | 725 | const node = try arena.create(ast.NodeBuiltinCall); |
| ... | @@ -1706,6 +1747,29 @@ pub const Parser = struct { | ... | @@ -1706,6 +1747,29 @@ pub const Parser = struct { |
| 1706 | try stack.append(RenderState { .Text = " " }); | 1747 | try stack.append(RenderState { .Text = " " }); |
| 1707 | try stack.append(RenderState { .Expression = test_decl.name }); | 1748 | try stack.append(RenderState { .Expression = test_decl.name }); |
| 1708 | }, | 1749 | }, |
| | 1750 | ast.Node.Id.StructField => { |
| | 1751 | const field = @fieldParentPtr(ast.NodeStructField, "base", decl); |
| | 1752 | try stream.print("{}: ", self.tokenizer.getTokenSlice(field.name_token)); |
| | 1753 | try stack.append(RenderState { .Expression = field.type_expr}); |
| | 1754 | }, |
| | 1755 | ast.Node.Id.UnionTag => { |
| | 1756 | const tag = @fieldParentPtr(ast.NodeUnionTag, "base", decl); |
| | 1757 | try stream.print("{}", self.tokenizer.getTokenSlice(tag.name_token)); |
| | 1758 | |
| | 1759 | if (tag.type_expr) |type_expr| { |
| | 1760 | try stream.print(": "); |
| | 1761 | try stack.append(RenderState { .Expression = type_expr}); |
| | 1762 | } |
| | 1763 | }, |
| | 1764 | ast.Node.Id.EnumTag => { |
| | 1765 | const tag = @fieldParentPtr(ast.NodeEnumTag, "base", decl); |
| | 1766 | try stream.print("{}", self.tokenizer.getTokenSlice(tag.name_token)); |
| | 1767 | |
| | 1768 | if (tag.value) |value| { |
| | 1769 | try stream.print(" = "); |
| | 1770 | try stack.append(RenderState { .Expression = value}); |
| | 1771 | } |
| | 1772 | }, |
| 1709 | else => unreachable, | 1773 | else => unreachable, |
| 1710 | } | 1774 | } |
| 1711 | }, | 1775 | }, |
| ... | @@ -1990,27 +2054,30 @@ pub const Parser = struct { | ... | @@ -1990,27 +2054,30 @@ pub const Parser = struct { |
| 1990 | }, | 2054 | }, |
| 1991 | ast.Node.Id.ContainerDecl => { | 2055 | ast.Node.Id.ContainerDecl => { |
| 1992 | const container_decl = @fieldParentPtr(ast.NodeContainerDecl, "base", base); | 2056 | const container_decl = @fieldParentPtr(ast.NodeContainerDecl, "base", base); |
| 1993 | try stream.print("{} {{", self.tokenizer.getTokenSlice(container_decl.kind_token)); | 2057 | |
| | 2058 | switch (container_decl.layout) { |
| | 2059 | ast.NodeContainerDecl.Layout.Packed => try stream.print("packed "), |
| | 2060 | ast.NodeContainerDecl.Layout.Extern => try stream.print("extern "), |
| | 2061 | ast.NodeContainerDecl.Layout.Auto => { }, |
| | 2062 | } |
| | 2063 | |
| | 2064 | switch (container_decl.kind) { |
| | 2065 | ast.NodeContainerDecl.Kind.Struct => try stream.print("struct"), |
| | 2066 | ast.NodeContainerDecl.Kind.Enum => try stream.print("enum"), |
| | 2067 | ast.NodeContainerDecl.Kind.Union => try stream.print("union"), |
| | 2068 | } |
| | 2069 | |
| 1994 | try stack.append(RenderState { .Text = "}"}); | 2070 | try stack.append(RenderState { .Text = "}"}); |
| 1995 | try stack.append(RenderState.PrintIndent); | 2071 | try stack.append(RenderState.PrintIndent); |
| 1996 | try stack.append(RenderState { .Indent = indent }); | 2072 | try stack.append(RenderState { .Indent = indent }); |
| | 2073 | try stack.append(RenderState { .Text = "\n"}); |
| 1997 | | 2074 | |
| 1998 | const fields_and_decls = container_decl.fields_and_decls.toSliceConst(); | 2075 | const fields_and_decls = container_decl.fields_and_decls.toSliceConst(); |
| 1999 | var i = fields_and_decls.len; | 2076 | var i = fields_and_decls.len; |
| 2000 | while (i != 0) { | 2077 | while (i != 0) { |
| 2001 | i -= 1; | 2078 | i -= 1; |
| 2002 | const node = fields_and_decls[i]; | 2079 | const node = fields_and_decls[i]; |
| 2003 | if (i != 0) { | 2080 | try stack.append(RenderState { .TopLevelDecl = node}); |
| 2004 | switch (node.id) { | | |
| 2005 | ast.Node.Id.StructField, | | |
| 2006 | ast.Node.Id.UnionTag, | | |
| 2007 | ast.Node.Id.EnumTag => { | | |
| 2008 | try stack.append(RenderState { .Text = "," }); | | |
| 2009 | }, | | |
| 2010 | else => { } | | |
| 2011 | } | | |
| 2012 | } | | |
| 2013 | try stack.append(RenderState { .Expression = node}); | | |
| 2014 | try stack.append(RenderState.PrintIndent); | 2081 | try stack.append(RenderState.PrintIndent); |
| 2015 | try stack.append(RenderState { | 2082 | try stack.append(RenderState { |
| 2016 | .Text = blk: { | 2083 | .Text = blk: { |
| ... | @@ -2025,22 +2092,43 @@ pub const Parser = struct { | ... | @@ -2025,22 +2092,43 @@ pub const Parser = struct { |
| 2025 | break :blk "\n"; | 2092 | break :blk "\n"; |
| 2026 | }, | 2093 | }, |
| 2027 | }); | 2094 | }); |
| | 2095 | |
| | 2096 | if (i != 0) { |
| | 2097 | const prev_node = fields_and_decls[i - 1]; |
| | 2098 | switch (prev_node.id) { |
| | 2099 | ast.Node.Id.StructField, |
| | 2100 | ast.Node.Id.UnionTag, |
| | 2101 | ast.Node.Id.EnumTag => { |
| | 2102 | try stack.append(RenderState { .Text = "," }); |
| | 2103 | }, |
| | 2104 | else => { } |
| | 2105 | } |
| | 2106 | } |
| 2028 | } | 2107 | } |
| 2029 | try stack.append(RenderState { .Indent = indent + indent_delta}); | 2108 | try stack.append(RenderState { .Indent = indent + indent_delta}); |
| | 2109 | try stack.append(RenderState { .Text = "{"}); |
| | 2110 | |
| | 2111 | switch (container_decl.init_arg_expr) { |
| | 2112 | ast.NodeContainerDecl.InitArg.None => try stack.append(RenderState { .Text = " "}), |
| | 2113 | ast.NodeContainerDecl.InitArg.Enum => try stack.append(RenderState { .Text = "(enum) "}), |
| | 2114 | ast.NodeContainerDecl.InitArg.Type => |type_expr| { |
| | 2115 | try stack.append(RenderState { .Text = ") "}); |
| | 2116 | try stack.append(RenderState { .Expression = type_expr}); |
| | 2117 | try stack.append(RenderState { .Text = "("}); |
| | 2118 | }, |
| | 2119 | } |
| 2030 | }, | 2120 | }, |
| 2031 | ast.Node.Id.MultilineStringLiteral => { | 2121 | ast.Node.Id.MultilineStringLiteral => { |
| 2032 | const multiline_str_literal = @fieldParentPtr(ast.NodeMultilineStringLiteral, "base", base); | 2122 | const multiline_str_literal = @fieldParentPtr(ast.NodeMultilineStringLiteral, "base", base); |
| 2033 | try stream.print("\n"); | 2123 | try stream.print("\n"); |
| 2034 | | 2124 | |
| 2035 | var i : usize = 0; | 2125 | var i : usize = 0; |
| 2036 | indent += 4; | | |
| 2037 | while (i < multiline_str_literal.tokens.len) : (i += 1) { | 2126 | while (i < multiline_str_literal.tokens.len) : (i += 1) { |
| 2038 | const t = multiline_str_literal.tokens.at(i); | 2127 | const t = multiline_str_literal.tokens.at(i); |
| 2039 | try stream.writeByteNTimes(' ', indent); | 2128 | try stream.writeByteNTimes(' ', indent + indent_delta); |
| 2040 | try stream.print("{}", self.tokenizer.getTokenSlice(t)); | 2129 | try stream.print("{}", self.tokenizer.getTokenSlice(t)); |
| 2041 | } | 2130 | } |
| 2042 | try stream.writeByteNTimes(' ', indent); | 2131 | try stream.writeByteNTimes(' ', indent + indent_delta); |
| 2043 | indent -= 4; | | |
| 2044 | }, | 2132 | }, |
| 2045 | ast.Node.Id.UndefinedLiteral => { | 2133 | ast.Node.Id.UndefinedLiteral => { |
| 2046 | const undefined_literal = @fieldParentPtr(ast.NodeUndefinedLiteral, "base", base); | 2134 | const undefined_literal = @fieldParentPtr(ast.NodeUndefinedLiteral, "base", base); |
| ... | @@ -2060,31 +2148,12 @@ pub const Parser = struct { | ... | @@ -2060,31 +2148,12 @@ pub const Parser = struct { |
| 2060 | } | 2148 | } |
| 2061 | } | 2149 | } |
| 2062 | }, | 2150 | }, |
| 2063 | ast.Node.Id.StructField => { | | |
| 2064 | const field = @fieldParentPtr(ast.NodeStructField, "base", base); | | |
| 2065 | try stream.print("{}:", self.tokenizer.getTokenSlice(field.name_token)); | | |
| 2066 | }, | | |
| 2067 | ast.Node.Id.UnionTag => { | | |
| 2068 | const tag = @fieldParentPtr(ast.NodeUnionTag, "base", base); | | |
| 2069 | try stream.print("{}", self.tokenizer.getTokenSlice(tag.name_token)); | | |
| 2070 | | | |
| 2071 | if (tag.type_expr) |type_expr| { | | |
| 2072 | try stream.print(": "); | | |
| 2073 | try stack.append(RenderState { .Expression = type_expr}); | | |
| 2074 | } | | |
| 2075 | }, | | |
| 2076 | ast.Node.Id.EnumTag => { | | |
| 2077 | const tag = @fieldParentPtr(ast.NodeEnumTag, "base", base); | | |
| 2078 | try stream.print("{}", self.tokenizer.getTokenSlice(tag.name_token)); | | |
| 2079 | | | |
| 2080 | if (tag.value) |value| { | | |
| 2081 | try stream.print(" = "); | | |
| 2082 | try stack.append(RenderState { .Expression = value}); | | |
| 2083 | } | | |
| 2084 | }, | | |
| 2085 | ast.Node.Id.FnProto => @panic("TODO fn proto in an expression"), | 2151 | ast.Node.Id.FnProto => @panic("TODO fn proto in an expression"), |
| 2086 | ast.Node.Id.LineComment => @panic("TODO render line comment in an expression"), | 2152 | ast.Node.Id.LineComment => @panic("TODO render line comment in an expression"), |
| 2087 | | 2153 | |
| | 2154 | ast.Node.Id.StructField, |
| | 2155 | ast.Node.Id.UnionTag, |
| | 2156 | ast.Node.Id.EnumTag, |
| 2088 | ast.Node.Id.Root, | 2157 | ast.Node.Id.Root, |
| 2089 | ast.Node.Id.VarDecl, | 2158 | ast.Node.Id.VarDecl, |
| 2090 | ast.Node.Id.TestDecl, | 2159 | ast.Node.Id.TestDecl, |
| ... | @@ -2489,21 +2558,21 @@ test "zig fmt: struct declaration" { | ... | @@ -2489,21 +2558,21 @@ test "zig fmt: struct declaration" { |
| 2489 | \\ return *self; | 2558 | \\ return *self; |
| 2490 | \\ } | 2559 | \\ } |
| 2491 | \\ | 2560 | \\ |
| 2492 | \\ f2: u8, | 2561 | \\ f2: u8 |
| 2493 | \\}; | 2562 | \\}; |
| 2494 | \\ | 2563 | \\ |
| 2495 | \\const Ps = packed struct { | 2564 | \\const Ps = packed struct { |
| 2496 | \\ a: u8, | 2565 | \\ a: u8, |
| 2497 | \\ b: u8, | 2566 | \\ b: u8, |
| 2498 | \\ | 2567 | \\ |
| 2499 | \\ c: u8, | 2568 | \\ c: u8 |
| 2500 | \\}; | 2569 | \\}; |
| 2501 | \\ | 2570 | \\ |
| 2502 | \\const Es = extern struct { | 2571 | \\const Es = extern struct { |
| 2503 | \\ a: u8, | 2572 | \\ a: u8, |
| 2504 | \\ b: u8, | 2573 | \\ b: u8, |
| 2505 | \\ | 2574 | \\ |
| 2506 | \\ c: u8, | 2575 | \\ c: u8 |
| 2507 | \\}; | 2576 | \\}; |
| 2508 | \\ | 2577 | \\ |
| 2509 | ); | 2578 | ); |
| ... | @@ -2513,25 +2582,25 @@ test "zig fmt: enum declaration" { | ... | @@ -2513,25 +2582,25 @@ test "zig fmt: enum declaration" { |
| 2513 | try testCanonical( | 2582 | try testCanonical( |
| 2514 | \\const E = enum { | 2583 | \\const E = enum { |
| 2515 | \\ Ok, | 2584 | \\ Ok, |
| 2516 | \\ SomethingElse = 0, | 2585 | \\ SomethingElse = 0 |
| 2517 | \\}; | 2586 | \\}; |
| 2518 | \\ | 2587 | \\ |
| 2519 | \\const E2 = enum(u8) { | 2588 | \\const E2 = enum(u8) { |
| 2520 | \\ Ok, | 2589 | \\ Ok, |
| 2521 | \\ SomethingElse = 255, | 2590 | \\ SomethingElse = 255, |
| 2522 | \\ SomethingThird, | 2591 | \\ SomethingThird |
| 2523 | \\}; | 2592 | \\}; |
| 2524 | \\ | 2593 | \\ |
| 2525 | \\const Ee = extern enum { | 2594 | \\const Ee = extern enum { |
| 2526 | \\ Ok, | 2595 | \\ Ok, |
| 2527 | \\ SomethingElse, | 2596 | \\ SomethingElse, |
| 2528 | \\ SomethingThird, | 2597 | \\ SomethingThird |
| 2529 | \\}; | 2598 | \\}; |
| 2530 | \\ | 2599 | \\ |
| 2531 | \\const Ep = packed enum { | 2600 | \\const Ep = packed enum { |
| 2532 | \\ Ok, | 2601 | \\ Ok, |
| 2533 | \\ SomethingElse, | 2602 | \\ SomethingElse, |
| 2534 | \\ SomethingThird, | 2603 | \\ SomethingThird |
| 2535 | \\}; | 2604 | \\}; |
| 2536 | \\ | 2605 | \\ |
| 2537 | ); | 2606 | ); |
| ... | @@ -2542,31 +2611,36 @@ test "zig fmt: union declaration" { | ... | @@ -2542,31 +2611,36 @@ test "zig fmt: union declaration" { |
| 2542 | \\const U = union { | 2611 | \\const U = union { |
| 2543 | \\ Int: u8, | 2612 | \\ Int: u8, |
| 2544 | \\ Float: f32, | 2613 | \\ Float: f32, |
| 2545 | \\ Bool: bool, | 2614 | \\ None, |
| | 2615 | \\ Bool: bool |
| 2546 | \\}; | 2616 | \\}; |
| 2547 | \\ | 2617 | \\ |
| 2548 | \\const Ue = union(enum) { | 2618 | \\const Ue = union(enum) { |
| 2549 | \\ Int: u8, | 2619 | \\ Int: u8, |
| 2550 | \\ Float: f32, | 2620 | \\ Float: f32, |
| 2551 | \\ Bool: bool, | 2621 | \\ None, |
| | 2622 | \\ Bool: bool |
| 2552 | \\}; | 2623 | \\}; |
| 2553 | \\ | 2624 | \\ |
| 2554 | \\const E = enum { | 2625 | \\const E = enum { |
| 2555 | \\ Int, | 2626 | \\ Int, |
| 2556 | \\ Float, | 2627 | \\ Float, |
| 2557 | \\ Bool, | 2628 | \\ None, |
| | 2629 | \\ Bool |
| 2558 | \\}; | 2630 | \\}; |
| 2559 | \\ | 2631 | \\ |
| 2560 | \\const Ue2 = union(E) { | 2632 | \\const Ue2 = union(E) { |
| 2561 | \\ Int: u8, | 2633 | \\ Int: u8, |
| 2562 | \\ Float: f32, | 2634 | \\ Float: f32, |
| 2563 | \\ Bool: bool, | 2635 | \\ None, |
| | 2636 | \\ Bool: bool |
| 2564 | \\}; | 2637 | \\}; |
| 2565 | \\ | 2638 | \\ |
| 2566 | \\const Eu = extern union { | 2639 | \\const Eu = extern union { |
| 2567 | \\ Int: u8, | 2640 | \\ Int: u8, |
| 2568 | \\ Float: f32, | 2641 | \\ Float: f32, |
| 2569 | \\ Bool: bool, | 2642 | \\ None, |
| | 2643 | \\ Bool: bool |
| 2570 | \\}; | 2644 | \\}; |
| 2571 | \\ | 2645 | \\ |
| 2572 | ); | 2646 | ); |