| ... | ... | @@ -766,6 +766,101 @@ pub const Parser = struct { |
| 766 | 766 | dest_ptr.store(&resume_node.base); |
| 767 | 767 | stack.append(State { .Expression = DestPtr { .Field = &resume_node.rhs } }) catch unreachable; |
| 768 | 768 | }, |
| 769 | Token.Id.Keyword_suspend => { |
| 770 | const node = try arena.create(ast.NodeSuspend); |
| 771 | *node = ast.NodeSuspend { |
| 772 | .base = self.initNode(ast.Node.Id.Suspend), |
| 773 | .suspend_token = token, |
| 774 | .payload = null, |
| 775 | .body = null, |
| 776 | }; |
| 777 | dest_ptr.store(&node.base); |
| 778 | stack.append(State { .SuspendBody = node }) catch unreachable; |
| 779 | try stack.append(State { .Payload = &node.payload }); |
| 780 | continue; |
| 781 | }, |
| 782 | Token.Id.Keyword_if => { |
| 783 | const node = try arena.create(ast.NodeIf); |
| 784 | *node = ast.NodeIf { |
| 785 | .base = self.initNode(ast.Node.Id.If), |
| 786 | .if_token = token, |
| 787 | .condition = undefined, |
| 788 | .payload = null, |
| 789 | .body = undefined, |
| 790 | .@"else" = null, |
| 791 | }; |
| 792 | dest_ptr.store(&node.base); |
| 793 | |
| 794 | stack.append(State { .Else = &node.@"else" }) catch unreachable; |
| 795 | try stack.append(State { .Expression = DestPtr { .Field = &node.body } }); |
| 796 | try stack.append(State { .PointerPayload = &node.payload }); |
| 797 | try stack.append(State { .ExpectToken = Token.Id.RParen }); |
| 798 | try stack.append(State { .Expression = DestPtr { .Field = &node.condition } }); |
| 799 | try stack.append(State { .ExpectToken = Token.Id.LParen }); |
| 800 | continue; |
| 801 | }, |
| 802 | Token.Id.Keyword_while => { |
| 803 | stack.append(State { |
| 804 | .While = LoopCtx { |
| 805 | .label = null, |
| 806 | .inline_token = null, |
| 807 | .loop_token = token, |
| 808 | .dest_ptr = dest_ptr, |
| 809 | } |
| 810 | }) catch unreachable; |
| 811 | continue; |
| 812 | }, |
| 813 | Token.Id.Keyword_for => { |
| 814 | stack.append(State { |
| 815 | .For = LoopCtx { |
| 816 | .label = null, |
| 817 | .inline_token = null, |
| 818 | .loop_token = token, |
| 819 | .dest_ptr = dest_ptr, |
| 820 | } |
| 821 | }) catch unreachable; |
| 822 | continue; |
| 823 | }, |
| 824 | Token.Id.Keyword_switch => { |
| 825 | const node = try arena.create(ast.NodeSwitch); |
| 826 | *node = ast.NodeSwitch { |
| 827 | .base = self.initNode(ast.Node.Id.Switch), |
| 828 | .switch_token = token, |
| 829 | .expr = undefined, |
| 830 | .cases = ArrayList(&ast.NodeSwitchCase).init(arena), |
| 831 | .rbrace = undefined, |
| 832 | }; |
| 833 | dest_ptr.store(&node.base); |
| 834 | |
| 835 | stack.append(State { |
| 836 | .SwitchCaseOrEnd = ListSave(&ast.NodeSwitchCase) { |
| 837 | .list = &node.cases, |
| 838 | .ptr = &node.rbrace, |
| 839 | }, |
| 840 | }) catch unreachable; |
| 841 | try stack.append(State { .ExpectToken = Token.Id.LBrace }); |
| 842 | try stack.append(State { .ExpectToken = Token.Id.RParen }); |
| 843 | try stack.append(State { .Expression = DestPtr { .Field = &node.expr } }); |
| 844 | try stack.append(State { .ExpectToken = Token.Id.LParen }); |
| 845 | }, |
| 846 | Token.Id.Keyword_comptime => { |
| 847 | const node = try arena.create(ast.NodeComptime); |
| 848 | *node = ast.NodeComptime { |
| 849 | .base = self.initNode(ast.Node.Id.Comptime), |
| 850 | .comptime_token = token, |
| 851 | .expr = undefined, |
| 852 | }; |
| 853 | dest_ptr.store(&node.base); |
| 854 | try stack.append(State { .Expression = DestPtr { .Field = &node.expr } }); |
| 855 | continue; |
| 856 | }, |
| 857 | Token.Id.LBrace => { |
| 858 | const block = try self.createBlock(arena, (?Token)(null), token); |
| 859 | dest_ptr.store(&block.base); |
| 860 | |
| 861 | stack.append(State { .Block = block }) catch unreachable; |
| 862 | continue; |
| 863 | }, |
| 769 | 864 | else => { |
| 770 | 865 | self.putBackToken(token); |
| 771 | 866 | stack.append(State { .UnwrapExpressionBegin = dest_ptr }) catch unreachable; |
| ... | ... | @@ -1328,19 +1423,6 @@ pub const Parser = struct { |
| 1328 | 1423 | dest_ptr.store(&node.base); |
| 1329 | 1424 | continue; |
| 1330 | 1425 | }, |
| 1331 | | Token.Id.Keyword_suspend => { |
| 1332 | | const node = try arena.create(ast.NodeSuspend); |
| 1333 | | *node = ast.NodeSuspend { |
| 1334 | | .base = self.initNode(ast.Node.Id.Suspend), |
| 1335 | | .suspend_token = token, |
| 1336 | | .payload = null, |
| 1337 | | .body = null, |
| 1338 | | }; |
| 1339 | | dest_ptr.store(&node.base); |
| 1340 | | stack.append(State { .SuspendBody = node }) catch unreachable; |
| 1341 | | try stack.append(State { .Payload = &node.payload }); |
| 1342 | | continue; |
| 1343 | | }, |
| 1344 | 1426 | Token.Id.MultilineStringLiteralLine => { |
| 1345 | 1427 | const node = try arena.create(ast.NodeMultilineStringLiteral); |
| 1346 | 1428 | *node = ast.NodeMultilineStringLiteral { |
| ... | ... | @@ -1544,13 +1626,6 @@ pub const Parser = struct { |
| 1544 | 1626 | }) catch unreachable; |
| 1545 | 1627 | continue; |
| 1546 | 1628 | }, |
| 1547 | | Token.Id.LBrace => { |
| 1548 | | const block = try self.createBlock(arena, (?Token)(null), token); |
| 1549 | | dest_ptr.store(&block.base); |
| 1550 | | |
| 1551 | | stack.append(State { .Block = block }) catch unreachable; |
| 1552 | | continue; |
| 1553 | | }, |
| 1554 | 1629 | Token.Id.Keyword_fn => { |
| 1555 | 1630 | // TODO shouldn't need these casts |
| 1556 | 1631 | const fn_proto = try self.createFnProto(arena, token, |
| ... | ... | @@ -1608,26 +1683,6 @@ pub const Parser = struct { |
| 1608 | 1683 | try stack.append(State { .AsmOutputItems = &node.outputs }); |
| 1609 | 1684 | try stack.append(State { .IfToken = Token.Id.Colon }); |
| 1610 | 1685 | }, |
| 1611 | | Token.Id.Keyword_if => { |
| 1612 | | const node = try arena.create(ast.NodeIf); |
| 1613 | | *node = ast.NodeIf { |
| 1614 | | .base = self.initNode(ast.Node.Id.If), |
| 1615 | | .if_token = token, |
| 1616 | | .condition = undefined, |
| 1617 | | .payload = null, |
| 1618 | | .body = undefined, |
| 1619 | | .@"else" = null, |
| 1620 | | }; |
| 1621 | | dest_ptr.store(&node.base); |
| 1622 | | |
| 1623 | | stack.append(State { .Else = &node.@"else" }) catch unreachable; |
| 1624 | | try stack.append(State { .Expression = DestPtr { .Field = &node.body } }); |
| 1625 | | try stack.append(State { .PointerPayload = &node.payload }); |
| 1626 | | try stack.append(State { .ExpectToken = Token.Id.RParen }); |
| 1627 | | try stack.append(State { .Expression = DestPtr { .Field = &node.condition } }); |
| 1628 | | try stack.append(State { .ExpectToken = Token.Id.LParen }); |
| 1629 | | continue; |
| 1630 | | }, |
| 1631 | 1686 | Token.Id.Keyword_inline => { |
| 1632 | 1687 | stack.append(State { |
| 1633 | 1688 | .Inline = InlineCtx { |
| ... | ... | @@ -1638,61 +1693,6 @@ pub const Parser = struct { |
| 1638 | 1693 | }) catch unreachable; |
| 1639 | 1694 | continue; |
| 1640 | 1695 | }, |
| 1641 | | Token.Id.Keyword_while => { |
| 1642 | | stack.append(State { |
| 1643 | | .While = LoopCtx { |
| 1644 | | .label = null, |
| 1645 | | .inline_token = null, |
| 1646 | | .loop_token = token, |
| 1647 | | .dest_ptr = dest_ptr, |
| 1648 | | } |
| 1649 | | }) catch unreachable; |
| 1650 | | continue; |
| 1651 | | }, |
| 1652 | | Token.Id.Keyword_for => { |
| 1653 | | stack.append(State { |
| 1654 | | .For = LoopCtx { |
| 1655 | | .label = null, |
| 1656 | | .inline_token = null, |
| 1657 | | .loop_token = token, |
| 1658 | | .dest_ptr = dest_ptr, |
| 1659 | | } |
| 1660 | | }) catch unreachable; |
| 1661 | | continue; |
| 1662 | | }, |
| 1663 | | Token.Id.Keyword_switch => { |
| 1664 | | const node = try arena.create(ast.NodeSwitch); |
| 1665 | | *node = ast.NodeSwitch { |
| 1666 | | .base = self.initNode(ast.Node.Id.Switch), |
| 1667 | | .switch_token = token, |
| 1668 | | .expr = undefined, |
| 1669 | | .cases = ArrayList(&ast.NodeSwitchCase).init(arena), |
| 1670 | | .rbrace = undefined, |
| 1671 | | }; |
| 1672 | | dest_ptr.store(&node.base); |
| 1673 | | |
| 1674 | | stack.append(State { |
| 1675 | | .SwitchCaseOrEnd = ListSave(&ast.NodeSwitchCase) { |
| 1676 | | .list = &node.cases, |
| 1677 | | .ptr = &node.rbrace, |
| 1678 | | }, |
| 1679 | | }) catch unreachable; |
| 1680 | | try stack.append(State { .ExpectToken = Token.Id.LBrace }); |
| 1681 | | try stack.append(State { .ExpectToken = Token.Id.RParen }); |
| 1682 | | try stack.append(State { .Expression = DestPtr { .Field = &node.expr } }); |
| 1683 | | try stack.append(State { .ExpectToken = Token.Id.LParen }); |
| 1684 | | }, |
| 1685 | | Token.Id.Keyword_comptime => { |
| 1686 | | const node = try arena.create(ast.NodeComptime); |
| 1687 | | *node = ast.NodeComptime { |
| 1688 | | .base = self.initNode(ast.Node.Id.Comptime), |
| 1689 | | .comptime_token = token, |
| 1690 | | .expr = undefined, |
| 1691 | | }; |
| 1692 | | dest_ptr.store(&node.base); |
| 1693 | | try stack.append(State { .Expression = DestPtr { .Field = &node.expr } }); |
| 1694 | | continue; |
| 1695 | | }, |
| 1696 | 1696 | else => { |
| 1697 | 1697 | try self.parseError(&stack, token, "expected primary expression, found {}", @tagName(token.id)); |
| 1698 | 1698 | continue; |
| ... | ... | @@ -4966,11 +4966,37 @@ test "zig fmt: coroutines" { |
| 4966 | 4966 | ); |
| 4967 | 4967 | } |
| 4968 | 4968 | |
| 4969 | | //{ |
| 4970 | | // var it = self.link_libs.iterator(); |
| 4971 | | // while (true) { |
| 4972 | | // const entry = it.next() ?? break; |
| 4973 | | // zig_args.append("--library") catch unreachable; |
| 4974 | | // zig_args.append(entry.key) catch unreachable; |
| 4975 | | // } |
| 4976 | | //} |
| 4969 | test "zig fmt: coroutines" { |
| 4970 | try testCanonical( |
| 4971 | \\async fn simpleAsyncFn() void { |
| 4972 | \\ x += 1; |
| 4973 | \\ suspend; |
| 4974 | \\ x += 1; |
| 4975 | \\ suspend |p| {} |
| 4976 | \\ const p = async simpleAsyncFn() catch unreachable; |
| 4977 | \\ await p; |
| 4978 | \\} |
| 4979 | \\ |
| 4980 | \\test "coroutine suspend, resume, cancel" { |
| 4981 | \\ const p = try async<std.debug.global_allocator> testAsyncSeq(); |
| 4982 | \\ resume p; |
| 4983 | \\ cancel p; |
| 4984 | \\} |
| 4985 | \\ |
| 4986 | ); |
| 4987 | } |
| 4988 | |
| 4989 | test "zig fmt: Block after if" { |
| 4990 | try testCanonical( |
| 4991 | \\test "Block after if" { |
| 4992 | \\ if (true) { |
| 4993 | \\ const a = 0; |
| 4994 | \\ } |
| 4995 | \\ |
| 4996 | \\ { |
| 4997 | \\ const a = 0; |
| 4998 | \\ } |
| 4999 | \\} |
| 5000 | \\ |
| 5001 | ); |
| 5002 | } |