parser: add slicing and tagged union tests
Port tests from upstream parser_test.zig: - "slices" (open, closed, sentinel-terminated) - "tagged union with enum values" - "tagged union enum tag last token" Implement in parser.c: - Slice expressions in parseSuffixOp: slice_open, slice, slice_sentinel - Handle OptionalIndex encoding for absent slice end expr Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
46
parser.c
46
parser.c
@@ -571,9 +571,49 @@ static AstNodeIndex parseSuffixOp(Parser* p, AstNodeIndex lhs) {
|
|||||||
.main_token = lbracket,
|
.main_token = lbracket,
|
||||||
.data = { .lhs = lhs, .rhs = index_expr },
|
.data = { .lhs = lhs, .rhs = index_expr },
|
||||||
});
|
});
|
||||||
case TOKEN_ELLIPSIS2:
|
case TOKEN_ELLIPSIS2: {
|
||||||
fprintf(stderr, "parseSuffixOp: slicing not implemented\n");
|
p->tok_i++; // consume ..
|
||||||
exit(1);
|
const AstNodeIndex end_expr = parseExpr(p);
|
||||||
|
if (eatToken(p, TOKEN_COLON) != null_token) {
|
||||||
|
const AstNodeIndex sentinel = expectExpr(p);
|
||||||
|
expectToken(p, TOKEN_R_BRACKET);
|
||||||
|
// end_expr 0 means "no end" — encode as ~0 for
|
||||||
|
// OptionalIndex.none
|
||||||
|
const AstNodeIndex opt_end
|
||||||
|
= end_expr == 0 ? ~(AstNodeIndex)0 : end_expr;
|
||||||
|
return addNode(&p->nodes,
|
||||||
|
(AstNodeItem) {
|
||||||
|
.tag = AST_NODE_SLICE_SENTINEL,
|
||||||
|
.main_token = lbracket,
|
||||||
|
.data = {
|
||||||
|
.lhs = lhs,
|
||||||
|
.rhs = addExtra(p,
|
||||||
|
(AstNodeIndex[]) {
|
||||||
|
index_expr, opt_end, sentinel },
|
||||||
|
3),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expectToken(p, TOKEN_R_BRACKET);
|
||||||
|
if (end_expr == 0) {
|
||||||
|
return addNode(&p->nodes,
|
||||||
|
(AstNodeItem) {
|
||||||
|
.tag = AST_NODE_SLICE_OPEN,
|
||||||
|
.main_token = lbracket,
|
||||||
|
.data = { .lhs = lhs, .rhs = index_expr },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return addNode(&p->nodes,
|
||||||
|
(AstNodeItem) {
|
||||||
|
.tag = AST_NODE_SLICE,
|
||||||
|
.main_token = lbracket,
|
||||||
|
.data = {
|
||||||
|
.lhs = lhs,
|
||||||
|
.rhs = addExtra(p,
|
||||||
|
(AstNodeIndex[]) { index_expr, end_expr }, 2),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
fprintf(
|
fprintf(
|
||||||
stderr, "parseSuffixOp: expected ] or .. after index expr\n");
|
stderr, "parseSuffixOp: expected ] or .. after index expr\n");
|
||||||
|
|||||||
@@ -1206,3 +1206,49 @@ test "zig fmt: array literal 3 element comma" {
|
|||||||
\\
|
\\
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "zig fmt: slices" {
|
||||||
|
try testCanonical(
|
||||||
|
\\const a = b[0..];
|
||||||
|
\\const c = d[0..1];
|
||||||
|
\\const d = f[0.. :0];
|
||||||
|
\\const e = f[0..1 :0];
|
||||||
|
\\
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "zig fmt: tagged union with enum values" {
|
||||||
|
try testCanonical(
|
||||||
|
\\const MultipleChoice2 = union(enum(u32)) {
|
||||||
|
\\ Unspecified1: i32,
|
||||||
|
\\ A: f32 = 20,
|
||||||
|
\\ Unspecified2: void,
|
||||||
|
\\ B: bool = 40,
|
||||||
|
\\ Unspecified3: i32,
|
||||||
|
\\ C: i8 = 60,
|
||||||
|
\\ Unspecified4: void,
|
||||||
|
\\ D: void = 1000,
|
||||||
|
\\ Unspecified5: i32,
|
||||||
|
\\};
|
||||||
|
\\
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "zig fmt: tagged union enum tag last token" {
|
||||||
|
try testCanonical(
|
||||||
|
\\test {
|
||||||
|
\\ const U = union(enum(u32)) {};
|
||||||
|
\\}
|
||||||
|
\\
|
||||||
|
\\test {
|
||||||
|
\\ const U = union(enum(u32)) { foo };
|
||||||
|
\\}
|
||||||
|
\\
|
||||||
|
\\test {
|
||||||
|
\\ const U = union(enum(u32)) {
|
||||||
|
\\ foo,
|
||||||
|
\\ };
|
||||||
|
\\}
|
||||||
|
\\
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user