commit 9eebba10ea21ace7cabc777ef9f76ea7ad3069eb (tree)
parent 383fe836264ec99e499e8a538d181c5462be0d5d
Author: Motiejus Jakštys <motiejus@jakstys.lt>
Date: Tue, 10 Feb 2026 22:48:38 +0000
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) <noreply@anthropic.com>
Diffstat:
| M | parser.c | | | 11 | ++++++----- |
| M | parser_test.zig | | | 83 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- |
2 files changed, 88 insertions(+), 6 deletions(-)
diff --git 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
@@ -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{