authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-07-15 18:15:59-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-07-15 18:15:59-07:00
logf11909227312882f29dbfc484dc79ab622792787
tree3f327f4d16c32034cb1eea79dfaeadfef6303d9b
parente70d6d19f5a937504ce0e2f79d03a6275b6ff357

stage2: breaking AST memory layout modifications

ast.Node.Id => ast.Node.Tag, matching recent style conventions. Now multiple different AST node tags can map to the same AST node data structures. In this commit, simple prefix operators now all map top SimplePrefixOp. `ast.Node.castTag` is now preferred over `ast.Node.cast`. Upcoming: InfixOp flattened out.

6 files changed, 450 insertions(+), 316 deletions(-)

lib/std/zig/ast.zig+191-122
...@@ -323,8 +323,8 @@ pub const Error = union(enum) {...@@ -323,8 +323,8 @@ pub const Error = union(enum) {
323 node: *Node,323 node: *Node,
324324
325 pub fn render(self: *const ExpectedCall, tokens: []const Token.Id, stream: anytype) !void {325 pub fn render(self: *const ExpectedCall, tokens: []const Token.Id, stream: anytype) !void {
326 return stream.print("expected " ++ @tagName(Node.Id.Call) ++ ", found {}", .{326 return stream.print("expected " ++ @tagName(Node.Tag.Call) ++ ", found {}", .{
327 @tagName(self.node.id),327 @tagName(self.node.tag),
328 });328 });
329 }329 }
330 };330 };
...@@ -333,8 +333,8 @@ pub const Error = union(enum) {...@@ -333,8 +333,8 @@ pub const Error = union(enum) {
333 node: *Node,333 node: *Node,
334334
335 pub fn render(self: *const ExpectedCallOrFnProto, tokens: []const Token.Id, stream: anytype) !void {335 pub fn render(self: *const ExpectedCallOrFnProto, tokens: []const Token.Id, stream: anytype) !void {
336 return stream.print("expected " ++ @tagName(Node.Id.Call) ++ " or " ++336 return stream.print("expected " ++ @tagName(Node.Tag.Call) ++ " or " ++
337 @tagName(Node.Id.FnProto) ++ ", found {}", .{@tagName(self.node.id)});337 @tagName(Node.Tag.FnProto) ++ ", found {}", .{@tagName(self.node.tag)});
338 }338 }
339 };339 };
340340
...@@ -396,9 +396,9 @@ pub const Error = union(enum) {...@@ -396,9 +396,9 @@ pub const Error = union(enum) {
396};396};
397397
398pub const Node = struct {398pub const Node = struct {
399 id: Id,399 tag: Tag,
400400
401 pub const Id = enum {401 pub const Tag = enum {
402 // Top level402 // Top level
403 Root,403 Root,
404 Use,404 Use,
...@@ -484,49 +484,129 @@ pub const Node = struct {...@@ -484,49 +484,129 @@ pub const Node = struct {
484 ContainerField,484 ContainerField,
485 ErrorTag,485 ErrorTag,
486 FieldInitializer,486 FieldInitializer,
487
488 pub fn Type(tag: Tag) type {
489 return switch (tag) {
490 .Root => Root,
491 .Use => Use,
492 .TestDecl => TestDecl,
493 .VarDecl => VarDecl,
494 .Defer => Defer,
495 .InfixOp => InfixOp,
496
497 .AddressOf,
498 .Await,
499 .BitNot,
500 .BoolNot,
501 .OptionalType,
502 .Negation,
503 .NegationWrap,
504 .Resume,
505 .Try,
506 => SimplePrefixOp,
507
508 .ArrayType => ArrayType,
509 .ArrayTypeSentinel => ArrayTypeSentinel,
510 .PtrType => PtrType,
511 .SliceType => SliceType,
512 .SuffixOp => SuffixOp,
513 .ArrayInitializer => ArrayInitializer,
514 .ArrayInitializerDot => ArrayInitializerDot,
515 .StructInitializer => StructInitializer,
516 .StructInitializerDot => StructInitializerDot,
517 .Call => Call,
518 .Switch => Switch,
519 .While => While,
520 .For => For,
521 .If => If,
522 .ControlFlowExpression => ControlFlowExpression,
523 .Suspend => Suspend,
524 .AnyType => AnyType,
525 .ErrorType => ErrorType,
526 .FnProto => FnProto,
527 .AnyFrameType => AnyFrameType,
528 .IntegerLiteral => IntegerLiteral,
529 .FloatLiteral => FloatLiteral,
530 .EnumLiteral => EnumLiteral,
531 .StringLiteral => StringLiteral,
532 .MultilineStringLiteral => MultilineStringLiteral,
533 .CharLiteral => CharLiteral,
534 .BoolLiteral => BoolLiteral,
535 .NullLiteral => NullLiteral,
536 .UndefinedLiteral => UndefinedLiteral,
537 .Unreachable => Unreachable,
538 .Identifier => Identifier,
539 .GroupedExpression => GroupedExpression,
540 .BuiltinCall => BuiltinCall,
541 .ErrorSetDecl => ErrorSetDecl,
542 .ContainerDecl => ContainerDecl,
543 .Asm => Asm,
544 .Comptime => Comptime,
545 .Nosuspend => Nosuspend,
546 .Block => Block,
547 .DocComment => DocComment,
548 .SwitchCase => SwitchCase,
549 .SwitchElse => SwitchElse,
550 .Else => Else,
551 .Payload => Payload,
552 .PointerPayload => PointerPayload,
553 .PointerIndexPayload => PointerIndexPayload,
554 .ContainerField => ContainerField,
555 .ErrorTag => ErrorTag,
556 .FieldInitializer => FieldInitializer,
557 };
558 }
487 };559 };
488560
561 /// Prefer `castTag` to this.
489 pub fn cast(base: *Node, comptime T: type) ?*T {562 pub fn cast(base: *Node, comptime T: type) ?*T {
490 if (base.id == comptime typeToId(T)) {563 if (std.meta.fieldInfo(T, "base").default_value) |default_base| {
491 return @fieldParentPtr(T, "base", base);564 return base.castTag(default_base.tag);
565 }
566 inline for (@typeInfo(Tag).Enum.fields) |field| {
567 const tag = @intToEnum(Tag, field.value);
568 if (base.tag == tag) {
569 if (T == tag.Type()) {
570 return @fieldParentPtr(T, "base", base);
571 }
572 return null;
573 }
574 }
575 unreachable;
576 }
577
578 pub fn castTag(base: *Node, comptime tag: Tag) ?*tag.Type() {
579 if (base.tag == tag) {
580 return @fieldParentPtr(tag.Type(), "base", base);
492 }581 }
493 return null;582 return null;
494 }583 }
495584
496 pub fn iterate(base: *Node, index: usize) ?*Node {585 pub fn iterate(base: *Node, index: usize) ?*Node {
497 inline for (@typeInfo(Id).Enum.fields) |f| {586 inline for (@typeInfo(Tag).Enum.fields) |field| {
498 if (base.id == @field(Id, f.name)) {587 const tag = @intToEnum(Tag, field.value);
499 const T = @field(Node, f.name);588 if (base.tag == tag) {
500 return @fieldParentPtr(T, "base", base).iterate(index);589 return @fieldParentPtr(tag.Type(), "base", base).iterate(index);
501 }590 }
502 }591 }
503 unreachable;592 unreachable;
504 }593 }
505594
506 pub fn firstToken(base: *const Node) TokenIndex {595 pub fn firstToken(base: *const Node) TokenIndex {
507 inline for (@typeInfo(Id).Enum.fields) |f| {596 inline for (@typeInfo(Tag).Enum.fields) |field| {
508 if (base.id == @field(Id, f.name)) {597 const tag = @intToEnum(Tag, field.value);
509 const T = @field(Node, f.name);598 if (base.tag == tag) {
510 return @fieldParentPtr(T, "base", base).firstToken();599 return @fieldParentPtr(tag.Type(), "base", base).firstToken();
511 }600 }
512 }601 }
513 unreachable;602 unreachable;
514 }603 }
515604
516 pub fn lastToken(base: *const Node) TokenIndex {605 pub fn lastToken(base: *const Node) TokenIndex {
517 inline for (@typeInfo(Id).Enum.fields) |f| {606 inline for (@typeInfo(Tag).Enum.fields) |field| {
518 if (base.id == @field(Id, f.name)) {607 const tag = @intToEnum(Tag, field.value);
519 const T = @field(Node, f.name);608 if (base.tag == tag) {
520 return @fieldParentPtr(T, "base", base).lastToken();609 return @fieldParentPtr(tag.Type(), "base", base).lastToken();
521 }
522 }
523 unreachable;
524 }
525
526 pub fn typeToId(comptime T: type) Id {
527 inline for (@typeInfo(Id).Enum.fields) |f| {
528 if (T == @field(Node, f.name)) {
529 return @field(Id, f.name);
530 }610 }
531 }611 }
532 unreachable;612 unreachable;
...@@ -535,7 +615,7 @@ pub const Node = struct {...@@ -535,7 +615,7 @@ pub const Node = struct {
535 pub fn requireSemiColon(base: *const Node) bool {615 pub fn requireSemiColon(base: *const Node) bool {
536 var n = base;616 var n = base;
537 while (true) {617 while (true) {
538 switch (n.id) {618 switch (n.tag) {
539 .Root,619 .Root,
540 .ContainerField,620 .ContainerField,
541 .Block,621 .Block,
...@@ -556,7 +636,7 @@ pub const Node = struct {...@@ -556,7 +636,7 @@ pub const Node = struct {
556 continue;636 continue;
557 }637 }
558638
559 return while_node.body.id != .Block;639 return while_node.body.tag != .Block;
560 },640 },
561 .For => {641 .For => {
562 const for_node = @fieldParentPtr(For, "base", n);642 const for_node = @fieldParentPtr(For, "base", n);
...@@ -565,7 +645,7 @@ pub const Node = struct {...@@ -565,7 +645,7 @@ pub const Node = struct {
565 continue;645 continue;
566 }646 }
567647
568 return for_node.body.id != .Block;648 return for_node.body.tag != .Block;
569 },649 },
570 .If => {650 .If => {
571 const if_node = @fieldParentPtr(If, "base", n);651 const if_node = @fieldParentPtr(If, "base", n);
...@@ -574,7 +654,7 @@ pub const Node = struct {...@@ -574,7 +654,7 @@ pub const Node = struct {
574 continue;654 continue;
575 }655 }
576656
577 return if_node.body.id != .Block;657 return if_node.body.tag != .Block;
578 },658 },
579 .Else => {659 .Else => {
580 const else_node = @fieldParentPtr(Else, "base", n);660 const else_node = @fieldParentPtr(Else, "base", n);
...@@ -583,23 +663,23 @@ pub const Node = struct {...@@ -583,23 +663,23 @@ pub const Node = struct {
583 },663 },
584 .Defer => {664 .Defer => {
585 const defer_node = @fieldParentPtr(Defer, "base", n);665 const defer_node = @fieldParentPtr(Defer, "base", n);
586 return defer_node.expr.id != .Block;666 return defer_node.expr.tag != .Block;
587 },667 },
588 .Comptime => {668 .Comptime => {
589 const comptime_node = @fieldParentPtr(Comptime, "base", n);669 const comptime_node = @fieldParentPtr(Comptime, "base", n);
590 return comptime_node.expr.id != .Block;670 return comptime_node.expr.tag != .Block;
591 },671 },
592 .Suspend => {672 .Suspend => {
593 const suspend_node = @fieldParentPtr(Suspend, "base", n);673 const suspend_node = @fieldParentPtr(Suspend, "base", n);
594 if (suspend_node.body) |body| {674 if (suspend_node.body) |body| {
595 return body.id != .Block;675 return body.tag != .Block;
596 }676 }
597677
598 return true;678 return true;
599 },679 },
600 .Nosuspend => {680 .Nosuspend => {
601 const nosuspend_node = @fieldParentPtr(Nosuspend, "base", n);681 const nosuspend_node = @fieldParentPtr(Nosuspend, "base", n);
602 return nosuspend_node.expr.id != .Block;682 return nosuspend_node.expr.tag != .Block;
603 },683 },
604 else => return true,684 else => return true,
605 }685 }
...@@ -613,7 +693,7 @@ pub const Node = struct {...@@ -613,7 +693,7 @@ pub const Node = struct {
613 std.debug.warn(" ", .{});693 std.debug.warn(" ", .{});
614 }694 }
615 }695 }
616 std.debug.warn("{}\n", .{@tagName(self.id)});696 std.debug.warn("{}\n", .{@tagName(self.tag)});
617697
618 var child_i: usize = 0;698 var child_i: usize = 0;
619 while (self.iterate(child_i)) |child| : (child_i += 1) {699 while (self.iterate(child_i)) |child| : (child_i += 1) {
...@@ -623,7 +703,7 @@ pub const Node = struct {...@@ -623,7 +703,7 @@ pub const Node = struct {
623703
624 /// The decls data follows this struct in memory as an array of Node pointers.704 /// The decls data follows this struct in memory as an array of Node pointers.
625 pub const Root = struct {705 pub const Root = struct {
626 base: Node = Node{ .id = .Root },706 base: Node = Node{ .tag = .Root },
627 eof_token: TokenIndex,707 eof_token: TokenIndex,
628 decls_len: NodeIndex,708 decls_len: NodeIndex,
629709
...@@ -678,7 +758,7 @@ pub const Node = struct {...@@ -678,7 +758,7 @@ pub const Node = struct {
678 /// Trailed in memory by possibly many things, with each optional thing758 /// Trailed in memory by possibly many things, with each optional thing
679 /// determined by a bit in `trailer_flags`.759 /// determined by a bit in `trailer_flags`.
680 pub const VarDecl = struct {760 pub const VarDecl = struct {
681 base: Node = Node{ .id = .VarDecl },761 base: Node = Node{ .tag = .VarDecl },
682 trailer_flags: TrailerFlags,762 trailer_flags: TrailerFlags,
683 mut_token: TokenIndex,763 mut_token: TokenIndex,
684 name_token: TokenIndex,764 name_token: TokenIndex,
...@@ -779,7 +859,7 @@ pub const Node = struct {...@@ -779,7 +859,7 @@ pub const Node = struct {
779 };859 };
780860
781 pub const Use = struct {861 pub const Use = struct {
782 base: Node = Node{ .id = .Use },862 base: Node = Node{ .tag = .Use },
783 doc_comments: ?*DocComment,863 doc_comments: ?*DocComment,
784 visib_token: ?TokenIndex,864 visib_token: ?TokenIndex,
785 use_token: TokenIndex,865 use_token: TokenIndex,
...@@ -806,7 +886,7 @@ pub const Node = struct {...@@ -806,7 +886,7 @@ pub const Node = struct {
806 };886 };
807887
808 pub const ErrorSetDecl = struct {888 pub const ErrorSetDecl = struct {
809 base: Node = Node{ .id = .ErrorSetDecl },889 base: Node = Node{ .tag = .ErrorSetDecl },
810 error_token: TokenIndex,890 error_token: TokenIndex,
811 rbrace_token: TokenIndex,891 rbrace_token: TokenIndex,
812 decls_len: NodeIndex,892 decls_len: NodeIndex,
...@@ -856,7 +936,7 @@ pub const Node = struct {...@@ -856,7 +936,7 @@ pub const Node = struct {
856936
857 /// The fields and decls Node pointers directly follow this struct in memory.937 /// The fields and decls Node pointers directly follow this struct in memory.
858 pub const ContainerDecl = struct {938 pub const ContainerDecl = struct {
859 base: Node = Node{ .id = .ContainerDecl },939 base: Node = Node{ .tag = .ContainerDecl },
860 kind_token: TokenIndex,940 kind_token: TokenIndex,
861 layout_token: ?TokenIndex,941 layout_token: ?TokenIndex,
862 lbrace_token: TokenIndex,942 lbrace_token: TokenIndex,
...@@ -925,7 +1005,7 @@ pub const Node = struct {...@@ -925,7 +1005,7 @@ pub const Node = struct {
925 };1005 };
9261006
927 pub const ContainerField = struct {1007 pub const ContainerField = struct {
928 base: Node = Node{ .id = .ContainerField },1008 base: Node = Node{ .tag = .ContainerField },
929 doc_comments: ?*DocComment,1009 doc_comments: ?*DocComment,
930 comptime_token: ?TokenIndex,1010 comptime_token: ?TokenIndex,
931 name_token: TokenIndex,1011 name_token: TokenIndex,
...@@ -976,7 +1056,7 @@ pub const Node = struct {...@@ -976,7 +1056,7 @@ pub const Node = struct {
976 };1056 };
9771057
978 pub const ErrorTag = struct {1058 pub const ErrorTag = struct {
979 base: Node = Node{ .id = .ErrorTag },1059 base: Node = Node{ .tag = .ErrorTag },
980 doc_comments: ?*DocComment,1060 doc_comments: ?*DocComment,
981 name_token: TokenIndex,1061 name_token: TokenIndex,
9821062
...@@ -1001,7 +1081,7 @@ pub const Node = struct {...@@ -1001,7 +1081,7 @@ pub const Node = struct {
1001 };1081 };
10021082
1003 pub const Identifier = struct {1083 pub const Identifier = struct {
1004 base: Node = Node{ .id = .Identifier },1084 base: Node = Node{ .tag = .Identifier },
1005 token: TokenIndex,1085 token: TokenIndex,
10061086
1007 pub fn iterate(self: *const Identifier, index: usize) ?*Node {1087 pub fn iterate(self: *const Identifier, index: usize) ?*Node {
...@@ -1020,7 +1100,7 @@ pub const Node = struct {...@@ -1020,7 +1100,7 @@ pub const Node = struct {
1020 /// The params are directly after the FnProto in memory.1100 /// The params are directly after the FnProto in memory.
1021 /// Next, each optional thing determined by a bit in `trailer_flags`.1101 /// Next, each optional thing determined by a bit in `trailer_flags`.
1022 pub const FnProto = struct {1102 pub const FnProto = struct {
1023 base: Node = Node{ .id = .FnProto },1103 base: Node = Node{ .tag = .FnProto },
1024 trailer_flags: TrailerFlags,1104 trailer_flags: TrailerFlags,
1025 fn_token: TokenIndex,1105 fn_token: TokenIndex,
1026 params_len: NodeIndex,1106 params_len: NodeIndex,
...@@ -1230,7 +1310,7 @@ pub const Node = struct {...@@ -1230,7 +1310,7 @@ pub const Node = struct {
1230 };1310 };
12311311
1232 pub const AnyFrameType = struct {1312 pub const AnyFrameType = struct {
1233 base: Node = Node{ .id = .AnyFrameType },1313 base: Node = Node{ .tag = .AnyFrameType },
1234 anyframe_token: TokenIndex,1314 anyframe_token: TokenIndex,
1235 result: ?Result,1315 result: ?Result,
12361316
...@@ -1262,7 +1342,7 @@ pub const Node = struct {...@@ -1262,7 +1342,7 @@ pub const Node = struct {
12621342
1263 /// The statements of the block follow Block directly in memory.1343 /// The statements of the block follow Block directly in memory.
1264 pub const Block = struct {1344 pub const Block = struct {
1265 base: Node = Node{ .id = .Block },1345 base: Node = Node{ .tag = .Block },
1266 statements_len: NodeIndex,1346 statements_len: NodeIndex,
1267 lbrace: TokenIndex,1347 lbrace: TokenIndex,
1268 rbrace: TokenIndex,1348 rbrace: TokenIndex,
...@@ -1316,7 +1396,7 @@ pub const Node = struct {...@@ -1316,7 +1396,7 @@ pub const Node = struct {
1316 };1396 };
13171397
1318 pub const Defer = struct {1398 pub const Defer = struct {
1319 base: Node = Node{ .id = .Defer },1399 base: Node = Node{ .tag = .Defer },
1320 defer_token: TokenIndex,1400 defer_token: TokenIndex,
1321 payload: ?*Node,1401 payload: ?*Node,
1322 expr: *Node,1402 expr: *Node,
...@@ -1340,7 +1420,7 @@ pub const Node = struct {...@@ -1340,7 +1420,7 @@ pub const Node = struct {
1340 };1420 };
13411421
1342 pub const Comptime = struct {1422 pub const Comptime = struct {
1343 base: Node = Node{ .id = .Comptime },1423 base: Node = Node{ .tag = .Comptime },
1344 doc_comments: ?*DocComment,1424 doc_comments: ?*DocComment,
1345 comptime_token: TokenIndex,1425 comptime_token: TokenIndex,
1346 expr: *Node,1426 expr: *Node,
...@@ -1364,7 +1444,7 @@ pub const Node = struct {...@@ -1364,7 +1444,7 @@ pub const Node = struct {
1364 };1444 };
13651445
1366 pub const Nosuspend = struct {1446 pub const Nosuspend = struct {
1367 base: Node = Node{ .id = .Nosuspend },1447 base: Node = Node{ .tag = .Nosuspend },
1368 nosuspend_token: TokenIndex,1448 nosuspend_token: TokenIndex,
1369 expr: *Node,1449 expr: *Node,
13701450
...@@ -1387,7 +1467,7 @@ pub const Node = struct {...@@ -1387,7 +1467,7 @@ pub const Node = struct {
1387 };1467 };
13881468
1389 pub const Payload = struct {1469 pub const Payload = struct {
1390 base: Node = Node{ .id = .Payload },1470 base: Node = Node{ .tag = .Payload },
1391 lpipe: TokenIndex,1471 lpipe: TokenIndex,
1392 error_symbol: *Node,1472 error_symbol: *Node,
1393 rpipe: TokenIndex,1473 rpipe: TokenIndex,
...@@ -1411,7 +1491,7 @@ pub const Node = struct {...@@ -1411,7 +1491,7 @@ pub const Node = struct {
1411 };1491 };
14121492
1413 pub const PointerPayload = struct {1493 pub const PointerPayload = struct {
1414 base: Node = Node{ .id = .PointerPayload },1494 base: Node = Node{ .tag = .PointerPayload },
1415 lpipe: TokenIndex,1495 lpipe: TokenIndex,
1416 ptr_token: ?TokenIndex,1496 ptr_token: ?TokenIndex,
1417 value_symbol: *Node,1497 value_symbol: *Node,
...@@ -1436,7 +1516,7 @@ pub const Node = struct {...@@ -1436,7 +1516,7 @@ pub const Node = struct {
1436 };1516 };
14371517
1438 pub const PointerIndexPayload = struct {1518 pub const PointerIndexPayload = struct {
1439 base: Node = Node{ .id = .PointerIndexPayload },1519 base: Node = Node{ .tag = .PointerIndexPayload },
1440 lpipe: TokenIndex,1520 lpipe: TokenIndex,
1441 ptr_token: ?TokenIndex,1521 ptr_token: ?TokenIndex,
1442 value_symbol: *Node,1522 value_symbol: *Node,
...@@ -1467,7 +1547,7 @@ pub const Node = struct {...@@ -1467,7 +1547,7 @@ pub const Node = struct {
1467 };1547 };
14681548
1469 pub const Else = struct {1549 pub const Else = struct {
1470 base: Node = Node{ .id = .Else },1550 base: Node = Node{ .tag = .Else },
1471 else_token: TokenIndex,1551 else_token: TokenIndex,
1472 payload: ?*Node,1552 payload: ?*Node,
1473 body: *Node,1553 body: *Node,
...@@ -1498,7 +1578,7 @@ pub const Node = struct {...@@ -1498,7 +1578,7 @@ pub const Node = struct {
1498 /// The cases node pointers are found in memory after Switch.1578 /// The cases node pointers are found in memory after Switch.
1499 /// They must be SwitchCase or SwitchElse nodes.1579 /// They must be SwitchCase or SwitchElse nodes.
1500 pub const Switch = struct {1580 pub const Switch = struct {
1501 base: Node = Node{ .id = .Switch },1581 base: Node = Node{ .tag = .Switch },
1502 switch_token: TokenIndex,1582 switch_token: TokenIndex,
1503 rbrace: TokenIndex,1583 rbrace: TokenIndex,
1504 cases_len: NodeIndex,1584 cases_len: NodeIndex,
...@@ -1552,7 +1632,7 @@ pub const Node = struct {...@@ -1552,7 +1632,7 @@ pub const Node = struct {
15521632
1553 /// Items sub-nodes appear in memory directly following SwitchCase.1633 /// Items sub-nodes appear in memory directly following SwitchCase.
1554 pub const SwitchCase = struct {1634 pub const SwitchCase = struct {
1555 base: Node = Node{ .id = .SwitchCase },1635 base: Node = Node{ .tag = .SwitchCase },
1556 arrow_token: TokenIndex,1636 arrow_token: TokenIndex,
1557 payload: ?*Node,1637 payload: ?*Node,
1558 expr: *Node,1638 expr: *Node,
...@@ -1610,7 +1690,7 @@ pub const Node = struct {...@@ -1610,7 +1690,7 @@ pub const Node = struct {
1610 };1690 };
16111691
1612 pub const SwitchElse = struct {1692 pub const SwitchElse = struct {
1613 base: Node = Node{ .id = .SwitchElse },1693 base: Node = Node{ .tag = .SwitchElse },
1614 token: TokenIndex,1694 token: TokenIndex,
16151695
1616 pub fn iterate(self: *const SwitchElse, index: usize) ?*Node {1696 pub fn iterate(self: *const SwitchElse, index: usize) ?*Node {
...@@ -1627,7 +1707,7 @@ pub const Node = struct {...@@ -1627,7 +1707,7 @@ pub const Node = struct {
1627 };1707 };
16281708
1629 pub const While = struct {1709 pub const While = struct {
1630 base: Node = Node{ .id = .While },1710 base: Node = Node{ .tag = .While },
1631 label: ?TokenIndex,1711 label: ?TokenIndex,
1632 inline_token: ?TokenIndex,1712 inline_token: ?TokenIndex,
1633 while_token: TokenIndex,1713 while_token: TokenIndex,
...@@ -1686,7 +1766,7 @@ pub const Node = struct {...@@ -1686,7 +1766,7 @@ pub const Node = struct {
1686 };1766 };
16871767
1688 pub const For = struct {1768 pub const For = struct {
1689 base: Node = Node{ .id = .For },1769 base: Node = Node{ .tag = .For },
1690 label: ?TokenIndex,1770 label: ?TokenIndex,
1691 inline_token: ?TokenIndex,1771 inline_token: ?TokenIndex,
1692 for_token: TokenIndex,1772 for_token: TokenIndex,
...@@ -1737,7 +1817,7 @@ pub const Node = struct {...@@ -1737,7 +1817,7 @@ pub const Node = struct {
1737 };1817 };
17381818
1739 pub const If = struct {1819 pub const If = struct {
1740 base: Node = Node{ .id = .If },1820 base: Node = Node{ .tag = .If },
1741 if_token: TokenIndex,1821 if_token: TokenIndex,
1742 condition: *Node,1822 condition: *Node,
1743 payload: ?*Node,1823 payload: ?*Node,
...@@ -1779,8 +1859,9 @@ pub const Node = struct {...@@ -1779,8 +1859,9 @@ pub const Node = struct {
1779 }1859 }
1780 };1860 };
17811861
1862 /// TODO split up and make every op its own AST Node tag
1782 pub const InfixOp = struct {1863 pub const InfixOp = struct {
1783 base: Node = Node{ .id = .InfixOp },1864 base: Node = Node{ .tag = .InfixOp },
1784 op_token: TokenIndex,1865 op_token: TokenIndex,
1785 lhs: *Node,1866 lhs: *Node,
1786 op: Op,1867 op: Op,
...@@ -1906,41 +1987,29 @@ pub const Node = struct {...@@ -1906,41 +1987,29 @@ pub const Node = struct {
1906 }1987 }
1907 };1988 };
19081989
1909 pub const AddressOf = SimplePrefixOp(.AddressOf);1990 pub const SimplePrefixOp = struct {
1910 pub const Await = SimplePrefixOp(.Await);1991 base: Node,
1911 pub const BitNot = SimplePrefixOp(.BitNot);1992 op_token: TokenIndex,
1912 pub const BoolNot = SimplePrefixOp(.BoolNot);1993 rhs: *Node,
1913 pub const OptionalType = SimplePrefixOp(.OptionalType);
1914 pub const Negation = SimplePrefixOp(.Negation);
1915 pub const NegationWrap = SimplePrefixOp(.NegationWrap);
1916 pub const Resume = SimplePrefixOp(.Resume);
1917 pub const Try = SimplePrefixOp(.Try);
1918
1919 pub fn SimplePrefixOp(comptime tag: Id) type {
1920 return struct {
1921 base: Node = Node{ .id = tag },
1922 op_token: TokenIndex,
1923 rhs: *Node,
19241994
1925 const Self = @This();1995 const Self = @This();
19261996
1927 pub fn iterate(self: *const Self, index: usize) ?*Node {1997 pub fn iterate(self: *const Self, index: usize) ?*Node {
1928 if (index == 0) return self.rhs;1998 if (index == 0) return self.rhs;
1929 return null;1999 return null;
1930 }2000 }
19312001
1932 pub fn firstToken(self: *const Self) TokenIndex {2002 pub fn firstToken(self: *const Self) TokenIndex {
1933 return self.op_token;2003 return self.op_token;
1934 }2004 }
19352005
1936 pub fn lastToken(self: *const Self) TokenIndex {2006 pub fn lastToken(self: *const Self) TokenIndex {
1937 return self.rhs.lastToken();2007 return self.rhs.lastToken();
1938 }2008 }
1939 };2009 };
1940 }
19412010
1942 pub const ArrayType = struct {2011 pub const ArrayType = struct {
1943 base: Node = Node{ .id = .ArrayType },2012 base: Node = Node{ .tag = .ArrayType },
1944 op_token: TokenIndex,2013 op_token: TokenIndex,
1945 rhs: *Node,2014 rhs: *Node,
1946 len_expr: *Node,2015 len_expr: *Node,
...@@ -1967,7 +2036,7 @@ pub const Node = struct {...@@ -1967,7 +2036,7 @@ pub const Node = struct {
1967 };2036 };
19682037
1969 pub const ArrayTypeSentinel = struct {2038 pub const ArrayTypeSentinel = struct {
1970 base: Node = Node{ .id = .ArrayTypeSentinel },2039 base: Node = Node{ .tag = .ArrayTypeSentinel },
1971 op_token: TokenIndex,2040 op_token: TokenIndex,
1972 rhs: *Node,2041 rhs: *Node,
1973 len_expr: *Node,2042 len_expr: *Node,
...@@ -1998,7 +2067,7 @@ pub const Node = struct {...@@ -1998,7 +2067,7 @@ pub const Node = struct {
1998 };2067 };
19992068
2000 pub const PtrType = struct {2069 pub const PtrType = struct {
2001 base: Node = Node{ .id = .PtrType },2070 base: Node = Node{ .tag = .PtrType },
2002 op_token: TokenIndex,2071 op_token: TokenIndex,
2003 rhs: *Node,2072 rhs: *Node,
2004 /// TODO Add a u8 flags field to Node where it would otherwise be padding, and each bit represents2073 /// TODO Add a u8 flags field to Node where it would otherwise be padding, and each bit represents
...@@ -2034,7 +2103,7 @@ pub const Node = struct {...@@ -2034,7 +2103,7 @@ pub const Node = struct {
2034 };2103 };
20352104
2036 pub const SliceType = struct {2105 pub const SliceType = struct {
2037 base: Node = Node{ .id = .SliceType },2106 base: Node = Node{ .tag = .SliceType },
2038 op_token: TokenIndex,2107 op_token: TokenIndex,
2039 rhs: *Node,2108 rhs: *Node,
2040 /// TODO Add a u8 flags field to Node where it would otherwise be padding, and each bit represents2109 /// TODO Add a u8 flags field to Node where it would otherwise be padding, and each bit represents
...@@ -2070,7 +2139,7 @@ pub const Node = struct {...@@ -2070,7 +2139,7 @@ pub const Node = struct {
2070 };2139 };
20712140
2072 pub const FieldInitializer = struct {2141 pub const FieldInitializer = struct {
2073 base: Node = Node{ .id = .FieldInitializer },2142 base: Node = Node{ .tag = .FieldInitializer },
2074 period_token: TokenIndex,2143 period_token: TokenIndex,
2075 name_token: TokenIndex,2144 name_token: TokenIndex,
2076 expr: *Node,2145 expr: *Node,
...@@ -2095,7 +2164,7 @@ pub const Node = struct {...@@ -2095,7 +2164,7 @@ pub const Node = struct {
20952164
2096 /// Elements occur directly in memory after ArrayInitializer.2165 /// Elements occur directly in memory after ArrayInitializer.
2097 pub const ArrayInitializer = struct {2166 pub const ArrayInitializer = struct {
2098 base: Node = Node{ .id = .ArrayInitializer },2167 base: Node = Node{ .tag = .ArrayInitializer },
2099 rtoken: TokenIndex,2168 rtoken: TokenIndex,
2100 list_len: NodeIndex,2169 list_len: NodeIndex,
2101 lhs: *Node,2170 lhs: *Node,
...@@ -2148,7 +2217,7 @@ pub const Node = struct {...@@ -2148,7 +2217,7 @@ pub const Node = struct {
21482217
2149 /// Elements occur directly in memory after ArrayInitializerDot.2218 /// Elements occur directly in memory after ArrayInitializerDot.
2150 pub const ArrayInitializerDot = struct {2219 pub const ArrayInitializerDot = struct {
2151 base: Node = Node{ .id = .ArrayInitializerDot },2220 base: Node = Node{ .tag = .ArrayInitializerDot },
2152 dot: TokenIndex,2221 dot: TokenIndex,
2153 rtoken: TokenIndex,2222 rtoken: TokenIndex,
2154 list_len: NodeIndex,2223 list_len: NodeIndex,
...@@ -2198,7 +2267,7 @@ pub const Node = struct {...@@ -2198,7 +2267,7 @@ pub const Node = struct {
21982267
2199 /// Elements occur directly in memory after StructInitializer.2268 /// Elements occur directly in memory after StructInitializer.
2200 pub const StructInitializer = struct {2269 pub const StructInitializer = struct {
2201 base: Node = Node{ .id = .StructInitializer },2270 base: Node = Node{ .tag = .StructInitializer },
2202 rtoken: TokenIndex,2271 rtoken: TokenIndex,
2203 list_len: NodeIndex,2272 list_len: NodeIndex,
2204 lhs: *Node,2273 lhs: *Node,
...@@ -2251,7 +2320,7 @@ pub const Node = struct {...@@ -2251,7 +2320,7 @@ pub const Node = struct {
22512320
2252 /// Elements occur directly in memory after StructInitializerDot.2321 /// Elements occur directly in memory after StructInitializerDot.
2253 pub const StructInitializerDot = struct {2322 pub const StructInitializerDot = struct {
2254 base: Node = Node{ .id = .StructInitializerDot },2323 base: Node = Node{ .tag = .StructInitializerDot },
2255 dot: TokenIndex,2324 dot: TokenIndex,
2256 rtoken: TokenIndex,2325 rtoken: TokenIndex,
2257 list_len: NodeIndex,2326 list_len: NodeIndex,
...@@ -2301,7 +2370,7 @@ pub const Node = struct {...@@ -2301,7 +2370,7 @@ pub const Node = struct {
23012370
2302 /// Parameter nodes directly follow Call in memory.2371 /// Parameter nodes directly follow Call in memory.
2303 pub const Call = struct {2372 pub const Call = struct {
2304 base: Node = Node{ .id = .Call },2373 base: Node = Node{ .tag = .Call },
2305 lhs: *Node,2374 lhs: *Node,
2306 rtoken: TokenIndex,2375 rtoken: TokenIndex,
2307 params_len: NodeIndex,2376 params_len: NodeIndex,
...@@ -2355,7 +2424,7 @@ pub const Node = struct {...@@ -2355,7 +2424,7 @@ pub const Node = struct {
2355 };2424 };
23562425
2357 pub const SuffixOp = struct {2426 pub const SuffixOp = struct {
2358 base: Node = Node{ .id = .SuffixOp },2427 base: Node = Node{ .tag = .SuffixOp },
2359 op: Op,2428 op: Op,
2360 lhs: *Node,2429 lhs: *Node,
2361 rtoken: TokenIndex,2430 rtoken: TokenIndex,
...@@ -2415,7 +2484,7 @@ pub const Node = struct {...@@ -2415,7 +2484,7 @@ pub const Node = struct {
2415 };2484 };
24162485
2417 pub const GroupedExpression = struct {2486 pub const GroupedExpression = struct {
2418 base: Node = Node{ .id = .GroupedExpression },2487 base: Node = Node{ .tag = .GroupedExpression },
2419 lparen: TokenIndex,2488 lparen: TokenIndex,
2420 expr: *Node,2489 expr: *Node,
2421 rparen: TokenIndex,2490 rparen: TokenIndex,
...@@ -2441,7 +2510,7 @@ pub const Node = struct {...@@ -2441,7 +2510,7 @@ pub const Node = struct {
2441 /// TODO break this into separate Break, Continue, Return AST Nodes to save memory.2510 /// TODO break this into separate Break, Continue, Return AST Nodes to save memory.
2442 /// Could be further broken into LabeledBreak, LabeledContinue, and ReturnVoid to save even more.2511 /// Could be further broken into LabeledBreak, LabeledContinue, and ReturnVoid to save even more.
2443 pub const ControlFlowExpression = struct {2512 pub const ControlFlowExpression = struct {
2444 base: Node = Node{ .id = .ControlFlowExpression },2513 base: Node = Node{ .tag = .ControlFlowExpression },
2445 ltoken: TokenIndex,2514 ltoken: TokenIndex,
2446 kind: Kind,2515 kind: Kind,
2447 rhs: ?*Node,2516 rhs: ?*Node,
...@@ -2496,7 +2565,7 @@ pub const Node = struct {...@@ -2496,7 +2565,7 @@ pub const Node = struct {
2496 };2565 };
24972566
2498 pub const Suspend = struct {2567 pub const Suspend = struct {
2499 base: Node = Node{ .id = .Suspend },2568 base: Node = Node{ .tag = .Suspend },
2500 suspend_token: TokenIndex,2569 suspend_token: TokenIndex,
2501 body: ?*Node,2570 body: ?*Node,
25022571
...@@ -2525,7 +2594,7 @@ pub const Node = struct {...@@ -2525,7 +2594,7 @@ pub const Node = struct {
2525 };2594 };
25262595
2527 pub const IntegerLiteral = struct {2596 pub const IntegerLiteral = struct {
2528 base: Node = Node{ .id = .IntegerLiteral },2597 base: Node = Node{ .tag = .IntegerLiteral },
2529 token: TokenIndex,2598 token: TokenIndex,
25302599
2531 pub fn iterate(self: *const IntegerLiteral, index: usize) ?*Node {2600 pub fn iterate(self: *const IntegerLiteral, index: usize) ?*Node {
...@@ -2542,7 +2611,7 @@ pub const Node = struct {...@@ -2542,7 +2611,7 @@ pub const Node = struct {
2542 };2611 };
25432612
2544 pub const EnumLiteral = struct {2613 pub const EnumLiteral = struct {
2545 base: Node = Node{ .id = .EnumLiteral },2614 base: Node = Node{ .tag = .EnumLiteral },
2546 dot: TokenIndex,2615 dot: TokenIndex,
2547 name: TokenIndex,2616 name: TokenIndex,
25482617
...@@ -2560,7 +2629,7 @@ pub const Node = struct {...@@ -2560,7 +2629,7 @@ pub const Node = struct {
2560 };2629 };
25612630
2562 pub const FloatLiteral = struct {2631 pub const FloatLiteral = struct {
2563 base: Node = Node{ .id = .FloatLiteral },2632 base: Node = Node{ .tag = .FloatLiteral },
2564 token: TokenIndex,2633 token: TokenIndex,
25652634
2566 pub fn iterate(self: *const FloatLiteral, index: usize) ?*Node {2635 pub fn iterate(self: *const FloatLiteral, index: usize) ?*Node {
...@@ -2578,7 +2647,7 @@ pub const Node = struct {...@@ -2578,7 +2647,7 @@ pub const Node = struct {
25782647
2579 /// Parameters are in memory following BuiltinCall.2648 /// Parameters are in memory following BuiltinCall.
2580 pub const BuiltinCall = struct {2649 pub const BuiltinCall = struct {
2581 base: Node = Node{ .id = .BuiltinCall },2650 base: Node = Node{ .tag = .BuiltinCall },
2582 params_len: NodeIndex,2651 params_len: NodeIndex,
2583 builtin_token: TokenIndex,2652 builtin_token: TokenIndex,
2584 rparen_token: TokenIndex,2653 rparen_token: TokenIndex,
...@@ -2627,7 +2696,7 @@ pub const Node = struct {...@@ -2627,7 +2696,7 @@ pub const Node = struct {
2627 };2696 };
26282697
2629 pub const StringLiteral = struct {2698 pub const StringLiteral = struct {
2630 base: Node = Node{ .id = .StringLiteral },2699 base: Node = Node{ .tag = .StringLiteral },
2631 token: TokenIndex,2700 token: TokenIndex,
26322701
2633 pub fn iterate(self: *const StringLiteral, index: usize) ?*Node {2702 pub fn iterate(self: *const StringLiteral, index: usize) ?*Node {
...@@ -2645,7 +2714,7 @@ pub const Node = struct {...@@ -2645,7 +2714,7 @@ pub const Node = struct {
26452714
2646 /// The string literal tokens appear directly in memory after MultilineStringLiteral.2715 /// The string literal tokens appear directly in memory after MultilineStringLiteral.
2647 pub const MultilineStringLiteral = struct {2716 pub const MultilineStringLiteral = struct {
2648 base: Node = Node{ .id = .MultilineStringLiteral },2717 base: Node = Node{ .tag = .MultilineStringLiteral },
2649 lines_len: TokenIndex,2718 lines_len: TokenIndex,
26502719
2651 /// After this the caller must initialize the lines list.2720 /// After this the caller must initialize the lines list.
...@@ -2687,7 +2756,7 @@ pub const Node = struct {...@@ -2687,7 +2756,7 @@ pub const Node = struct {
2687 };2756 };
26882757
2689 pub const CharLiteral = struct {2758 pub const CharLiteral = struct {
2690 base: Node = Node{ .id = .CharLiteral },2759 base: Node = Node{ .tag = .CharLiteral },
2691 token: TokenIndex,2760 token: TokenIndex,
26922761
2693 pub fn iterate(self: *const CharLiteral, index: usize) ?*Node {2762 pub fn iterate(self: *const CharLiteral, index: usize) ?*Node {
...@@ -2704,7 +2773,7 @@ pub const Node = struct {...@@ -2704,7 +2773,7 @@ pub const Node = struct {
2704 };2773 };
27052774
2706 pub const BoolLiteral = struct {2775 pub const BoolLiteral = struct {
2707 base: Node = Node{ .id = .BoolLiteral },2776 base: Node = Node{ .tag = .BoolLiteral },
2708 token: TokenIndex,2777 token: TokenIndex,
27092778
2710 pub fn iterate(self: *const BoolLiteral, index: usize) ?*Node {2779 pub fn iterate(self: *const BoolLiteral, index: usize) ?*Node {
...@@ -2721,7 +2790,7 @@ pub const Node = struct {...@@ -2721,7 +2790,7 @@ pub const Node = struct {
2721 };2790 };
27222791
2723 pub const NullLiteral = struct {2792 pub const NullLiteral = struct {
2724 base: Node = Node{ .id = .NullLiteral },2793 base: Node = Node{ .tag = .NullLiteral },
2725 token: TokenIndex,2794 token: TokenIndex,
27262795
2727 pub fn iterate(self: *const NullLiteral, index: usize) ?*Node {2796 pub fn iterate(self: *const NullLiteral, index: usize) ?*Node {
...@@ -2738,7 +2807,7 @@ pub const Node = struct {...@@ -2738,7 +2807,7 @@ pub const Node = struct {
2738 };2807 };
27392808
2740 pub const UndefinedLiteral = struct {2809 pub const UndefinedLiteral = struct {
2741 base: Node = Node{ .id = .UndefinedLiteral },2810 base: Node = Node{ .tag = .UndefinedLiteral },
2742 token: TokenIndex,2811 token: TokenIndex,
27432812
2744 pub fn iterate(self: *const UndefinedLiteral, index: usize) ?*Node {2813 pub fn iterate(self: *const UndefinedLiteral, index: usize) ?*Node {
...@@ -2755,7 +2824,7 @@ pub const Node = struct {...@@ -2755,7 +2824,7 @@ pub const Node = struct {
2755 };2824 };
27562825
2757 pub const Asm = struct {2826 pub const Asm = struct {
2758 base: Node = Node{ .id = .Asm },2827 base: Node = Node{ .tag = .Asm },
2759 asm_token: TokenIndex,2828 asm_token: TokenIndex,
2760 rparen: TokenIndex,2829 rparen: TokenIndex,
2761 volatile_token: ?TokenIndex,2830 volatile_token: ?TokenIndex,
...@@ -2875,7 +2944,7 @@ pub const Node = struct {...@@ -2875,7 +2944,7 @@ pub const Node = struct {
2875 };2944 };
28762945
2877 pub const Unreachable = struct {2946 pub const Unreachable = struct {
2878 base: Node = Node{ .id = .Unreachable },2947 base: Node = Node{ .tag = .Unreachable },
2879 token: TokenIndex,2948 token: TokenIndex,
28802949
2881 pub fn iterate(self: *const Unreachable, index: usize) ?*Node {2950 pub fn iterate(self: *const Unreachable, index: usize) ?*Node {
...@@ -2892,7 +2961,7 @@ pub const Node = struct {...@@ -2892,7 +2961,7 @@ pub const Node = struct {
2892 };2961 };
28932962
2894 pub const ErrorType = struct {2963 pub const ErrorType = struct {
2895 base: Node = Node{ .id = .ErrorType },2964 base: Node = Node{ .tag = .ErrorType },
2896 token: TokenIndex,2965 token: TokenIndex,
28972966
2898 pub fn iterate(self: *const ErrorType, index: usize) ?*Node {2967 pub fn iterate(self: *const ErrorType, index: usize) ?*Node {
...@@ -2909,7 +2978,7 @@ pub const Node = struct {...@@ -2909,7 +2978,7 @@ pub const Node = struct {
2909 };2978 };
29102979
2911 pub const AnyType = struct {2980 pub const AnyType = struct {
2912 base: Node = Node{ .id = .AnyType },2981 base: Node = Node{ .tag = .AnyType },
2913 token: TokenIndex,2982 token: TokenIndex,
29142983
2915 pub fn iterate(self: *const AnyType, index: usize) ?*Node {2984 pub fn iterate(self: *const AnyType, index: usize) ?*Node {
...@@ -2929,7 +2998,7 @@ pub const Node = struct {...@@ -2929,7 +2998,7 @@ pub const Node = struct {
2929 /// TODO actually maybe remove entirely in favor of iterating backward from Node.firstToken()2998 /// TODO actually maybe remove entirely in favor of iterating backward from Node.firstToken()
2930 /// and forwards to find same-line doc comments.2999 /// and forwards to find same-line doc comments.
2931 pub const DocComment = struct {3000 pub const DocComment = struct {
2932 base: Node = Node{ .id = .DocComment },3001 base: Node = Node{ .tag = .DocComment },
2933 /// Points to the first doc comment token. API users are expected to iterate over the3002 /// Points to the first doc comment token. API users are expected to iterate over the
2934 /// tokens array, looking for more doc comments, ignoring line comments, and stopping3003 /// tokens array, looking for more doc comments, ignoring line comments, and stopping
2935 /// at the first other token.3004 /// at the first other token.
...@@ -2951,7 +3020,7 @@ pub const Node = struct {...@@ -2951,7 +3020,7 @@ pub const Node = struct {
2951 };3020 };
29523021
2953 pub const TestDecl = struct {3022 pub const TestDecl = struct {
2954 base: Node = Node{ .id = .TestDecl },3023 base: Node = Node{ .tag = .TestDecl },
2955 doc_comments: ?*DocComment,3024 doc_comments: ?*DocComment,
2956 test_token: TokenIndex,3025 test_token: TokenIndex,
2957 name: *Node,3026 name: *Node,
...@@ -2996,7 +3065,7 @@ pub const PtrInfo = struct {...@@ -2996,7 +3065,7 @@ pub const PtrInfo = struct {
29963065
2997test "iterate" {3066test "iterate" {
2998 var root = Node.Root{3067 var root = Node.Root{
2999 .base = Node{ .id = Node.Id.Root },3068 .base = Node{ .tag = Node.Tag.Root },
3000 .decls_len = 0,3069 .decls_len = 0,
3001 .eof_token = 0,3070 .eof_token = 0,
3002 };3071 };
lib/std/zig/parse.zig+36-111
...@@ -1128,8 +1128,9 @@ const Parser = struct {...@@ -1128,8 +1128,9 @@ const Parser = struct {
1128 const expr_node = try p.expectNode(parseExpr, .{1128 const expr_node = try p.expectNode(parseExpr, .{
1129 .ExpectedExpr = .{ .token = p.tok_i },1129 .ExpectedExpr = .{ .token = p.tok_i },
1130 });1130 });
1131 const node = try p.arena.allocator.create(Node.Resume);1131 const node = try p.arena.allocator.create(Node.SimplePrefixOp);
1132 node.* = .{1132 node.* = .{
1133 .base = .{ .tag = .Resume },
1133 .op_token = token,1134 .op_token = token,
1134 .rhs = expr_node,1135 .rhs = expr_node,
1135 };1136 };
...@@ -1439,7 +1440,7 @@ const Parser = struct {...@@ -1439,7 +1440,7 @@ const Parser = struct {
1439 });1440 });
14401441
1441 while (try p.parseSuffixOp()) |node| {1442 while (try p.parseSuffixOp()) |node| {
1442 switch (node.id) {1443 switch (node.tag) {
1443 .SuffixOp => node.cast(Node.SuffixOp).?.lhs = res,1444 .SuffixOp => node.cast(Node.SuffixOp).?.lhs = res,
1444 .InfixOp => node.cast(Node.InfixOp).?.lhs = res,1445 .InfixOp => node.cast(Node.InfixOp).?.lhs = res,
1445 else => unreachable,1446 else => unreachable,
...@@ -1470,7 +1471,7 @@ const Parser = struct {...@@ -1470,7 +1471,7 @@ const Parser = struct {
14701471
1471 while (true) {1472 while (true) {
1472 if (try p.parseSuffixOp()) |node| {1473 if (try p.parseSuffixOp()) |node| {
1473 switch (node.id) {1474 switch (node.tag) {
1474 .SuffixOp => node.cast(Node.SuffixOp).?.lhs = res,1475 .SuffixOp => node.cast(Node.SuffixOp).?.lhs = res,
1475 .InfixOp => node.cast(Node.InfixOp).?.lhs = res,1476 .InfixOp => node.cast(Node.InfixOp).?.lhs = res,
1476 else => unreachable,1477 else => unreachable,
...@@ -1660,7 +1661,7 @@ const Parser = struct {...@@ -1660,7 +1661,7 @@ const Parser = struct {
1660 }1661 }
16611662
1662 if (try p.parseLoopTypeExpr()) |node| {1663 if (try p.parseLoopTypeExpr()) |node| {
1663 switch (node.id) {1664 switch (node.tag) {
1664 .For => node.cast(Node.For).?.label = label,1665 .For => node.cast(Node.For).?.label = label,
1665 .While => node.cast(Node.While).?.label = label,1666 .While => node.cast(Node.While).?.label = label,
1666 else => unreachable,1667 else => unreachable,
...@@ -2434,9 +2435,10 @@ const Parser = struct {...@@ -2434,9 +2435,10 @@ const Parser = struct {
2434 }2435 }
2435 }2436 }
24362437
2437 fn allocSimplePrefixOp(p: *Parser, comptime tag: Node.Id, token: TokenIndex) !?*Node {2438 fn allocSimplePrefixOp(p: *Parser, comptime tag: Node.Tag, token: TokenIndex) !?*Node {
2438 const node = try p.arena.allocator.create(Node.SimplePrefixOp(tag));2439 const node = try p.arena.allocator.create(Node.SimplePrefixOp);
2439 node.* = .{2440 node.* = .{
2441 .base = .{ .tag = tag },
2440 .op_token = token,2442 .op_token = token,
2441 .rhs = undefined, // set by caller2443 .rhs = undefined, // set by caller
2442 };2444 };
...@@ -2457,8 +2459,9 @@ const Parser = struct {...@@ -2457,8 +2459,9 @@ const Parser = struct {
2457 /// / PtrTypeStart (KEYWORD_align LPAREN Expr (COLON INTEGER COLON INTEGER)? RPAREN / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)*2459 /// / PtrTypeStart (KEYWORD_align LPAREN Expr (COLON INTEGER COLON INTEGER)? RPAREN / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)*
2458 fn parsePrefixTypeOp(p: *Parser) !?*Node {2460 fn parsePrefixTypeOp(p: *Parser) !?*Node {
2459 if (p.eatToken(.QuestionMark)) |token| {2461 if (p.eatToken(.QuestionMark)) |token| {
2460 const node = try p.arena.allocator.create(Node.OptionalType);2462 const node = try p.arena.allocator.create(Node.SimplePrefixOp);
2461 node.* = .{2463 node.* = .{
2464 .base = .{ .tag = .OptionalType },
2462 .op_token = token,2465 .op_token = token,
2463 .rhs = undefined, // set by caller2466 .rhs = undefined, // set by caller
2464 };2467 };
...@@ -3072,7 +3075,6 @@ const Parser = struct {...@@ -3072,7 +3075,6 @@ const Parser = struct {
3072 fn createLiteral(p: *Parser, comptime T: type, token: TokenIndex) !*Node {3075 fn createLiteral(p: *Parser, comptime T: type, token: TokenIndex) !*Node {
3073 const result = try p.arena.allocator.create(T);3076 const result = try p.arena.allocator.create(T);
3074 result.* = T{3077 result.* = T{
3075 .base = Node{ .id = Node.typeToId(T) },
3076 .token = token,3078 .token = token,
3077 };3079 };
3078 return &result.base;3080 return &result.base;
...@@ -3148,8 +3150,9 @@ const Parser = struct {...@@ -3148,8 +3150,9 @@ const Parser = struct {
31483150
3149 fn parseTry(p: *Parser) !?*Node {3151 fn parseTry(p: *Parser) !?*Node {
3150 const token = p.eatToken(.Keyword_try) orelse return null;3152 const token = p.eatToken(.Keyword_try) orelse return null;
3151 const node = try p.arena.allocator.create(Node.Try);3153 const node = try p.arena.allocator.create(Node.SimplePrefixOp);
3152 node.* = .{3154 node.* = .{
3155 .base = .{ .tag = .Try },
3153 .op_token = token,3156 .op_token = token,
3154 .rhs = undefined, // set by caller3157 .rhs = undefined, // set by caller
3155 };3158 };
...@@ -3213,58 +3216,19 @@ const Parser = struct {...@@ -3213,58 +3216,19 @@ const Parser = struct {
3213 if (try opParseFn(p)) |first_op| {3216 if (try opParseFn(p)) |first_op| {
3214 var rightmost_op = first_op;3217 var rightmost_op = first_op;
3215 while (true) {3218 while (true) {
3216 switch (rightmost_op.id) {3219 switch (rightmost_op.tag) {
3217 .AddressOf => {3220 .AddressOf,
3221 .Await,
3222 .BitNot,
3223 .BoolNot,
3224 .OptionalType,
3225 .Negation,
3226 .NegationWrap,
3227 .Resume,
3228 .Try,
3229 => {
3218 if (try opParseFn(p)) |rhs| {3230 if (try opParseFn(p)) |rhs| {
3219 rightmost_op.cast(Node.AddressOf).?.rhs = rhs;3231 rightmost_op.cast(Node.SimplePrefixOp).?.rhs = rhs;
3220 rightmost_op = rhs;
3221 } else break;
3222 },
3223 .Await => {
3224 if (try opParseFn(p)) |rhs| {
3225 rightmost_op.cast(Node.Await).?.rhs = rhs;
3226 rightmost_op = rhs;
3227 } else break;
3228 },
3229 .BitNot => {
3230 if (try opParseFn(p)) |rhs| {
3231 rightmost_op.cast(Node.BitNot).?.rhs = rhs;
3232 rightmost_op = rhs;
3233 } else break;
3234 },
3235 .BoolNot => {
3236 if (try opParseFn(p)) |rhs| {
3237 rightmost_op.cast(Node.BoolNot).?.rhs = rhs;
3238 rightmost_op = rhs;
3239 } else break;
3240 },
3241 .OptionalType => {
3242 if (try opParseFn(p)) |rhs| {
3243 rightmost_op.cast(Node.OptionalType).?.rhs = rhs;
3244 rightmost_op = rhs;
3245 } else break;
3246 },
3247 .Negation => {
3248 if (try opParseFn(p)) |rhs| {
3249 rightmost_op.cast(Node.Negation).?.rhs = rhs;
3250 rightmost_op = rhs;
3251 } else break;
3252 },
3253 .NegationWrap => {
3254 if (try opParseFn(p)) |rhs| {
3255 rightmost_op.cast(Node.NegationWrap).?.rhs = rhs;
3256 rightmost_op = rhs;
3257 } else break;
3258 },
3259 .Resume => {
3260 if (try opParseFn(p)) |rhs| {
3261 rightmost_op.cast(Node.Resume).?.rhs = rhs;
3262 rightmost_op = rhs;
3263 } else break;
3264 },
3265 .Try => {
3266 if (try opParseFn(p)) |rhs| {
3267 rightmost_op.cast(Node.Try).?.rhs = rhs;
3268 rightmost_op = rhs;3232 rightmost_op = rhs;
3269 } else break;3233 } else break;
3270 },3234 },
...@@ -3310,57 +3274,18 @@ const Parser = struct {...@@ -3310,57 +3274,18 @@ const Parser = struct {
3310 }3274 }
33113275
3312 // If any prefix op existed, a child node on the RHS is required3276 // If any prefix op existed, a child node on the RHS is required
3313 switch (rightmost_op.id) {3277 switch (rightmost_op.tag) {
3314 .AddressOf => {3278 .AddressOf,
3315 const prefix_op = rightmost_op.cast(Node.AddressOf).?;3279 .Await,
3316 prefix_op.rhs = try p.expectNode(childParseFn, .{3280 .BitNot,
3317 .InvalidToken = .{ .token = p.tok_i },3281 .BoolNot,
3318 });3282 .OptionalType,
3319 },3283 .Negation,
3320 .Await => {3284 .NegationWrap,
3321 const prefix_op = rightmost_op.cast(Node.Await).?;3285 .Resume,
3322 prefix_op.rhs = try p.expectNode(childParseFn, .{3286 .Try,
3323 .InvalidToken = .{ .token = p.tok_i },3287 => {
3324 });3288 const prefix_op = rightmost_op.cast(Node.SimplePrefixOp).?;
3325 },
3326 .BitNot => {
3327 const prefix_op = rightmost_op.cast(Node.BitNot).?;
3328 prefix_op.rhs = try p.expectNode(childParseFn, .{
3329 .InvalidToken = .{ .token = p.tok_i },
3330 });
3331 },
3332 .BoolNot => {
3333 const prefix_op = rightmost_op.cast(Node.BoolNot).?;
3334 prefix_op.rhs = try p.expectNode(childParseFn, .{
3335 .InvalidToken = .{ .token = p.tok_i },
3336 });
3337 },
3338 .OptionalType => {
3339 const prefix_op = rightmost_op.cast(Node.OptionalType).?;
3340 prefix_op.rhs = try p.expectNode(childParseFn, .{
3341 .InvalidToken = .{ .token = p.tok_i },
3342 });
3343 },
3344 .Negation => {
3345 const prefix_op = rightmost_op.cast(Node.Negation).?;
3346 prefix_op.rhs = try p.expectNode(childParseFn, .{
3347 .InvalidToken = .{ .token = p.tok_i },
3348 });
3349 },
3350 .NegationWrap => {
3351 const prefix_op = rightmost_op.cast(Node.NegationWrap).?;
3352 prefix_op.rhs = try p.expectNode(childParseFn, .{
3353 .InvalidToken = .{ .token = p.tok_i },
3354 });
3355 },
3356 .Resume => {
3357 const prefix_op = rightmost_op.cast(Node.Resume).?;
3358 prefix_op.rhs = try p.expectNode(childParseFn, .{
3359 .InvalidToken = .{ .token = p.tok_i },
3360 });
3361 },
3362 .Try => {
3363 const prefix_op = rightmost_op.cast(Node.Try).?;
3364 prefix_op.rhs = try p.expectNode(childParseFn, .{3289 prefix_op.rhs = try p.expectNode(childParseFn, .{
3365 .InvalidToken = .{ .token = p.tok_i },3290 .InvalidToken = .{ .token = p.tok_i },
3366 });3291 });
lib/std/zig/render.zig+33-58
...@@ -223,7 +223,7 @@ fn renderTopLevelDecl(allocator: *mem.Allocator, stream: anytype, tree: *ast.Tre...@@ -223,7 +223,7 @@ fn renderTopLevelDecl(allocator: *mem.Allocator, stream: anytype, tree: *ast.Tre
223}223}
224224
225fn renderContainerDecl(allocator: *mem.Allocator, stream: anytype, tree: *ast.Tree, indent: usize, start_col: *usize, decl: *ast.Node, space: Space) (@TypeOf(stream).Error || Error)!void {225fn renderContainerDecl(allocator: *mem.Allocator, stream: anytype, tree: *ast.Tree, indent: usize, start_col: *usize, decl: *ast.Node, space: Space) (@TypeOf(stream).Error || Error)!void {
226 switch (decl.id) {226 switch (decl.tag) {
227 .FnProto => {227 .FnProto => {
228 const fn_proto = @fieldParentPtr(ast.Node.FnProto, "base", decl);228 const fn_proto = @fieldParentPtr(ast.Node.FnProto, "base", decl);
229229
...@@ -365,7 +365,7 @@ fn renderExpression(...@@ -365,7 +365,7 @@ fn renderExpression(
365 base: *ast.Node,365 base: *ast.Node,
366 space: Space,366 space: Space,
367) (@TypeOf(stream).Error || Error)!void {367) (@TypeOf(stream).Error || Error)!void {
368 switch (base.id) {368 switch (base.tag) {
369 .Identifier => {369 .Identifier => {
370 const identifier = @fieldParentPtr(ast.Node.Identifier, "base", base);370 const identifier = @fieldParentPtr(ast.Node.Identifier, "base", base);
371 return renderToken(tree, stream, identifier.token, indent, start_col, space);371 return renderToken(tree, stream, identifier.token, indent, start_col, space);
...@@ -468,50 +468,25 @@ fn renderExpression(...@@ -468,50 +468,25 @@ fn renderExpression(
468 return renderExpression(allocator, stream, tree, indent, start_col, infix_op_node.rhs, space);468 return renderExpression(allocator, stream, tree, indent, start_col, infix_op_node.rhs, space);
469 },469 },
470470
471 .BitNot => {471 .BitNot,
472 const bit_not = @fieldParentPtr(ast.Node.BitNot, "base", base);472 .BoolNot,
473 try renderToken(tree, stream, bit_not.op_token, indent, start_col, Space.None);473 .Negation,
474 return renderExpression(allocator, stream, tree, indent, start_col, bit_not.rhs, space);474 .NegationWrap,
475 .OptionalType,
476 .AddressOf,
477 => {
478 const casted_node = @fieldParentPtr(ast.Node.SimplePrefixOp, "base", base);
479 try renderToken(tree, stream, casted_node.op_token, indent, start_col, Space.None);
480 return renderExpression(allocator, stream, tree, indent, start_col, casted_node.rhs, space);
475 },481 },
476 .BoolNot => {482
477 const bool_not = @fieldParentPtr(ast.Node.BoolNot, "base", base);483 .Try,
478 try renderToken(tree, stream, bool_not.op_token, indent, start_col, Space.None);484 .Resume,
479 return renderExpression(allocator, stream, tree, indent, start_col, bool_not.rhs, space);485 .Await,
480 },486 => {
481 .Negation => {487 const casted_node = @fieldParentPtr(ast.Node.SimplePrefixOp, "base", base);
482 const negation = @fieldParentPtr(ast.Node.Negation, "base", base);488 try renderToken(tree, stream, casted_node.op_token, indent, start_col, Space.Space);
483 try renderToken(tree, stream, negation.op_token, indent, start_col, Space.None);489 return renderExpression(allocator, stream, tree, indent, start_col, casted_node.rhs, space);
484 return renderExpression(allocator, stream, tree, indent, start_col, negation.rhs, space);
485 },
486 .NegationWrap => {
487 const negation_wrap = @fieldParentPtr(ast.Node.NegationWrap, "base", base);
488 try renderToken(tree, stream, negation_wrap.op_token, indent, start_col, Space.None);
489 return renderExpression(allocator, stream, tree, indent, start_col, negation_wrap.rhs, space);
490 },
491 .OptionalType => {
492 const opt_type = @fieldParentPtr(ast.Node.OptionalType, "base", base);
493 try renderToken(tree, stream, opt_type.op_token, indent, start_col, Space.None);
494 return renderExpression(allocator, stream, tree, indent, start_col, opt_type.rhs, space);
495 },
496 .AddressOf => {
497 const addr_of = @fieldParentPtr(ast.Node.AddressOf, "base", base);
498 try renderToken(tree, stream, addr_of.op_token, indent, start_col, Space.None);
499 return renderExpression(allocator, stream, tree, indent, start_col, addr_of.rhs, space);
500 },
501 .Try => {
502 const try_node = @fieldParentPtr(ast.Node.Try, "base", base);
503 try renderToken(tree, stream, try_node.op_token, indent, start_col, Space.Space);
504 return renderExpression(allocator, stream, tree, indent, start_col, try_node.rhs, space);
505 },
506 .Resume => {
507 const resume_node = @fieldParentPtr(ast.Node.Resume, "base", base);
508 try renderToken(tree, stream, resume_node.op_token, indent, start_col, Space.Space);
509 return renderExpression(allocator, stream, tree, indent, start_col, resume_node.rhs, space);
510 },
511 .Await => {
512 const await_node = @fieldParentPtr(ast.Node.Await, "base", base);
513 try renderToken(tree, stream, await_node.op_token, indent, start_col, Space.Space);
514 return renderExpression(allocator, stream, tree, indent, start_col, await_node.rhs, space);
515 },490 },
516491
517 .ArrayType => {492 .ArrayType => {
...@@ -659,7 +634,7 @@ fn renderExpression(...@@ -659,7 +634,7 @@ fn renderExpression(
659 .ArrayInitializer, .ArrayInitializerDot => {634 .ArrayInitializer, .ArrayInitializerDot => {
660 var rtoken: ast.TokenIndex = undefined;635 var rtoken: ast.TokenIndex = undefined;
661 var exprs: []*ast.Node = undefined;636 var exprs: []*ast.Node = undefined;
662 const lhs: union(enum) { dot: ast.TokenIndex, node: *ast.Node } = switch (base.id) {637 const lhs: union(enum) { dot: ast.TokenIndex, node: *ast.Node } = switch (base.tag) {
663 .ArrayInitializerDot => blk: {638 .ArrayInitializerDot => blk: {
664 const casted = @fieldParentPtr(ast.Node.ArrayInitializerDot, "base", base);639 const casted = @fieldParentPtr(ast.Node.ArrayInitializerDot, "base", base);
665 rtoken = casted.rtoken;640 rtoken = casted.rtoken;
...@@ -793,14 +768,14 @@ fn renderExpression(...@@ -793,14 +768,14 @@ fn renderExpression(
793 }768 }
794769
795 try renderExtraNewline(tree, stream, start_col, next_expr);770 try renderExtraNewline(tree, stream, start_col, next_expr);
796 if (next_expr.id != .MultilineStringLiteral) {771 if (next_expr.tag != .MultilineStringLiteral) {
797 try stream.writeByteNTimes(' ', new_indent);772 try stream.writeByteNTimes(' ', new_indent);
798 }773 }
799 } else {774 } else {
800 try renderExpression(allocator, stream, tree, new_indent, start_col, expr, Space.Comma); // ,775 try renderExpression(allocator, stream, tree, new_indent, start_col, expr, Space.Comma); // ,
801 }776 }
802 }777 }
803 if (exprs[exprs.len - 1].id != .MultilineStringLiteral) {778 if (exprs[exprs.len - 1].tag != .MultilineStringLiteral) {
804 try stream.writeByteNTimes(' ', indent);779 try stream.writeByteNTimes(' ', indent);
805 }780 }
806 return renderToken(tree, stream, rtoken, indent, start_col, space);781 return renderToken(tree, stream, rtoken, indent, start_col, space);
...@@ -823,7 +798,7 @@ fn renderExpression(...@@ -823,7 +798,7 @@ fn renderExpression(
823 .StructInitializer, .StructInitializerDot => {798 .StructInitializer, .StructInitializerDot => {
824 var rtoken: ast.TokenIndex = undefined;799 var rtoken: ast.TokenIndex = undefined;
825 var field_inits: []*ast.Node = undefined;800 var field_inits: []*ast.Node = undefined;
826 const lhs: union(enum) { dot: ast.TokenIndex, node: *ast.Node } = switch (base.id) {801 const lhs: union(enum) { dot: ast.TokenIndex, node: *ast.Node } = switch (base.tag) {
827 .StructInitializerDot => blk: {802 .StructInitializerDot => blk: {
828 const casted = @fieldParentPtr(ast.Node.StructInitializerDot, "base", base);803 const casted = @fieldParentPtr(ast.Node.StructInitializerDot, "base", base);
829 rtoken = casted.rtoken;804 rtoken = casted.rtoken;
...@@ -877,7 +852,7 @@ fn renderExpression(...@@ -877,7 +852,7 @@ fn renderExpression(
877 if (field_inits.len == 1) blk: {852 if (field_inits.len == 1) blk: {
878 const field_init = field_inits[0].cast(ast.Node.FieldInitializer).?;853 const field_init = field_inits[0].cast(ast.Node.FieldInitializer).?;
879854
880 switch (field_init.expr.id) {855 switch (field_init.expr.tag) {
881 .StructInitializer,856 .StructInitializer,
882 .StructInitializerDot,857 .StructInitializerDot,
883 => break :blk,858 => break :blk,
...@@ -974,7 +949,7 @@ fn renderExpression(...@@ -974,7 +949,7 @@ fn renderExpression(
974949
975 const params = call.params();950 const params = call.params();
976 for (params) |param_node, i| {951 for (params) |param_node, i| {
977 const param_node_new_indent = if (param_node.id == .MultilineStringLiteral) blk: {952 const param_node_new_indent = if (param_node.tag == .MultilineStringLiteral) blk: {
978 break :blk indent;953 break :blk indent;
979 } else blk: {954 } else blk: {
980 try stream.writeByteNTimes(' ', new_indent);955 try stream.writeByteNTimes(' ', new_indent);
...@@ -1284,7 +1259,7 @@ fn renderExpression(...@@ -1284,7 +1259,7 @@ fn renderExpression(
1284 // declarations inside are fields1259 // declarations inside are fields
1285 const src_has_only_fields = blk: {1260 const src_has_only_fields = blk: {
1286 for (fields_and_decls) |decl| {1261 for (fields_and_decls) |decl| {
1287 if (decl.id != .ContainerField) break :blk false;1262 if (decl.tag != .ContainerField) break :blk false;
1288 }1263 }
1289 break :blk true;1264 break :blk true;
1290 };1265 };
...@@ -1831,7 +1806,7 @@ fn renderExpression(...@@ -1831,7 +1806,7 @@ fn renderExpression(
18311806
1832 const rparen = tree.nextToken(for_node.array_expr.lastToken());1807 const rparen = tree.nextToken(for_node.array_expr.lastToken());
18331808
1834 const body_is_block = for_node.body.id == .Block;1809 const body_is_block = for_node.body.tag == .Block;
1835 const src_one_line_to_body = !body_is_block and tree.tokensOnSameLine(rparen, for_node.body.firstToken());1810 const src_one_line_to_body = !body_is_block and tree.tokensOnSameLine(rparen, for_node.body.firstToken());
1836 const body_on_same_line = body_is_block or src_one_line_to_body;1811 const body_on_same_line = body_is_block or src_one_line_to_body;
18371812
...@@ -1874,7 +1849,7 @@ fn renderExpression(...@@ -1874,7 +1849,7 @@ fn renderExpression(
18741849
1875 try renderExpression(allocator, stream, tree, indent, start_col, if_node.condition, Space.None); // condition1850 try renderExpression(allocator, stream, tree, indent, start_col, if_node.condition, Space.None); // condition
18761851
1877 const body_is_if_block = if_node.body.id == .If;1852 const body_is_if_block = if_node.body.tag == .If;
1878 const body_is_block = nodeIsBlock(if_node.body);1853 const body_is_block = nodeIsBlock(if_node.body);
18791854
1880 if (body_is_if_block) {1855 if (body_is_if_block) {
...@@ -1978,7 +1953,7 @@ fn renderExpression(...@@ -1978,7 +1953,7 @@ fn renderExpression(
19781953
1979 const indent_once = indent + indent_delta;1954 const indent_once = indent + indent_delta;
19801955
1981 if (asm_node.template.id == .MultilineStringLiteral) {1956 if (asm_node.template.tag == .MultilineStringLiteral) {
1982 // After rendering a multiline string literal the cursor is1957 // After rendering a multiline string literal the cursor is
1983 // already offset by indent1958 // already offset by indent
1984 try stream.writeByteNTimes(' ', indent_delta);1959 try stream.writeByteNTimes(' ', indent_delta);
...@@ -2245,7 +2220,7 @@ fn renderVarDecl(...@@ -2245,7 +2220,7 @@ fn renderVarDecl(
2245 }2220 }
22462221
2247 if (var_decl.getTrailer("init_node")) |init_node| {2222 if (var_decl.getTrailer("init_node")) |init_node| {
2248 const s = if (init_node.id == .MultilineStringLiteral) Space.None else Space.Space;2223 const s = if (init_node.tag == .MultilineStringLiteral) Space.None else Space.Space;
2249 try renderToken(tree, stream, var_decl.getTrailer("eq_token").?, indent, start_col, s); // =2224 try renderToken(tree, stream, var_decl.getTrailer("eq_token").?, indent, start_col, s); // =
2250 try renderExpression(allocator, stream, tree, indent, start_col, init_node, Space.None);2225 try renderExpression(allocator, stream, tree, indent, start_col, init_node, Space.None);
2251 }2226 }
...@@ -2287,7 +2262,7 @@ fn renderStatement(...@@ -2287,7 +2262,7 @@ fn renderStatement(
2287 start_col: *usize,2262 start_col: *usize,
2288 base: *ast.Node,2263 base: *ast.Node,
2289) (@TypeOf(stream).Error || Error)!void {2264) (@TypeOf(stream).Error || Error)!void {
2290 switch (base.id) {2265 switch (base.tag) {
2291 .VarDecl => {2266 .VarDecl => {
2292 const var_decl = @fieldParentPtr(ast.Node.VarDecl, "base", base);2267 const var_decl = @fieldParentPtr(ast.Node.VarDecl, "base", base);
2293 try renderVarDecl(allocator, stream, tree, indent, start_col, var_decl);2268 try renderVarDecl(allocator, stream, tree, indent, start_col, var_decl);
...@@ -2566,7 +2541,7 @@ fn renderDocCommentsToken(...@@ -2566,7 +2541,7 @@ fn renderDocCommentsToken(
2566}2541}
25672542
2568fn nodeIsBlock(base: *const ast.Node) bool {2543fn nodeIsBlock(base: *const ast.Node) bool {
2569 return switch (base.id) {2544 return switch (base.tag) {
2570 .Block,2545 .Block,
2571 .If,2546 .If,
2572 .For,2547 .For,
src-self-hosted/Module.zig+43-1
...@@ -212,6 +212,7 @@ pub const Decl = struct {...@@ -212,6 +212,7 @@ pub const Decl = struct {
212 },212 },
213 .block => unreachable,213 .block => unreachable,
214 .gen_zir => unreachable,214 .gen_zir => unreachable,
215 .local_var => unreachable,
215 .decl => unreachable,216 .decl => unreachable,
216 }217 }
217 }218 }
...@@ -307,6 +308,7 @@ pub const Scope = struct {...@@ -307,6 +308,7 @@ pub const Scope = struct {
307 .block => return self.cast(Block).?.arena,308 .block => return self.cast(Block).?.arena,
308 .decl => return &self.cast(DeclAnalysis).?.arena.allocator,309 .decl => return &self.cast(DeclAnalysis).?.arena.allocator,
309 .gen_zir => return self.cast(GenZIR).?.arena,310 .gen_zir => return self.cast(GenZIR).?.arena,
311 .local_var => return self.cast(LocalVar).?.gen_zir.arena,
310 .zir_module => return &self.cast(ZIRModule).?.contents.module.arena.allocator,312 .zir_module => return &self.cast(ZIRModule).?.contents.module.arena.allocator,
311 .file => unreachable,313 .file => unreachable,
312 }314 }
...@@ -318,6 +320,7 @@ pub const Scope = struct {...@@ -318,6 +320,7 @@ pub const Scope = struct {
318 return switch (self.tag) {320 return switch (self.tag) {
319 .block => self.cast(Block).?.decl,321 .block => self.cast(Block).?.decl,
320 .gen_zir => self.cast(GenZIR).?.decl,322 .gen_zir => self.cast(GenZIR).?.decl,
323 .local_var => return self.cast(LocalVar).?.gen_zir.decl,
321 .decl => self.cast(DeclAnalysis).?.decl,324 .decl => self.cast(DeclAnalysis).?.decl,
322 .zir_module => null,325 .zir_module => null,
323 .file => null,326 .file => null,
...@@ -330,6 +333,7 @@ pub const Scope = struct {...@@ -330,6 +333,7 @@ pub const Scope = struct {
330 switch (self.tag) {333 switch (self.tag) {
331 .block => return self.cast(Block).?.decl.scope,334 .block => return self.cast(Block).?.decl.scope,
332 .gen_zir => return self.cast(GenZIR).?.decl.scope,335 .gen_zir => return self.cast(GenZIR).?.decl.scope,
336 .local_var => return self.cast(LocalVar).?.gen_zir.decl.scope,
333 .decl => return self.cast(DeclAnalysis).?.decl.scope,337 .decl => return self.cast(DeclAnalysis).?.decl.scope,
334 .zir_module, .file => return self,338 .zir_module, .file => return self,
335 }339 }
...@@ -342,6 +346,7 @@ pub const Scope = struct {...@@ -342,6 +346,7 @@ pub const Scope = struct {
342 switch (self.tag) {346 switch (self.tag) {
343 .block => unreachable,347 .block => unreachable,
344 .gen_zir => unreachable,348 .gen_zir => unreachable,
349 .local_var => unreachable,
345 .decl => unreachable,350 .decl => unreachable,
346 .zir_module => return self.cast(ZIRModule).?.fullyQualifiedNameHash(name),351 .zir_module => return self.cast(ZIRModule).?.fullyQualifiedNameHash(name),
347 .file => return self.cast(File).?.fullyQualifiedNameHash(name),352 .file => return self.cast(File).?.fullyQualifiedNameHash(name),
...@@ -356,9 +361,22 @@ pub const Scope = struct {...@@ -356,9 +361,22 @@ pub const Scope = struct {
356 .decl => return self.cast(DeclAnalysis).?.decl.scope.cast(File).?.contents.tree,361 .decl => return self.cast(DeclAnalysis).?.decl.scope.cast(File).?.contents.tree,
357 .block => return self.cast(Block).?.decl.scope.cast(File).?.contents.tree,362 .block => return self.cast(Block).?.decl.scope.cast(File).?.contents.tree,
358 .gen_zir => return self.cast(GenZIR).?.decl.scope.cast(File).?.contents.tree,363 .gen_zir => return self.cast(GenZIR).?.decl.scope.cast(File).?.contents.tree,
364 .local_var => return self.cast(LocalVar).?.gen_zir.decl.scope.cast(File).?.contents.tree,
359 }365 }
360 }366 }
361367
368 /// Asserts the scope is a child of a `GenZIR` and returns it.
369 pub fn getGenZIR(self: *Scope) *GenZIR {
370 return switch (self.tag) {
371 .block => unreachable,
372 .gen_zir => self.cast(GenZIR).?,
373 .local_var => return self.cast(LocalVar).?.gen_zir,
374 .decl => unreachable,
375 .zir_module => unreachable,
376 .file => unreachable,
377 };
378 }
379
362 pub fn dumpInst(self: *Scope, inst: *Inst) void {380 pub fn dumpInst(self: *Scope, inst: *Inst) void {
363 const zir_module = self.namespace();381 const zir_module = self.namespace();
364 const loc = std.zig.findLineColumn(zir_module.source.bytes, inst.src);382 const loc = std.zig.findLineColumn(zir_module.source.bytes, inst.src);
...@@ -379,6 +397,7 @@ pub const Scope = struct {...@@ -379,6 +397,7 @@ pub const Scope = struct {
379 .zir_module => return @fieldParentPtr(ZIRModule, "base", base).sub_file_path,397 .zir_module => return @fieldParentPtr(ZIRModule, "base", base).sub_file_path,
380 .block => unreachable,398 .block => unreachable,
381 .gen_zir => unreachable,399 .gen_zir => unreachable,
400 .local_var => unreachable,
382 .decl => unreachable,401 .decl => unreachable,
383 }402 }
384 }403 }
...@@ -389,6 +408,7 @@ pub const Scope = struct {...@@ -389,6 +408,7 @@ pub const Scope = struct {
389 .zir_module => return @fieldParentPtr(ZIRModule, "base", base).unload(gpa),408 .zir_module => return @fieldParentPtr(ZIRModule, "base", base).unload(gpa),
390 .block => unreachable,409 .block => unreachable,
391 .gen_zir => unreachable,410 .gen_zir => unreachable,
411 .local_var => unreachable,
392 .decl => unreachable,412 .decl => unreachable,
393 }413 }
394 }414 }
...@@ -398,6 +418,7 @@ pub const Scope = struct {...@@ -398,6 +418,7 @@ pub const Scope = struct {
398 .file => return @fieldParentPtr(File, "base", base).getSource(module),418 .file => return @fieldParentPtr(File, "base", base).getSource(module),
399 .zir_module => return @fieldParentPtr(ZIRModule, "base", base).getSource(module),419 .zir_module => return @fieldParentPtr(ZIRModule, "base", base).getSource(module),
400 .gen_zir => unreachable,420 .gen_zir => unreachable,
421 .local_var => unreachable,
401 .block => unreachable,422 .block => unreachable,
402 .decl => unreachable,423 .decl => unreachable,
403 }424 }
...@@ -410,6 +431,7 @@ pub const Scope = struct {...@@ -410,6 +431,7 @@ pub const Scope = struct {
410 .zir_module => return @fieldParentPtr(ZIRModule, "base", base).removeDecl(child),431 .zir_module => return @fieldParentPtr(ZIRModule, "base", base).removeDecl(child),
411 .block => unreachable,432 .block => unreachable,
412 .gen_zir => unreachable,433 .gen_zir => unreachable,
434 .local_var => unreachable,
413 .decl => unreachable,435 .decl => unreachable,
414 }436 }
415 }437 }
...@@ -429,6 +451,7 @@ pub const Scope = struct {...@@ -429,6 +451,7 @@ pub const Scope = struct {
429 },451 },
430 .block => unreachable,452 .block => unreachable,
431 .gen_zir => unreachable,453 .gen_zir => unreachable,
454 .local_var => unreachable,
432 .decl => unreachable,455 .decl => unreachable,
433 }456 }
434 }457 }
...@@ -449,6 +472,7 @@ pub const Scope = struct {...@@ -449,6 +472,7 @@ pub const Scope = struct {
449 block,472 block,
450 decl,473 decl,
451 gen_zir,474 gen_zir,
475 local_var,
452 };476 };
453477
454 pub const File = struct {478 pub const File = struct {
...@@ -680,6 +704,18 @@ pub const Scope = struct {...@@ -680,6 +704,18 @@ pub const Scope = struct {
680 arena: *Allocator,704 arena: *Allocator,
681 instructions: std.ArrayListUnmanaged(*zir.Inst) = .{},705 instructions: std.ArrayListUnmanaged(*zir.Inst) = .{},
682 };706 };
707
708 /// This structure lives as long as the AST generation of the Block
709 /// node that contains the variable. This struct's parents can be
710 /// other `LocalVar` and finally a `GenZIR` at the top.
711 pub const LocalVar = struct {
712 pub const base_tag: Tag = .local_var;
713 base: Scope = Scope{ .tag = base_tag },
714 gen_zir: *GenZIR,
715 parent: *Scope,
716 name: []const u8,
717 inst: *zir.Inst,
718 };
683};719};
684720
685pub const AllErrors = struct {721pub const AllErrors = struct {
...@@ -1114,7 +1150,7 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {...@@ -1114,7 +1150,7 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {
1114 const file_scope = decl.scope.cast(Scope.File).?;1150 const file_scope = decl.scope.cast(Scope.File).?;
1115 const tree = try self.getAstTree(file_scope);1151 const tree = try self.getAstTree(file_scope);
1116 const ast_node = tree.root_node.decls()[decl.src_index];1152 const ast_node = tree.root_node.decls()[decl.src_index];
1117 switch (ast_node.id) {1153 switch (ast_node.tag) {
1118 .FnProto => {1154 .FnProto => {
1119 const fn_proto = @fieldParentPtr(ast.Node.FnProto, "base", ast_node);1155 const fn_proto = @fieldParentPtr(ast.Node.FnProto, "base", ast_node);
11201156
...@@ -3247,6 +3283,12 @@ fn failWithOwnedErrorMsg(self: *Module, scope: *Scope, src: usize, err_msg: *Err...@@ -3247,6 +3283,12 @@ fn failWithOwnedErrorMsg(self: *Module, scope: *Scope, src: usize, err_msg: *Err
3247 gen_zir.decl.generation = self.generation;3283 gen_zir.decl.generation = self.generation;
3248 self.failed_decls.putAssumeCapacityNoClobber(gen_zir.decl, err_msg);3284 self.failed_decls.putAssumeCapacityNoClobber(gen_zir.decl, err_msg);
3249 },3285 },
3286 .local_var => {
3287 const gen_zir = scope.cast(Scope.LocalVar).?.gen_zir;
3288 gen_zir.decl.analysis = .sema_failure;
3289 gen_zir.decl.generation = self.generation;
3290 self.failed_decls.putAssumeCapacityNoClobber(gen_zir.decl, err_msg);
3291 },
3250 .zir_module => {3292 .zir_module => {
3251 const zir_module = scope.cast(Scope.ZIRModule).?;3293 const zir_module = scope.cast(Scope.ZIRModule).?;
3252 zir_module.status = .loaded_sema_failure;3294 zir_module.status = .loaded_sema_failure;
src-self-hosted/astgen.zig+133-11
...@@ -11,8 +11,11 @@ const trace = @import("tracy.zig").trace;...@@ -11,8 +11,11 @@ const trace = @import("tracy.zig").trace;
11const Scope = Module.Scope;11const Scope = Module.Scope;
12const InnerError = Module.InnerError;12const InnerError = Module.InnerError;
1313
14/// Turn Zig AST into untyped ZIR istructions.
14pub fn expr(mod: *Module, scope: *Scope, ast_node: *ast.Node) InnerError!*zir.Inst {15pub fn expr(mod: *Module, scope: *Scope, ast_node: *ast.Node) InnerError!*zir.Inst {
15 switch (ast_node.id) {16 switch (ast_node.tag) {
17 .VarDecl => unreachable, // Handled in `blockExpr`.
18
16 .Identifier => return identifier(mod, scope, @fieldParentPtr(ast.Node.Identifier, "base", ast_node)),19 .Identifier => return identifier(mod, scope, @fieldParentPtr(ast.Node.Identifier, "base", ast_node)),
17 .Asm => return assembly(mod, scope, @fieldParentPtr(ast.Node.Asm, "base", ast_node)),20 .Asm => return assembly(mod, scope, @fieldParentPtr(ast.Node.Asm, "base", ast_node)),
18 .StringLiteral => return stringLiteral(mod, scope, @fieldParentPtr(ast.Node.StringLiteral, "base", ast_node)),21 .StringLiteral => return stringLiteral(mod, scope, @fieldParentPtr(ast.Node.StringLiteral, "base", ast_node)),
...@@ -23,29 +26,72 @@ pub fn expr(mod: *Module, scope: *Scope, ast_node: *ast.Node) InnerError!*zir.In...@@ -23,29 +26,72 @@ pub fn expr(mod: *Module, scope: *Scope, ast_node: *ast.Node) InnerError!*zir.In
23 .ControlFlowExpression => return controlFlowExpr(mod, scope, @fieldParentPtr(ast.Node.ControlFlowExpression, "base", ast_node)),26 .ControlFlowExpression => return controlFlowExpr(mod, scope, @fieldParentPtr(ast.Node.ControlFlowExpression, "base", ast_node)),
24 .If => return ifExpr(mod, scope, @fieldParentPtr(ast.Node.If, "base", ast_node)),27 .If => return ifExpr(mod, scope, @fieldParentPtr(ast.Node.If, "base", ast_node)),
25 .InfixOp => return infixOp(mod, scope, @fieldParentPtr(ast.Node.InfixOp, "base", ast_node)),28 .InfixOp => return infixOp(mod, scope, @fieldParentPtr(ast.Node.InfixOp, "base", ast_node)),
26 .BoolNot => return boolNot(mod, scope, @fieldParentPtr(ast.Node.BoolNot, "base", ast_node)),29 .BoolNot => return boolNot(mod, scope, @fieldParentPtr(ast.Node.SimplePrefixOp, "base", ast_node)),
27 .VarDecl => return varDecl(mod, scope, @fieldParentPtr(ast.Node.VarDecl, "base", ast_node)),30 else => return mod.failNode(scope, ast_node, "TODO implement astgen.Expr for {}", .{@tagName(ast_node.tag)}),
28 else => return mod.failNode(scope, ast_node, "TODO implement astgen.Expr for {}", .{@tagName(ast_node.id)}),
29 }31 }
30}32}
3133
32pub fn blockExpr(mod: *Module, scope: *Scope, block_node: *ast.Node.Block) !void {34pub fn blockExpr(mod: *Module, parent_scope: *Scope, block_node: *ast.Node.Block) !void {
33 const tracy = trace(@src());35 const tracy = trace(@src());
34 defer tracy.end();36 defer tracy.end();
3537
36 if (block_node.label) |label| {38 if (block_node.label) |label| {
37 return mod.failTok(scope, label, "TODO implement labeled blocks", .{});39 return mod.failTok(parent_scope, label, "TODO implement labeled blocks", .{});
38 }40 }
41
42 var block_arena = std.heap.ArenaAllocator.init(mod.gpa);
43 defer block_arena.deinit();
44
45 var scope = parent_scope;
39 for (block_node.statements()) |statement| {46 for (block_node.statements()) |statement| {
40 _ = try expr(mod, scope, statement);47 switch (statement.tag) {
48 .VarDecl => {
49 const sub_scope = try block_arena.allocator.create(Scope.LocalVar);
50 const var_decl_node = @fieldParentPtr(ast.Node.VarDecl, "base", statement);
51 sub_scope.* = try varDecl(mod, scope, var_decl_node);
52 scope = &sub_scope.base;
53 },
54 else => _ = try expr(mod, scope, statement),
55 }
41 }56 }
42}57}
4358
44fn varDecl(mod: *Module, scope: *Scope, node: *ast.Node.VarDecl) InnerError!*zir.Inst {59fn varDecl(mod: *Module, scope: *Scope, node: *ast.Node.VarDecl) InnerError!Scope.LocalVar {
45 return mod.failNode(scope, &node.base, "TODO implement var decls", .{});60 if (node.getTrailer("comptime_token")) |comptime_token| {
61 return mod.failTok(scope, comptime_token, "TODO implement comptime locals", .{});
62 }
63 if (node.getTrailer("align_node")) |align_node| {
64 return mod.failNode(scope, align_node, "TODO implement alignment on locals", .{});
65 }
66 if (node.getTrailer("type_node")) |type_node| {
67 return mod.failNode(scope, type_node, "TODO implement typed locals", .{});
68 }
69 const tree = scope.tree();
70 switch (tree.token_ids[node.mut_token]) {
71 .Keyword_const => {},
72 .Keyword_var => {
73 return mod.failTok(scope, node.mut_token, "TODO implement mutable locals", .{});
74 },
75 else => unreachable,
76 }
77 // Depending on the type of AST the initialization expression is, we may need an lvalue
78 // or an rvalue as a result location. If it is an rvalue, we can use the instruction as
79 // the variable, no memory location needed.
80 const init_node = node.getTrailer("init_node").?;
81 if (nodeNeedsMemoryLocation(init_node)) {
82 return mod.failNode(scope, init_node, "TODO implement result locations", .{});
83 }
84 const init_inst = try expr(mod, scope, init_node);
85 const ident_name = tree.tokenSlice(node.name_token); // TODO support @"aoeu" identifiers
86 return Scope.LocalVar{
87 .parent = scope,
88 .gen_zir = scope.getGenZIR(),
89 .name = ident_name,
90 .inst = init_inst,
91 };
46}92}
4793
48fn boolNot(mod: *Module, scope: *Scope, node: *ast.Node.BoolNot) InnerError!*zir.Inst {94fn boolNot(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerError!*zir.Inst {
49 const operand = try expr(mod, scope, node.rhs);95 const operand = try expr(mod, scope, node.rhs);
50 const tree = scope.tree();96 const tree = scope.tree();
51 const src = tree.token_locs[node.op_token].start;97 const src = tree.token_locs[node.op_token].start;
...@@ -55,7 +101,7 @@ fn boolNot(mod: *Module, scope: *Scope, node: *ast.Node.BoolNot) InnerError!*zir...@@ -55,7 +101,7 @@ fn boolNot(mod: *Module, scope: *Scope, node: *ast.Node.BoolNot) InnerError!*zir
55fn infixOp(mod: *Module, scope: *Scope, infix_node: *ast.Node.InfixOp) InnerError!*zir.Inst {101fn infixOp(mod: *Module, scope: *Scope, infix_node: *ast.Node.InfixOp) InnerError!*zir.Inst {
56 switch (infix_node.op) {102 switch (infix_node.op) {
57 .Assign => {103 .Assign => {
58 if (infix_node.lhs.id == .Identifier) {104 if (infix_node.lhs.tag == .Identifier) {
59 const ident = @fieldParentPtr(ast.Node.Identifier, "base", infix_node.lhs);105 const ident = @fieldParentPtr(ast.Node.Identifier, "base", infix_node.lhs);
60 const tree = scope.tree();106 const tree = scope.tree();
61 const ident_name = tree.tokenSlice(ident.token);107 const ident_name = tree.tokenSlice(ident.token);
...@@ -474,3 +520,79 @@ fn getSimplePrimitiveValue(name: []const u8) ?TypedValue {...@@ -474,3 +520,79 @@ fn getSimplePrimitiveValue(name: []const u8) ?TypedValue {
474 }520 }
475 return null;521 return null;
476}522}
523
524fn nodeNeedsMemoryLocation(node: *ast.Node) bool {
525 return switch (node.tag) {
526 .Root,
527 .Use,
528 .TestDecl,
529 .DocComment,
530 .SwitchCase,
531 .SwitchElse,
532 .Else,
533 .Payload,
534 .PointerPayload,
535 .PointerIndexPayload,
536 .ContainerField,
537 .ErrorTag,
538 .FieldInitializer,
539 => unreachable,
540
541 .ControlFlowExpression,
542 .BitNot,
543 .BoolNot,
544 .VarDecl,
545 .Defer,
546 .AddressOf,
547 .OptionalType,
548 .Negation,
549 .NegationWrap,
550 .Resume,
551 .ArrayType,
552 .ArrayTypeSentinel,
553 .PtrType,
554 .SliceType,
555 .Suspend,
556 .AnyType,
557 .ErrorType,
558 .FnProto,
559 .AnyFrameType,
560 .IntegerLiteral,
561 .FloatLiteral,
562 .EnumLiteral,
563 .StringLiteral,
564 .MultilineStringLiteral,
565 .CharLiteral,
566 .BoolLiteral,
567 .NullLiteral,
568 .UndefinedLiteral,
569 .Unreachable,
570 .Identifier,
571 .ErrorSetDecl,
572 .ContainerDecl,
573 .Asm,
574 => false,
575
576 .ArrayInitializer,
577 .ArrayInitializerDot,
578 .StructInitializer,
579 .StructInitializerDot,
580 => true,
581
582 .GroupedExpression => nodeNeedsMemoryLocation(node.cast(ast.Node.GroupedExpression).?.expr),
583
584 .InfixOp => @panic("TODO nodeNeedsMemoryLocation for InfixOp"),
585 .Await => @panic("TODO nodeNeedsMemoryLocation for Await"),
586 .Try => @panic("TODO nodeNeedsMemoryLocation for Try"),
587 .If => @panic("TODO nodeNeedsMemoryLocation for If"),
588 .SuffixOp => @panic("TODO nodeNeedsMemoryLocation for SuffixOp"),
589 .Call => @panic("TODO nodeNeedsMemoryLocation for Call"),
590 .Switch => @panic("TODO nodeNeedsMemoryLocation for Switch"),
591 .While => @panic("TODO nodeNeedsMemoryLocation for While"),
592 .For => @panic("TODO nodeNeedsMemoryLocation for For"),
593 .BuiltinCall => @panic("TODO nodeNeedsMemoryLocation for BuiltinCall"),
594 .Comptime => @panic("TODO nodeNeedsMemoryLocation for Comptime"),
595 .Nosuspend => @panic("TODO nodeNeedsMemoryLocation for Nosuspend"),
596 .Block => @panic("TODO nodeNeedsMemoryLocation for Block"),
597 };
598}
src-self-hosted/translate_c.zig+14-13
...@@ -1219,7 +1219,7 @@ fn transStmt(...@@ -1219,7 +1219,7 @@ fn transStmt(
1219 .StringLiteralClass => return transStringLiteral(rp, scope, @ptrCast(*const ZigClangStringLiteral, stmt), result_used),1219 .StringLiteralClass => return transStringLiteral(rp, scope, @ptrCast(*const ZigClangStringLiteral, stmt), result_used),
1220 .ParenExprClass => {1220 .ParenExprClass => {
1221 const expr = try transExpr(rp, scope, ZigClangParenExpr_getSubExpr(@ptrCast(*const ZigClangParenExpr, stmt)), .used, lrvalue);1221 const expr = try transExpr(rp, scope, ZigClangParenExpr_getSubExpr(@ptrCast(*const ZigClangParenExpr, stmt)), .used, lrvalue);
1222 if (expr.id == .GroupedExpression) return maybeSuppressResult(rp, scope, result_used, expr);1222 if (expr.tag == .GroupedExpression) return maybeSuppressResult(rp, scope, result_used, expr);
1223 const node = try rp.c.arena.create(ast.Node.GroupedExpression);1223 const node = try rp.c.arena.create(ast.Node.GroupedExpression);
1224 node.* = .{1224 node.* = .{
1225 .lparen = try appendToken(rp.c, .LParen, "("),1225 .lparen = try appendToken(rp.c, .LParen, "("),
...@@ -1264,7 +1264,7 @@ fn transStmt(...@@ -1264,7 +1264,7 @@ fn transStmt(
1264 .OpaqueValueExprClass => {1264 .OpaqueValueExprClass => {
1265 const source_expr = ZigClangOpaqueValueExpr_getSourceExpr(@ptrCast(*const ZigClangOpaqueValueExpr, stmt)).?;1265 const source_expr = ZigClangOpaqueValueExpr_getSourceExpr(@ptrCast(*const ZigClangOpaqueValueExpr, stmt)).?;
1266 const expr = try transExpr(rp, scope, source_expr, .used, lrvalue);1266 const expr = try transExpr(rp, scope, source_expr, .used, lrvalue);
1267 if (expr.id == .GroupedExpression) return maybeSuppressResult(rp, scope, result_used, expr);1267 if (expr.tag == .GroupedExpression) return maybeSuppressResult(rp, scope, result_used, expr);
1268 const node = try rp.c.arena.create(ast.Node.GroupedExpression);1268 const node = try rp.c.arena.create(ast.Node.GroupedExpression);
1269 node.* = .{1269 node.* = .{
1270 .lparen = try appendToken(rp.c, .LParen, "("),1270 .lparen = try appendToken(rp.c, .LParen, "("),
...@@ -1693,7 +1693,7 @@ fn transBoolExpr(...@@ -1693,7 +1693,7 @@ fn transBoolExpr(
1693 var res = try transExpr(rp, scope, expr, used, lrvalue);1693 var res = try transExpr(rp, scope, expr, used, lrvalue);
16941694
1695 if (isBoolRes(res)) {1695 if (isBoolRes(res)) {
1696 if (!grouped and res.id == .GroupedExpression) {1696 if (!grouped and res.tag == .GroupedExpression) {
1697 const group = @fieldParentPtr(ast.Node.GroupedExpression, "base", res);1697 const group = @fieldParentPtr(ast.Node.GroupedExpression, "base", res);
1698 res = group.expr;1698 res = group.expr;
1699 // get zig fmt to work properly1699 // get zig fmt to work properly
...@@ -1736,7 +1736,7 @@ fn exprIsStringLiteral(expr: *const ZigClangExpr) bool {...@@ -1736,7 +1736,7 @@ fn exprIsStringLiteral(expr: *const ZigClangExpr) bool {
1736}1736}
17371737
1738fn isBoolRes(res: *ast.Node) bool {1738fn isBoolRes(res: *ast.Node) bool {
1739 switch (res.id) {1739 switch (res.tag) {
1740 .InfixOp => switch (@fieldParentPtr(ast.Node.InfixOp, "base", res).op) {1740 .InfixOp => switch (@fieldParentPtr(ast.Node.InfixOp, "base", res).op) {
1741 .BoolOr,1741 .BoolOr,
1742 .BoolAnd,1742 .BoolAnd,
...@@ -4107,12 +4107,13 @@ fn transCreateNodeFieldAccess(c: *Context, container: *ast.Node, field_name: []c...@@ -4107,12 +4107,13 @@ fn transCreateNodeFieldAccess(c: *Context, container: *ast.Node, field_name: []c
41074107
4108fn transCreateNodeSimplePrefixOp(4108fn transCreateNodeSimplePrefixOp(
4109 c: *Context,4109 c: *Context,
4110 comptime tag: ast.Node.Id,4110 comptime tag: ast.Node.Tag,
4111 op_tok_id: std.zig.Token.Id,4111 op_tok_id: std.zig.Token.Id,
4112 bytes: []const u8,4112 bytes: []const u8,
4113) !*ast.Node.SimplePrefixOp(tag) {4113) !*ast.Node.SimplePrefixOp {
4114 const node = try c.arena.create(ast.Node.SimplePrefixOp(tag));4114 const node = try c.arena.create(ast.Node.SimplePrefixOp);
4115 node.* = .{4115 node.* = .{
4116 .base = .{ .tag = tag },
4116 .op_token = try appendToken(c, op_tok_id, bytes),4117 .op_token = try appendToken(c, op_tok_id, bytes),
4117 .rhs = undefined, // translate and set afterward4118 .rhs = undefined, // translate and set afterward
4118 };4119 };
...@@ -5338,10 +5339,10 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8,...@@ -5338,10 +5339,10 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8,
5338 .{@tagName(last.id)},5339 .{@tagName(last.id)},
5339 );5340 );
5340 _ = try appendToken(c, .Semicolon, ";");5341 _ = try appendToken(c, .Semicolon, ";");
5341 const type_of_arg = if (expr.id != .Block) expr else blk: {5342 const type_of_arg = if (expr.tag != .Block) expr else blk: {
5342 const blk = @fieldParentPtr(ast.Node.Block, "base", expr);5343 const blk = @fieldParentPtr(ast.Node.Block, "base", expr);
5343 const blk_last = blk.statements()[blk.statements_len - 1];5344 const blk_last = blk.statements()[blk.statements_len - 1];
5344 std.debug.assert(blk_last.id == .ControlFlowExpression);5345 std.debug.assert(blk_last.tag == .ControlFlowExpression);
5345 const br = @fieldParentPtr(ast.Node.ControlFlowExpression, "base", blk_last);5346 const br = @fieldParentPtr(ast.Node.ControlFlowExpression, "base", blk_last);
5346 break :blk br.rhs.?;5347 break :blk br.rhs.?;
5347 };5348 };
...@@ -5788,7 +5789,7 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,...@@ -5788,7 +5789,7 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
57885789
5789fn macroBoolToInt(c: *Context, node: *ast.Node) !*ast.Node {5790fn macroBoolToInt(c: *Context, node: *ast.Node) !*ast.Node {
5790 if (!isBoolRes(node)) {5791 if (!isBoolRes(node)) {
5791 if (node.id != .InfixOp) return node;5792 if (node.tag != .InfixOp) return node;
57925793
5793 const group_node = try c.arena.create(ast.Node.GroupedExpression);5794 const group_node = try c.arena.create(ast.Node.GroupedExpression);
5794 group_node.* = .{5795 group_node.* = .{
...@@ -5807,7 +5808,7 @@ fn macroBoolToInt(c: *Context, node: *ast.Node) !*ast.Node {...@@ -5807,7 +5808,7 @@ fn macroBoolToInt(c: *Context, node: *ast.Node) !*ast.Node {
58075808
5808fn macroIntToBool(c: *Context, node: *ast.Node) !*ast.Node {5809fn macroIntToBool(c: *Context, node: *ast.Node) !*ast.Node {
5809 if (isBoolRes(node)) {5810 if (isBoolRes(node)) {
5810 if (node.id != .InfixOp) return node;5811 if (node.tag != .InfixOp) return node;
58115812
5812 const group_node = try c.arena.create(ast.Node.GroupedExpression);5813 const group_node = try c.arena.create(ast.Node.GroupedExpression);
5813 group_node.* = .{5814 group_node.* = .{
...@@ -6105,7 +6106,7 @@ fn tokenSlice(c: *Context, token: ast.TokenIndex) []u8 {...@@ -6105,7 +6106,7 @@ fn tokenSlice(c: *Context, token: ast.TokenIndex) []u8 {
6105}6106}
61066107
6107fn getContainer(c: *Context, node: *ast.Node) ?*ast.Node {6108fn getContainer(c: *Context, node: *ast.Node) ?*ast.Node {
6108 switch (node.id) {6109 switch (node.tag) {
6109 .ContainerDecl,6110 .ContainerDecl,
6110 .AddressOf,6111 .AddressOf,
6111 .Await,6112 .Await,
...@@ -6182,7 +6183,7 @@ fn getContainerTypeOf(c: *Context, ref: *ast.Node) ?*ast.Node {...@@ -6182,7 +6183,7 @@ fn getContainerTypeOf(c: *Context, ref: *ast.Node) ?*ast.Node {
6182fn getFnProto(c: *Context, ref: *ast.Node) ?*ast.Node.FnProto {6183fn getFnProto(c: *Context, ref: *ast.Node) ?*ast.Node.FnProto {
6183 const init = if (ref.cast(ast.Node.VarDecl)) |v| v.getTrailer("init_node").? else return null;6184 const init = if (ref.cast(ast.Node.VarDecl)) |v| v.getTrailer("init_node").? else return null;
6184 if (getContainerTypeOf(c, init)) |ty_node| {6185 if (getContainerTypeOf(c, init)) |ty_node| {
6185 if (ty_node.cast(ast.Node.OptionalType)) |prefix| {6186 if (ty_node.castTag(.OptionalType)) |prefix| {
6186 if (prefix.rhs.cast(ast.Node.FnProto)) |fn_proto| {6187 if (prefix.rhs.cast(ast.Node.FnProto)) |fn_proto| {
6187 return fn_proto;6188 return fn_proto;
6188 }6189 }