diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig index 8f2eb6d2c6..ed9f8b79b9 100644 --- a/lib/std/zig/parser_test.zig +++ b/lib/std/zig/parser_test.zig @@ -32,7 +32,7 @@ test "zig fmt: tuple struct" { } test "zig fmt: preserves clobbers in inline asm with stray comma" { - try testCanonical( + try testTransform( \\fn foo() void { \\ asm volatile ("" \\ : [_] "" (-> type), @@ -46,6 +46,20 @@ test "zig fmt: preserves clobbers in inline asm with stray comma" { \\ ); \\} \\ + , + \\fn foo() void { + \\ asm volatile ("" + \\ : [_] "" (-> type), + \\ : + \\ : .{ .clobber = true } + \\ ); + \\ asm volatile ("" + \\ : + \\ : [_] "" (type), + \\ : .{ .clobber = true } + \\ ); + \\} + \\ ); } @@ -64,7 +78,7 @@ test "zig fmt: remove trailing comma at the end of assembly clobber" { \\ asm volatile ("" \\ : [_] "" (-> type), \\ : - \\ : "clobber1", "clobber2" + \\ : .{ .clobber1 = true, .clobber2 = true } \\ ); \\} \\ @@ -628,7 +642,7 @@ test "zig fmt: builtin call with trailing comma" { } test "zig fmt: asm expression with comptime content" { - try testCanonical( + try testTransform( \\comptime { \\ asm ("foo" ++ "bar"); \\} @@ -648,6 +662,26 @@ test "zig fmt: asm expression with comptime content" { \\ ); \\} \\ + , + \\comptime { + \\ asm ("foo" ++ "bar"); + \\} + \\pub fn main() void { + \\ asm volatile ("foo" ++ "bar"); + \\ asm volatile ("foo" ++ "bar" + \\ : [_] "" (x), + \\ ); + \\ asm volatile ("foo" ++ "bar" + \\ : [_] "" (x), + \\ : [_] "" (y), + \\ ); + \\ asm volatile ("foo" ++ "bar" + \\ : [_] "" (x), + \\ : [_] "" (y), + \\ : .{ .h = true, .e = true, .l = true, .l = true, .o = true } + \\ ); + \\} + \\ ); } @@ -2182,7 +2216,7 @@ test "zig fmt: simple asm" { \\ : [a] "x" (-> i32), \\ : [a] "x" (1), \\ ); - \\ asm ("still not real assembly" ::: "a", "b"); + \\ asm ("still not real assembly" ::: .{ .a = true, .b = true }); \\} \\ ); @@ -3907,7 +3941,7 @@ test "zig fmt: fn type" { } test "zig fmt: inline asm" { - try testCanonical( + try testTransform( \\pub fn syscall1(number: usize, arg1: usize) usize { \\ return asm volatile ("syscall" \\ : [ret] "={rax}" (-> usize), @@ -3917,6 +3951,16 @@ test "zig fmt: inline asm" { \\ ); \\} \\ + , + \\pub fn syscall1(number: usize, arg1: usize) usize { + \\ return asm volatile ("syscall" + \\ : [ret] "={rax}" (-> usize), + \\ : [number] "{rax}" (number), + \\ [arg1] "{rdi}" (arg1), + \\ : .{ .rcx = true, .r11 = true } + \\ ); + \\} + \\ ); } @@ -3998,7 +4042,7 @@ test "zig fmt: inline asm parameter alignment" { \\ asm volatile ( \\ \\ foo \\ \\ bar - \\ ::: "", ""); + \\ ::: .{ .a = true, .b = true }); \\ asm volatile ( \\ \\ foo \\ \\ bar @@ -4006,8 +4050,7 @@ test "zig fmt: inline asm parameter alignment" { \\ [_] "" (-> usize), \\ : [_] "" (0), \\ [_] "" (0), - \\ : "", "" - \\ ); + \\ : .{}); \\} \\ ); @@ -5325,7 +5368,7 @@ test "zig fmt: make single-line if no trailing comma, fmt: off" { \\ asm ("not real assembly" \\ :[a] "x" (->i32),:[a] "x" (1),); \\ asm volatile ("still not real assembly" - \\ :::"a","b",); + \\ :::.{.a = true,.b = true,}); \\ } \\} ); @@ -5737,7 +5780,7 @@ test "zig fmt: canonicalize symbols (asm)" { \\ [@"arg1"] "{rdi}" (arg), \\ [arg2] "{rsi}" (arg), \\ [arg3] "{rdx}" (arg), - \\ : "rcx", "r11" + \\ : "rcx", "fn" \\ ); \\ \\ const @"false": usize = 10; @@ -5759,7 +5802,7 @@ test "zig fmt: canonicalize symbols (asm)" { \\ [arg1] "{rdi}" (arg), \\ [arg2] "{rsi}" (arg), \\ [arg3] "{rdx}" (arg), - \\ : "rcx", "r11" + \\ : .{ .rcx = true, .@"fn" = true } \\ ); \\ \\ const @"false": usize = 10; diff --git a/lib/std/zig/render.zig b/lib/std/zig/render.zig index c6391d30b3..2fcc1d7f35 100644 --- a/lib/std/zig/render.zig +++ b/lib/std/zig/render.zig @@ -2398,8 +2398,8 @@ fn renderAsmLegacy( var tok_i = first_clobber; while (true) : (tok_i += 1) { - try ais.writer().writeAll(".@"); - try ais.writer().writeAll(tokenSliceForRender(tree, tok_i)); + try ais.writer().writeByte('.'); + _ = try writeStringLiteralAsIdentifier(r, tok_i); try ais.writer().writeAll(" = true"); tok_i += 1; @@ -2411,6 +2411,7 @@ fn renderAsmLegacy( }, .comma => { if (tree.tokenTag(tok_i + 1) == .r_paren) { + try ais.writer().writeAll(" }"); ais.popIndent(); return renderToken(r, tok_i + 1, space); } else { @@ -2512,11 +2513,10 @@ fn renderAsmLegacy( switch (tree.tokenTag(tok_i + 1)) { .r_paren => { ais.setIndentDelta(indent_delta); - try ais.writer().writeAll(".@"); - const lexeme = tokenSliceForRender(tree, tok_i); - try ais.writer().writeAll(lexeme); + try ais.writer().writeByte('.'); + const lexeme_len = try writeStringLiteralAsIdentifier(r, tok_i); try ais.writer().writeAll(" = true }"); - try renderSpace(r, tok_i, lexeme.len, .newline); + try renderSpace(r, tok_i, lexeme_len, .newline); ais.popIndent(); return renderToken(r, tok_i + 1, space); }, @@ -2524,17 +2524,16 @@ fn renderAsmLegacy( switch (tree.tokenTag(tok_i + 2)) { .r_paren => { ais.setIndentDelta(indent_delta); - try ais.writer().writeAll(".@"); - const lexeme = tokenSliceForRender(tree, tok_i); - try ais.writer().writeAll(lexeme); + try ais.writer().writeByte('.'); + const lexeme_len = try writeStringLiteralAsIdentifier(r, tok_i); try ais.writer().writeAll(" = true }"); - try renderSpace(r, tok_i, lexeme.len, .newline); + try renderSpace(r, tok_i, lexeme_len, .newline); ais.popIndent(); return renderToken(r, tok_i + 2, space); }, else => { - try ais.writer().writeAll(".@"); - try ais.writer().writeAll(tokenSliceForRender(tree, tok_i)); + try ais.writer().writeByte('.'); + _ = try writeStringLiteralAsIdentifier(r, tok_i); try ais.writer().writeAll(" = true"); try renderToken(r, tok_i + 1, .space); tok_i += 2; @@ -3232,6 +3231,22 @@ fn tokenSliceForRender(tree: Ast, token_index: Ast.TokenIndex) []const u8 { return ret; } +fn writeStringLiteralAsIdentifier(r: *Render, token_index: Ast.TokenIndex) !usize { + const tree = r.tree; + const ais = r.ais; + assert(tree.tokenTag(token_index) == .string_literal); + const lexeme = tokenSliceForRender(tree, token_index); + const unquoted = lexeme[1..][0 .. lexeme.len - 2]; + if (std.zig.isValidId(unquoted)) { + try ais.writer().writeAll(unquoted); + return unquoted.len; + } else { + try ais.writer().writeByte('@'); + try ais.writer().writeAll(lexeme); + return lexeme.len + 1; + } +} + fn hasSameLineComment(tree: Ast, token_index: Ast.TokenIndex) bool { const between_source = tree.source[tree.tokenStart(token_index)..tree.tokenStart(token_index + 1)]; for (between_source) |byte| switch (byte) {