parser: port switch, slice, array literal, formatting tests
Port tests: - "switch cases trailing comma" - "slice align" - "add trailing comma to array literal" - "first thing in file is line comment" - "line comment after doc comment" - "bit field alignment" - "nested switch" - "float literal with exponent" - "if-else end of comptime" - "nested blocks" - "statements with comment between" - "statements with empty line between" - "ptr deref operator and unwrap optional operator" Fix in parser.c: - switch_case SubRange stored via addExtra (not inline) - Switch case body uses parseAssignExpr (not expectExpr) - TOKEN_PERIOD_ASTERISK for deref in parseSuffixOp Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
15
parser.c
15
parser.c
@@ -638,6 +638,12 @@ static AstNodeIndex parseSuffixOp(Parser* p, AstNodeIndex lhs) {
|
||||
return 0; // tcc
|
||||
}
|
||||
case TOKEN_PERIOD_ASTERISK:
|
||||
return addNode(&p->nodes,
|
||||
(AstNodeItem) {
|
||||
.tag = AST_NODE_DEREF,
|
||||
.main_token = nextToken(p),
|
||||
.data = { .lhs = lhs, .rhs = 0 },
|
||||
});
|
||||
case TOKEN_INVALID_PERIODASTERISKS:
|
||||
fprintf(stderr, "parseSuffixOp does not support %s\n",
|
||||
tokenizerGetTagString(tok));
|
||||
@@ -1825,7 +1831,8 @@ static AstNodeIndex parseSwitchExpr(Parser* p) {
|
||||
const AstTokenIndex arrow
|
||||
= expectToken(p, TOKEN_EQUAL_ANGLE_BRACKET_RIGHT);
|
||||
parsePtrPayload(p);
|
||||
const AstNodeIndex case_body = expectExpr(p);
|
||||
const AstNodeIndex case_body = parseAssignExpr(p);
|
||||
assert(case_body != 0);
|
||||
|
||||
const uint32_t items_len = p->scratch.len - items_old_len;
|
||||
AstNodeIndex case_node;
|
||||
@@ -1851,7 +1858,11 @@ static AstNodeIndex parseSwitchExpr(Parser* p) {
|
||||
(AstNodeItem) {
|
||||
.tag = AST_NODE_SWITCH_CASE,
|
||||
.main_token = arrow,
|
||||
.data = { .lhs = span.start, .rhs = case_body },
|
||||
.data = {
|
||||
.lhs = addExtra(p,
|
||||
(AstNodeIndex[]) { span.start, span.end }, 2),
|
||||
.rhs = case_body,
|
||||
},
|
||||
});
|
||||
} break;
|
||||
}
|
||||
|
||||
173
parser_test.zig
173
parser_test.zig
@@ -2566,6 +2566,179 @@ test "zig fmt: extra newlines at the end" {
|
||||
);
|
||||
}
|
||||
|
||||
test "zig fmt: switch cases trailing comma" {
|
||||
try testTransform(
|
||||
\\test "switch cases trailing comma"{
|
||||
\\ switch (x) {
|
||||
\\ 1,2,3 => {},
|
||||
\\ 4,5, => {},
|
||||
\\ 6... 8, => {},
|
||||
\\ 9 ...
|
||||
\\ 10 => {},
|
||||
\\ 11 => {},
|
||||
\\ 12, => {},
|
||||
\\ else => {},
|
||||
\\ }
|
||||
\\}
|
||||
,
|
||||
\\test "switch cases trailing comma" {
|
||||
\\ switch (x) {
|
||||
\\ 1, 2, 3 => {},
|
||||
\\ 4,
|
||||
\\ 5,
|
||||
\\ => {},
|
||||
\\ 6...8,
|
||||
\\ => {},
|
||||
\\ 9...10 => {},
|
||||
\\ 11 => {},
|
||||
\\ 12,
|
||||
\\ => {},
|
||||
\\ else => {},
|
||||
\\ }
|
||||
\\}
|
||||
\\
|
||||
);
|
||||
}
|
||||
|
||||
test "zig fmt: slice align" {
|
||||
try testCanonical(
|
||||
\\const A = struct {
|
||||
\\ items: []align(A) T,
|
||||
\\};
|
||||
\\
|
||||
);
|
||||
}
|
||||
|
||||
test "zig fmt: add trailing comma to array literal" {
|
||||
try testTransform(
|
||||
\\comptime {
|
||||
\\ return []u16{'m', 's', 'y', 's', '-' // hi
|
||||
\\ };
|
||||
\\ return []u16{'m', 's', 'y', 's',
|
||||
\\ '-'};
|
||||
\\ return []u16{'m', 's', 'y', 's', '-'};
|
||||
\\}
|
||||
,
|
||||
\\comptime {
|
||||
\\ return []u16{
|
||||
\\ 'm', 's', 'y', 's', '-', // hi
|
||||
\\ };
|
||||
\\ return []u16{ 'm', 's', 'y', 's', '-' };
|
||||
\\ return []u16{ 'm', 's', 'y', 's', '-' };
|
||||
\\}
|
||||
\\
|
||||
);
|
||||
}
|
||||
|
||||
test "zig fmt: first thing in file is line comment" {
|
||||
try testCanonical(
|
||||
\\// Introspection and determination of system libraries needed by zig.
|
||||
\\
|
||||
\\// Introspection and determination of system libraries needed by zig.
|
||||
\\
|
||||
\\const std = @import("std");
|
||||
\\
|
||||
);
|
||||
}
|
||||
|
||||
test "zig fmt: line comment after doc comment" {
|
||||
try testCanonical(
|
||||
\\/// doc comment
|
||||
\\// line comment
|
||||
\\fn foo() void {}
|
||||
\\
|
||||
);
|
||||
}
|
||||
|
||||
test "zig fmt: bit field alignment" {
|
||||
try testCanonical(
|
||||
\\test {
|
||||
\\ assert(@TypeOf(&blah.b) == *align(1:3:6) const u3);
|
||||
\\}
|
||||
\\
|
||||
);
|
||||
}
|
||||
|
||||
test "zig fmt: nested switch" {
|
||||
try testCanonical(
|
||||
\\test {
|
||||
\\ switch (state) {
|
||||
\\ TermState.Start => switch (c) {
|
||||
\\ '\x1b' => state = TermState.Escape,
|
||||
\\ else => try out.writeByte(c),
|
||||
\\ },
|
||||
\\ }
|
||||
\\}
|
||||
\\
|
||||
);
|
||||
}
|
||||
|
||||
test "zig fmt: float literal with exponent" {
|
||||
try testCanonical(
|
||||
\\pub const f64_true_min = 4.94065645841246544177e-324;
|
||||
\\const threshold = 0x1.a827999fcef32p+1022;
|
||||
\\
|
||||
);
|
||||
}
|
||||
|
||||
test "zig fmt: if-else end of comptime" {
|
||||
try testCanonical(
|
||||
\\comptime {
|
||||
\\ if (a) {
|
||||
\\ b();
|
||||
\\ } else {
|
||||
\\ b();
|
||||
\\ }
|
||||
\\}
|
||||
\\
|
||||
);
|
||||
}
|
||||
|
||||
test "zig fmt: nested blocks" {
|
||||
try testCanonical(
|
||||
\\comptime {
|
||||
\\ {
|
||||
\\ {
|
||||
\\ {
|
||||
\\ a();
|
||||
\\ }
|
||||
\\ }
|
||||
\\ }
|
||||
\\}
|
||||
\\
|
||||
);
|
||||
}
|
||||
|
||||
test "zig fmt: statements with comment between" {
|
||||
try testCanonical(
|
||||
\\comptime {
|
||||
\\ a = b;
|
||||
\\ // comment
|
||||
\\ a = b;
|
||||
\\}
|
||||
\\
|
||||
);
|
||||
}
|
||||
|
||||
test "zig fmt: statements with empty line between" {
|
||||
try testCanonical(
|
||||
\\comptime {
|
||||
\\ a = b;
|
||||
\\
|
||||
\\ a = b;
|
||||
\\}
|
||||
\\
|
||||
);
|
||||
}
|
||||
|
||||
test "zig fmt: ptr deref operator and unwrap optional operator" {
|
||||
try testCanonical(
|
||||
\\const a = b.*;
|
||||
\\const a = b.?;
|
||||
\\
|
||||
);
|
||||
}
|
||||
|
||||
test "zig fmt: nested struct literal with one item" {
|
||||
try testCanonical(
|
||||
\\const a = foo{
|
||||
|
||||
Reference in New Issue
Block a user