| ... | ... | @@ -164,8 +164,8 @@ pub const Parser = struct { |
| 164 | 164 | WhileContinueExpr: &?&ast.Node, |
| 165 | 165 | Statement: &ast.NodeBlock, |
| 166 | 166 | Semicolon: &const &const ast.Node, |
| 167 | | AsmOutputItems: &ArrayList(ast.NodeAsm.AsmOutput), |
| 168 | | AsmInputItems: &ArrayList(ast.NodeAsm.AsmInput), |
| 167 | AsmOutputItems: &ArrayList(&ast.NodeAsmOutput), |
| 168 | AsmInputItems: &ArrayList(&ast.NodeAsmInput), |
| 169 | 169 | AsmClopperItems: &ArrayList(&ast.NodeStringLiteral), |
| 170 | 170 | ExprListItemOrEnd: ExprListCtx, |
| 171 | 171 | ExprListCommaOrEnd: ExprListCtx, |
| ... | ... | @@ -1510,8 +1510,8 @@ pub const Parser = struct { |
| 1510 | 1510 | .is_volatile = is_volatile, |
| 1511 | 1511 | .template = template, |
| 1512 | 1512 | //.tokens = ArrayList(ast.NodeAsm.AsmToken).init(arena), |
| 1513 | | .outputs = ArrayList(ast.NodeAsm.AsmOutput).init(arena), |
| 1514 | | .inputs = ArrayList(ast.NodeAsm.AsmInput).init(arena), |
| 1513 | .outputs = ArrayList(&ast.NodeAsmOutput).init(arena), |
| 1514 | .inputs = ArrayList(&ast.NodeAsmInput).init(arena), |
| 1515 | 1515 | .cloppers = ArrayList(&ast.NodeStringLiteral).init(arena), |
| 1516 | 1516 | .rparen = undefined, |
| 1517 | 1517 | }; |
| ... | ... | @@ -1679,18 +1679,23 @@ pub const Parser = struct { |
| 1679 | 1679 | _ = (try self.eatToken(&stack, Token.Id.LParen)) ?? continue; |
| 1680 | 1680 | try stack.append(State { .ExpectToken = Token.Id.RParen }); |
| 1681 | 1681 | |
| 1682 | | const res = try items.addOne(); |
| 1683 | | *res = ast.NodeAsm.AsmOutput { |
| 1684 | | .symbolic_name = symbolic_name, |
| 1685 | | .constraint = constraint, |
| 1686 | | .variable_name = null, |
| 1687 | | .return_type = null, |
| 1682 | const node = try arena.create(ast.NodeAsmOutput); |
| 1683 | *node = ast.NodeAsmOutput { |
| 1684 | .base = self.initNode(ast.Node.Id.AsmOutput), |
| 1685 | .symbolic_name = try self.createIdentifier(arena, symbolic_name), |
| 1686 | .constraint = try self.createStringLiteral(arena, constraint), |
| 1687 | .kind = undefined, |
| 1688 | 1688 | }; |
| 1689 | try items.append(node); |
| 1690 | |
| 1689 | 1691 | const symbol_or_arrow = self.getNextToken(); |
| 1690 | 1692 | switch (symbol_or_arrow.id) { |
| 1691 | | Token.Id.Identifier => res.variable_name = symbol_or_arrow, |
| 1693 | Token.Id.Identifier => { |
| 1694 | node.kind = ast.NodeAsmOutput.Kind { .Variable = try self.createIdentifier(arena, symbol_or_arrow) }; |
| 1695 | }, |
| 1692 | 1696 | Token.Id.Arrow => { |
| 1693 | | try stack.append(State { .TypeExprBegin = DestPtr { .NullableField = &res.return_type } }); |
| 1697 | node.kind = ast.NodeAsmOutput.Kind { .Return = undefined }; |
| 1698 | try stack.append(State { .TypeExprBegin = DestPtr { .Field = &node.kind.Return } }); |
| 1694 | 1699 | }, |
| 1695 | 1700 | else => { |
| 1696 | 1701 | try self.parseError(&stack, symbol_or_arrow, "expected '->' or {}, found {}", |
| ... | ... | @@ -1718,13 +1723,15 @@ pub const Parser = struct { |
| 1718 | 1723 | _ = (try self.eatToken(&stack, Token.Id.LParen)) ?? continue; |
| 1719 | 1724 | try stack.append(State { .ExpectToken = Token.Id.RParen }); |
| 1720 | 1725 | |
| 1721 | | const res = try items.addOne(); |
| 1722 | | *res = ast.NodeAsm.AsmInput { |
| 1723 | | .symbolic_name = symbolic_name, |
| 1724 | | .constraint = constraint, |
| 1726 | const node = try arena.create(ast.NodeAsmInput); |
| 1727 | *node = ast.NodeAsmInput { |
| 1728 | .base = self.initNode(ast.Node.Id.AsmInput), |
| 1729 | .symbolic_name = try self.createIdentifier(arena, symbolic_name), |
| 1730 | .constraint = try self.createStringLiteral(arena, constraint), |
| 1725 | 1731 | .expr = undefined, |
| 1726 | 1732 | }; |
| 1727 | | try stack.append(State { .Expression = DestPtr { .Field = &res.expr } }); |
| 1733 | try items.append(node); |
| 1734 | try stack.append(State { .Expression = DestPtr { .Field = &node.expr } }); |
| 1728 | 1735 | }, |
| 1729 | 1736 | |
| 1730 | 1737 | State.AsmClopperItems => |items| { |
| ... | ... | @@ -3803,14 +3810,113 @@ pub const Parser = struct { |
| 3803 | 3810 | |
| 3804 | 3811 | try stream.print("({}", self.tokenizer.getTokenSlice(asm_node.template)); |
| 3805 | 3812 | |
| 3813 | try stack.append(RenderState { .Indent = indent }); |
| 3806 | 3814 | try stack.append(RenderState { .Text = ")" }); |
| 3807 | | @panic("TODO: Render asm"); |
| 3808 | | //\\ return asm volatile ("syscall" |
| 3809 | | //\\ : [ret] "={rax}" (-> usize) |
| 3810 | | //\\ : [number] "{rax}" (number), |
| 3811 | | //\\ [arg1] "{rdi}" (arg1) |
| 3812 | | //\\ : "rcx", "r11"); |
| 3813 | | },, |
| 3815 | { |
| 3816 | const cloppers = asm_node.cloppers.toSliceConst(); |
| 3817 | var i = cloppers.len; |
| 3818 | while (i != 0) { |
| 3819 | i -= 1; |
| 3820 | try stack.append(RenderState { .Expression = &cloppers[i].base }); |
| 3821 | |
| 3822 | if (i != 0) { |
| 3823 | try stack.append(RenderState { .Text = ", " }); |
| 3824 | } |
| 3825 | } |
| 3826 | } |
| 3827 | try stack.append(RenderState { .Text = ": " }); |
| 3828 | try stack.append(RenderState.PrintIndent); |
| 3829 | try stack.append(RenderState { .Indent = indent + indent_delta }); |
| 3830 | try stack.append(RenderState { .Text = "\n" }); |
| 3831 | { |
| 3832 | const inputs = asm_node.inputs.toSliceConst(); |
| 3833 | var i = inputs.len; |
| 3834 | while (i != 0) { |
| 3835 | i -= 1; |
| 3836 | const node = inputs[i]; |
| 3837 | try stack.append(RenderState { .Expression = &node.base}); |
| 3838 | |
| 3839 | if (i != 0) { |
| 3840 | try stack.append(RenderState.PrintIndent); |
| 3841 | try stack.append(RenderState { |
| 3842 | .Text = blk: { |
| 3843 | const prev_node = inputs[i - 1]; |
| 3844 | const loc = self.tokenizer.getTokenLocation(prev_node.lastToken().end, node.firstToken()); |
| 3845 | if (loc.line >= 2) { |
| 3846 | break :blk "\n\n"; |
| 3847 | } |
| 3848 | break :blk "\n"; |
| 3849 | }, |
| 3850 | }); |
| 3851 | try stack.append(RenderState { .Text = "," }); |
| 3852 | } |
| 3853 | } |
| 3854 | } |
| 3855 | try stack.append(RenderState { .Indent = indent + indent_delta + 2}); |
| 3856 | try stack.append(RenderState { .Text = ": "}); |
| 3857 | try stack.append(RenderState.PrintIndent); |
| 3858 | try stack.append(RenderState { .Indent = indent + indent_delta}); |
| 3859 | try stack.append(RenderState { .Text = "\n" }); |
| 3860 | { |
| 3861 | const outputs = asm_node.outputs.toSliceConst(); |
| 3862 | var i = outputs.len; |
| 3863 | while (i != 0) { |
| 3864 | i -= 1; |
| 3865 | const node = outputs[i]; |
| 3866 | try stack.append(RenderState { .Expression = &node.base}); |
| 3867 | |
| 3868 | if (i != 0) { |
| 3869 | try stack.append(RenderState.PrintIndent); |
| 3870 | try stack.append(RenderState { |
| 3871 | .Text = blk: { |
| 3872 | const prev_node = outputs[i - 1]; |
| 3873 | const loc = self.tokenizer.getTokenLocation(prev_node.lastToken().end, node.firstToken()); |
| 3874 | if (loc.line >= 2) { |
| 3875 | break :blk "\n\n"; |
| 3876 | } |
| 3877 | break :blk "\n"; |
| 3878 | }, |
| 3879 | }); |
| 3880 | try stack.append(RenderState { .Text = "," }); |
| 3881 | } |
| 3882 | } |
| 3883 | } |
| 3884 | try stack.append(RenderState { .Indent = indent + indent_delta + 2}); |
| 3885 | try stack.append(RenderState { .Text = ": "}); |
| 3886 | try stack.append(RenderState.PrintIndent); |
| 3887 | try stack.append(RenderState { .Indent = indent + indent_delta}); |
| 3888 | try stack.append(RenderState { .Text = "\n" }); |
| 3889 | }, |
| 3890 | ast.Node.Id.AsmInput => { |
| 3891 | const asm_input = @fieldParentPtr(ast.NodeAsmInput, "base", base); |
| 3892 | |
| 3893 | try stack.append(RenderState { .Text = ")"}); |
| 3894 | try stack.append(RenderState { .Expression = asm_input.expr}); |
| 3895 | try stack.append(RenderState { .Text = " ("}); |
| 3896 | try stack.append(RenderState { .Expression = &asm_input.constraint.base}); |
| 3897 | try stack.append(RenderState { .Text = "] "}); |
| 3898 | try stack.append(RenderState { .Expression = &asm_input.symbolic_name.base}); |
| 3899 | try stack.append(RenderState { .Text = "["}); |
| 3900 | }, |
| 3901 | ast.Node.Id.AsmOutput => { |
| 3902 | const asm_output = @fieldParentPtr(ast.NodeAsmOutput, "base", base); |
| 3903 | |
| 3904 | try stack.append(RenderState { .Text = ")"}); |
| 3905 | switch (asm_output.kind) { |
| 3906 | ast.NodeAsmOutput.Kind.Variable => |variable_name| { |
| 3907 | try stack.append(RenderState { .Expression = &variable_name.base}); |
| 3908 | }, |
| 3909 | ast.NodeAsmOutput.Kind.Return => |return_type| { |
| 3910 | try stack.append(RenderState { .Expression = return_type}); |
| 3911 | try stack.append(RenderState { .Text = "-> "}); |
| 3912 | }, |
| 3913 | } |
| 3914 | try stack.append(RenderState { .Text = " ("}); |
| 3915 | try stack.append(RenderState { .Expression = &asm_output.constraint.base}); |
| 3916 | try stack.append(RenderState { .Text = "] "}); |
| 3917 | try stack.append(RenderState { .Expression = &asm_output.symbolic_name.base}); |
| 3918 | try stack.append(RenderState { .Text = "["}); |
| 3919 | }, |
| 3814 | 3920 | |
| 3815 | 3921 | ast.Node.Id.StructField, |
| 3816 | 3922 | ast.Node.Id.UnionTag, |
| ... | ... | @@ -4672,7 +4778,7 @@ test "zig fmt: inline asm" { |
| 4672 | 4778 | \\ return asm volatile ("syscall" |
| 4673 | 4779 | \\ : [ret] "={rax}" (-> usize) |
| 4674 | 4780 | \\ : [number] "{rax}" (number), |
| 4675 | | \\ [arg1] "{rdi}" (arg1) |
| 4781 | \\ [arg1] "{rdi}" (arg1) |
| 4676 | 4782 | \\ : "rcx", "r11"); |
| 4677 | 4783 | \\} |
| 4678 | 4784 | \\ |