From 9eebba10ea21ace7cabc777ef9f76ea7ad3069eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Motiejus=20Jak=C5=A1tys?= Date: Tue, 10 Feb 2026 22:48:38 +0000 Subject: [PATCH] parser: port remaining asm tests Port tests: - "asm expression with comptime content" - "simple asm" Fix asm_output to handle (identifier) operand without arrow. Fix asm_simple zigData mapping to use node_and_token. Co-Authored-By: Claude Opus 4.6 (1M context) --- parser.c | 11 ++++--- parser_test.zig | 83 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 88 insertions(+), 6 deletions(-) diff --git a/parser.c b/parser.c index 65f8fd648f..a2fd3e3eaa 100644 --- a/parser.c +++ b/parser.c @@ -2046,17 +2046,18 @@ static AstNodeIndex parseAsmOutputItem(Parser* p) { expectToken(p, TOKEN_R_BRACKET); expectToken(p, TOKEN_STRING_LITERAL); expectToken(p, TOKEN_L_PAREN); - AstNodeIndex operand = 0; - if (p->token_tags[p->tok_i] == TOKEN_ARROW) { - p->tok_i++; - operand = parseTypeExpr(p); + AstNodeIndex type_expr = 0; + if (eatToken(p, TOKEN_ARROW) != null_token) { + type_expr = parseTypeExpr(p); + } else { + expectToken(p, TOKEN_IDENTIFIER); } const AstTokenIndex rparen = expectToken(p, TOKEN_R_PAREN); return addNode(&p->nodes, (AstNodeItem) { .tag = AST_NODE_ASM_OUTPUT, .main_token = ident, - .data = { .lhs = operand, .rhs = rparen }, + .data = { .lhs = type_expr, .rhs = rparen }, }); } return null_node; diff --git a/parser_test.zig b/parser_test.zig index 297411536e..1da5422e35 100644 --- a/parser_test.zig +++ b/parser_test.zig @@ -381,6 +381,7 @@ fn zigData(tag: Ast.Node.Tag, lhs: u32, rhs: u32) Ast.Node.Data { // .node_and_token .grouped_expression, .asm_input, + .asm_simple, .field_access, .unwrap_optional, => .{ .node_and_token = .{ toIndex(lhs), rhs } }, @@ -428,7 +429,6 @@ fn zigData(tag: Ast.Node.Tag, lhs: u32, rhs: u32) Ast.Node.Data { .@"for", => .{ .@"for" = .{ toExtraIndex(lhs), @bitCast(rhs) } }, - .asm_simple, .asm_legacy, => .{ .node_and_extra = .{ toIndex(lhs), toExtraIndex(rhs) } }, }; @@ -1133,6 +1133,50 @@ test "zig fmt: builtin call with trailing comma" { ); } +test "zig fmt: asm expression with comptime content" { + try testTransform( + \\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", "e", "l", "l", "o" + \\ ); + \\} + \\ + , + \\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 } + \\ ); + \\} + \\ + ); +} + test "zig fmt: array types last token" { try testCanonical( \\test { @@ -2633,6 +2677,43 @@ test "zig fmt: extra newlines at the end" { ); } +test "zig fmt: simple asm" { + try testTransform( + \\comptime { + \\ asm volatile ( + \\ \\.globl aoeu; + \\ \\.type aoeu, @function; + \\ \\.set aoeu, derp; + \\ ); + \\ + \\ asm ("not real assembly" + \\ :[a] "x" (x),); + \\ asm ("not real assembly" + \\ :[a] "x" (->i32),:[a] "x" (1),); + \\ asm ("still not real assembly" + \\ :::"a","b",); + \\} + , + \\comptime { + \\ asm volatile ( + \\ \\.globl aoeu; + \\ \\.type aoeu, @function; + \\ \\.set aoeu, derp; + \\ ); + \\ + \\ asm ("not real assembly" + \\ : [a] "x" (x), + \\ ); + \\ asm ("not real assembly" + \\ : [a] "x" (-> i32), + \\ : [a] "x" (1), + \\ ); + \\ asm ("still not real assembly" ::: .{ .a = true, .b = true }); + \\} + \\ + ); +} + test "zig fmt: nested struct literal with one item" { try testCanonical( \\const a = foo{