| ... | ... | @@ -2756,8 +2756,47 @@ fn renderAsm( |
| 2756 | 2756 | try renderToken(r, asm_node.ast.asm_token + 1, .none); // lparen |
| 2757 | 2757 | } |
| 2758 | 2758 | |
| 2759 | const render_colons: [3]?Ast.TokenIndex = colons: { |
| 2760 | var colons: [3]Ast.TokenIndex = undefined; |
| 2761 | var render: u2 = 0; |
| 2762 | |
| 2763 | const rparen = asm_node.ast.rparen; |
| 2764 | filled: { |
| 2765 | colons[0] = tree.lastToken(asm_node.ast.template) + 1; |
| 2766 | if (colons[0] == rparen) break :filled; |
| 2767 | |
| 2768 | if (asm_node.outputs.len != 0) { |
| 2769 | colons[1] = tree.lastToken(asm_node.outputs[asm_node.outputs.len - 1]) + 1; |
| 2770 | colons[1] += @intFromBool(tree.tokenTag(colons[1]) == .comma); |
| 2771 | render = 1; |
| 2772 | } else { |
| 2773 | colons[1] = colons[0] + 1; |
| 2774 | if (hasComment(tree, colons[0], colons[1])) render = 1; |
| 2775 | } |
| 2776 | if (colons[1] == rparen) break :filled; |
| 2777 | |
| 2778 | // Next colon is not checked for here since it cannot present without clobbers |
| 2779 | if (asm_node.inputs.len != 0) { |
| 2780 | render = 2; |
| 2781 | } else { |
| 2782 | const colon_or_rparen = colons[1] + 1; |
| 2783 | if (hasComment(tree, colons[1], colon_or_rparen)) render = 2; |
| 2784 | } |
| 2785 | |
| 2786 | if (asm_node.ast.clobbers.unwrap()) |clobbers| { |
| 2787 | colons[2] = tree.firstToken(clobbers) - 1; |
| 2788 | render = 3; |
| 2789 | } |
| 2790 | } |
| 2791 | |
| 2792 | var opt_colons: [3]?Ast.TokenIndex = @splat(null); |
| 2793 | for (0..render) |i| opt_colons[i] = colons[i]; |
| 2794 | break :colons opt_colons; |
| 2795 | }; |
| 2796 | |
| 2797 | try ais.forcePushIndent(.normal); |
| 2798 | |
| 2759 | 2799 | if (asm_node.ast.items.len == 0) { |
| 2760 | | try ais.forcePushIndent(.normal); |
| 2761 | 2800 | if (asm_node.ast.clobbers.unwrap()) |clobbers| { |
| 2762 | 2801 | // asm ("foo" ::: clobbers) |
| 2763 | 2802 | try renderExpression(r, asm_node.ast.template, .space); |
| ... | ... | @@ -2771,13 +2810,14 @@ fn renderAsm( |
| 2771 | 2810 | return renderToken(r, asm_node.ast.rparen, space); // rparen |
| 2772 | 2811 | } |
| 2773 | 2812 | |
| 2774 | | // asm ("foo") |
| 2775 | | try renderExpression(r, asm_node.ast.template, .none); |
| 2776 | | ais.popIndent(); |
| 2777 | | return renderToken(r, asm_node.ast.rparen, space); // rparen |
| 2813 | if (render_colons[0] == null) { |
| 2814 | // asm ("foo") |
| 2815 | try renderExpression(r, asm_node.ast.template, .none); |
| 2816 | ais.popIndent(); |
| 2817 | return renderToken(r, asm_node.ast.rparen, space); // rparen |
| 2818 | } |
| 2778 | 2819 | } |
| 2779 | 2820 | |
| 2780 | | try ais.forcePushIndent(.normal); |
| 2781 | 2821 | try renderExpression(r, asm_node.ast.template, .newline); |
| 2782 | 2822 | ais.forceLastIndent(); // Might have been dedented by a multiline string literal |
| 2783 | 2823 | assert(ais.current_line_empty); |
| ... | ... | @@ -2785,86 +2825,62 @@ fn renderAsm( |
| 2785 | 2825 | const prev_indent_delta = ais.indent_delta; // May be part of another asm expression |
| 2786 | 2826 | // so indent_delta can't be unconditionally used |
| 2787 | 2827 | ais.setIndentDelta(asm_indent_delta); |
| 2788 | | const colon1 = tree.lastToken(asm_node.ast.template) + 1; |
| 2789 | 2828 | |
| 2790 | | const colon2 = if (asm_node.outputs.len == 0) colon2: { |
| 2791 | | try renderToken(r, colon1, .newline); // : |
| 2792 | | break :colon2 colon1 + 1; |
| 2793 | | } else colon2: { |
| 2794 | | try renderToken(r, colon1, .space); // : |
| 2829 | rendered: { |
| 2830 | if (render_colons[0]) |colon1| { |
| 2831 | if (asm_node.outputs.len != 0) { |
| 2832 | try renderToken(r, colon1, .space); |
| 2833 | try ais.forcePushIndent(.normal); |
| 2795 | 2834 | |
| 2796 | | try ais.forcePushIndent(.normal); |
| 2797 | | for (asm_node.outputs, 0..) |asm_output, i| { |
| 2798 | | if (i + 1 < asm_node.outputs.len) { |
| 2799 | | const next_asm_output = asm_node.outputs[i + 1]; |
| 2800 | | try renderAsmOutput(r, asm_output, .none); |
| 2835 | const final = asm_node.outputs.len - 1; |
| 2836 | for (asm_node.outputs[0..final], 0..) |asm_output, i| { |
| 2837 | try renderAsmOutput(r, asm_output, .none); |
| 2838 | |
| 2839 | const next_start = tree.firstToken(asm_node.outputs[i + 1]); |
| 2840 | try renderToken(r, next_start - 1, .newline); // , |
| 2841 | try renderExtraNewlineToken(r, next_start); |
| 2842 | } |
| 2801 | 2843 | |
| 2802 | | const comma = tree.firstToken(next_asm_output) - 1; |
| 2803 | | try renderToken(r, comma, .newline); // , |
| 2804 | | try renderExtraNewlineToken(r, tree.firstToken(next_asm_output)); |
| 2805 | | } else if (asm_node.inputs.len == 0 and asm_node.ast.clobbers == .none) { |
| 2806 | 2844 | try ais.pushSpace(.comma); |
| 2807 | | try renderAsmOutput(r, asm_output, .comma); |
| 2845 | try renderAsmOutput(r, asm_node.outputs[final], .comma); |
| 2808 | 2846 | ais.popSpace(); |
| 2809 | 2847 | ais.popIndent(); |
| 2810 | | ais.setIndentDelta(indent_delta); |
| 2811 | | ais.popIndent(); |
| 2812 | | return renderToken(r, asm_node.ast.rparen, space); // rparen |
| 2813 | 2848 | } else { |
| 2814 | | try ais.pushSpace(.comma); |
| 2815 | | try renderAsmOutput(r, asm_output, .comma); |
| 2816 | | ais.popSpace(); |
| 2817 | | const comma_or_colon = tree.lastToken(asm_output) + 1; |
| 2818 | | ais.popIndent(); |
| 2819 | | break :colon2 switch (tree.tokenTag(comma_or_colon)) { |
| 2820 | | .comma => comma_or_colon + 1, |
| 2821 | | else => comma_or_colon, |
| 2822 | | }; |
| 2849 | try renderToken(r, colon1, .newline); |
| 2823 | 2850 | } |
| 2824 | 2851 | } else unreachable; |
| 2825 | | }; |
| 2826 | 2852 | |
| 2827 | | const colon3 = if (asm_node.inputs.len == 0) colon3: { |
| 2828 | | try renderToken(r, colon2, .newline); // : |
| 2829 | | break :colon3 colon2 + 1; |
| 2830 | | } else colon3: { |
| 2831 | | try renderToken(r, colon2, .space); // : |
| 2832 | | try ais.forcePushIndent(.normal); |
| 2833 | | for (asm_node.inputs, 0..) |asm_input, i| { |
| 2834 | | if (i + 1 < asm_node.inputs.len) { |
| 2835 | | const next_asm_input = asm_node.inputs[i + 1]; |
| 2836 | | try renderAsmInput(r, asm_input, .none); |
| 2837 | | |
| 2838 | | const first_token = tree.firstToken(next_asm_input); |
| 2839 | | try renderToken(r, first_token - 1, .newline); // , |
| 2840 | | try renderExtraNewlineToken(r, first_token); |
| 2841 | | } else if (asm_node.ast.clobbers == .none) { |
| 2853 | if (render_colons[1]) |colon2| { |
| 2854 | if (asm_node.inputs.len != 0) { |
| 2855 | try renderToken(r, colon2, .space); |
| 2856 | try ais.forcePushIndent(.normal); |
| 2857 | |
| 2858 | const final = asm_node.inputs.len - 1; |
| 2859 | for (asm_node.inputs[0..final], 0..) |asm_input, i| { |
| 2860 | try renderAsmInput(r, asm_input, .none); |
| 2861 | |
| 2862 | const next_start = tree.firstToken(asm_node.inputs[i + 1]); |
| 2863 | try renderToken(r, next_start - 1, .newline); // , |
| 2864 | try renderExtraNewlineToken(r, next_start); |
| 2865 | } |
| 2866 | |
| 2842 | 2867 | try ais.pushSpace(.comma); |
| 2843 | | try renderAsmInput(r, asm_input, .comma); |
| 2868 | try renderAsmInput(r, asm_node.inputs[final], .comma); |
| 2844 | 2869 | ais.popSpace(); |
| 2845 | 2870 | ais.popIndent(); |
| 2846 | | ais.setIndentDelta(indent_delta); |
| 2847 | | ais.popIndent(); |
| 2848 | | return renderToken(r, asm_node.ast.rparen, space); // rparen |
| 2849 | 2871 | } else { |
| 2850 | | try ais.pushSpace(.comma); |
| 2851 | | try renderAsmInput(r, asm_input, .comma); |
| 2852 | | ais.popSpace(); |
| 2853 | | const comma_or_colon = tree.lastToken(asm_input) + 1; |
| 2854 | | ais.popIndent(); |
| 2855 | | break :colon3 switch (tree.tokenTag(comma_or_colon)) { |
| 2856 | | .comma => comma_or_colon + 1, |
| 2857 | | else => comma_or_colon, |
| 2858 | | }; |
| 2872 | try renderToken(r, colon2, .newline); |
| 2859 | 2873 | } |
| 2874 | } else break :rendered; |
| 2875 | |
| 2876 | if (render_colons[2]) |colon3| { |
| 2877 | const clobbers = asm_node.ast.clobbers.unwrap().?; |
| 2878 | try renderToken(r, colon3, .maybe_space); |
| 2879 | try renderExpression(r, clobbers, .none); |
| 2880 | ais.forceLastIndent(); // Might have been dedented by a multiline string literal |
| 2860 | 2881 | } |
| 2861 | | unreachable; |
| 2862 | | }; |
| 2882 | } |
| 2863 | 2883 | |
| 2864 | | try renderToken(r, colon3, .maybe_space); // : |
| 2865 | | const clobbers = asm_node.ast.clobbers.unwrap().?; |
| 2866 | | try renderExpression(r, clobbers, .none); |
| 2867 | | ais.forceLastIndent(); // Might have been dedented by a multiline string literal |
| 2868 | 2884 | ais.setIndentDelta(prev_indent_delta); |
| 2869 | 2885 | ais.popIndent(); |
| 2870 | 2886 | return renderToken(r, asm_node.ast.rparen, space); // rparen |