commit cc6ddf4975b15ebc6a43863f70a9fc10ceed6891 (tree)
parent d32b8ac30f30ab61af8112445c02fa70ce14601e
Author: Motiejus Jakštys <motiejus.jakstys@chronosphere.io>
Date: Wed, 11 Feb 2026 05:15:57 +0000
parser: port asm, comment, doc comment tests
Port tests:
- "inline asm"
- "inline asm parameter alignment"
- "multiline string in array"
- "file ends with struct field"
- "line comment in array"
- "comment in array initializer/access"
- "comments at several places in struct init"
- "remove newlines surrounding doc comment"
- "remove newlines surrounding doc comment between members"
- "fix single statement if/for/while line breaks"
- "fn type"
- "nosuspend"
- "Block after if"
- "string identifier"
- "error return"
Add if/switch support in parsePrimaryTypeExpr.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Diffstat:
| M | parser.c | | | 5 | ++--- |
| M | parser_test.zig | | | 225 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
2 files changed, 227 insertions(+), 3 deletions(-)
diff --git a/parser.c b/parser.c
@@ -40,6 +40,7 @@ static void parsePayload(Parser*);
static AstNodeIndex parseSwitchExpr(Parser*);
static AstNodeIndex parseForExpr(Parser*);
static AstNodeIndex parseAsmExpr(Parser*);
+static AstNodeIndex parseIfExpr(Parser*);
typedef struct {
enum { FIELD_STATE_NONE, FIELD_STATE_SEEN, FIELD_STATE_END } tag;
@@ -477,9 +478,7 @@ static AstNodeIndex parsePrimaryTypeExpr(Parser* p) {
case TOKEN_KEYWORD_FN:
return parseFnProto(p);
case TOKEN_KEYWORD_IF:
- fprintf(stderr, "parsePrimaryTypeExpr does not support %s\n",
- tokenizerGetTagString(tok));
- exit(1);
+ return parseIfExpr(p);
case TOKEN_KEYWORD_SWITCH:
return parseSwitchExpr(p);
case TOKEN_KEYWORD_EXTERN:
diff --git a/parser_test.zig b/parser_test.zig
@@ -4344,6 +4344,231 @@ test "zig fmt: error return" {
);
}
+test "zig fmt: inline asm" {
+ try testTransform(
+ \\pub fn syscall1(number: usize, arg1: usize) usize {
+ \\ return asm volatile ("syscall"
+ \\ : [ret] "={rax}" (-> usize),
+ \\ : [number] "{rax}" (number),
+ \\ [arg1] "{rdi}" (arg1),
+ \\ : "rcx", "r11"
+ \\ );
+ \\}
+ \\
+ ,
+ \\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 }
+ \\ );
+ \\}
+ \\
+ );
+}
+
+test "zig fmt: inline asm parameter alignment" {
+ try testCanonical(
+ \\pub fn main() void {
+ \\ asm volatile (
+ \\ \\ foo
+ \\ \\ bar
+ \\ );
+ \\ asm volatile (
+ \\ \\ foo
+ \\ \\ bar
+ \\ : [_] "" (-> usize),
+ \\ [_] "" (-> usize),
+ \\ );
+ \\ asm volatile (
+ \\ \\ foo
+ \\ \\ bar
+ \\ :
+ \\ : [_] "" (0),
+ \\ [_] "" (0),
+ \\ );
+ \\ asm volatile (
+ \\ \\ foo
+ \\ \\ bar
+ \\ ::: .{ .a = true, .b = true });
+ \\ asm volatile (
+ \\ \\ foo
+ \\ \\ bar
+ \\ : [_] "" (-> usize),
+ \\ [_] "" (-> usize),
+ \\ : [_] "" (0),
+ \\ [_] "" (0),
+ \\ : .{});
+ \\}
+ \\
+ );
+}
+
+test "zig fmt: multiline string in array" {
+ try testCanonical(
+ \\const Foo = [][]const u8{
+ \\ \\aaa
+ \\ ,
+ \\ \\bbb
+ \\};
+ \\
+ \\fn bar() void {
+ \\ const Foo = [][]const u8{
+ \\ \\aaa
+ \\ ,
+ \\ \\bbb
+ \\ };
+ \\ const Bar = [][]const u8{ // comment here
+ \\ \\aaa
+ \\ \\
+ \\ , // and another comment can go here
+ \\ \\bbb
+ \\ };
+ \\}
+ \\
+ );
+}
+
+
+test "zig fmt: file ends with struct field" {
+ try testCanonical(
+ \\a: bool
+ \\
+ );
+}
+
+test "zig fmt: line comment in array" {
+ try testTransform(
+ \\test "a" {
+ \\ var arr = [_]u32{
+ \\ 0
+ \\ // 1,
+ \\ // 2,
+ \\ };
+ \\}
+ \\
+ ,
+ \\test "a" {
+ \\ var arr = [_]u32{
+ \\ 0,
+ \\ // 1,
+ \\ // 2,
+ \\ };
+ \\}
+ \\
+ );
+ try testCanonical(
+ \\test "a" {
+ \\ var arr = [_]u32{
+ \\ 0,
+ \\ // 1,
+ \\ // 2,
+ \\ };
+ \\}
+ \\
+ );
+}
+
+test "zig fmt: comment in array initializer/access" {
+ try testCanonical(
+ \\test "a" {
+ \\ var a = x{ //aa
+ \\ //bb
+ \\ };
+ \\ var a = []x{ //aa
+ \\ //bb
+ \\ };
+ \\ var b = [ //aa
+ \\ _
+ \\ ]x{ //aa
+ \\ //bb
+ \\ 9,
+ \\ };
+ \\ var c = b[ //aa
+ \\ 0
+ \\ ];
+ \\ var d = [
+ \\ _
+ \\ //aa
+ \\ :
+ \\ 0
+ \\ ]x{ //aa
+ \\ //bb
+ \\ 9,
+ \\ };
+ \\ var e = d[
+ \\ 0
+ \\ //aa
+ \\ ];
+ \\}
+ \\
+ );
+}
+
+test "zig fmt: comments at several places in struct init" {
+ try testTransform(
+ \\var bar = Bar{
+ \\ .x = 10, // test
+ \\ .y = "test"
+ \\ // test
+ \\};
+ \\
+ ,
+ \\var bar = Bar{
+ \\ .x = 10, // test
+ \\ .y = "test",
+ \\ // test
+ \\};
+ \\
+ );
+
+ try testCanonical(
+ \\var bar = Bar{ // test
+ \\ .x = 10, // test
+ \\ .y = "test",
+ \\ // test
+ \\};
+ \\
+ );
+}
+
+test "zig fmt: remove newlines surrounding doc comment" {
+ try testTransform(
+ \\
+ \\
+ \\
+ \\/// doc comment
+ \\
+ \\fn foo() void {}
+ \\
+ ,
+ \\/// doc comment
+ \\fn foo() void {}
+ \\
+ );
+}
+
+test "zig fmt: remove newlines surrounding doc comment between members" {
+ try testTransform(
+ \\f1: i32,
+ \\
+ \\
+ \\/// doc comment
+ \\
+ \\f2: i32,
+ \\
+ ,
+ \\f1: i32,
+ \\
+ \\/// doc comment
+ \\f2: i32,
+ \\
+ );
+}
+
+
+
test "Ast header smoke test" {
try std.testing.expectEqual(zigNode(c.AST_NODE_IF), Ast.Node.Tag.@"if");
}