parser: port test "c pointer type"

Implement [*], [*c], and [*:s] pointer type parsing in parseTypeExpr.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-02-10 15:05:41 +00:00
parent 74d6a66a2d
commit 592638502a
2 changed files with 72 additions and 3 deletions

View File

@@ -862,9 +862,71 @@ static AstNodeIndex parseTypeExpr(Parser* p) {
case TOKEN_L_BRACKET: {
const AstTokenIndex lbracket = nextToken(p);
if (p->token_tags[p->tok_i] == TOKEN_ASTERISK) {
fprintf(
stderr, "parseTypeExpr: [*] pointer types not implemented\n");
exit(1);
// [*] many-item pointer, [*c] C pointer, [*:s] sentinel
p->tok_i++; // consume *
AstNodeIndex sentinel = 0;
if (p->token_tags[p->tok_i] == TOKEN_IDENTIFIER) {
// Check for 'c' modifier: [*c]
// The 'c' is a regular identifier token
const char c = p->source[p->token_starts[p->tok_i]];
if (c == 'c'
&& p->token_starts[p->tok_i + 1]
- p->token_starts[p->tok_i]
<= 2) {
p->tok_i++; // consume 'c'
}
} else if (eatToken(p, TOKEN_COLON) != null_token) {
sentinel = expectExpr(p);
}
expectToken(p, TOKEN_R_BRACKET);
// const/volatile/allowzero pointer modifiers
while (p->token_tags[p->tok_i] == TOKEN_KEYWORD_CONST
|| p->token_tags[p->tok_i] == TOKEN_KEYWORD_VOLATILE
|| p->token_tags[p->tok_i] == TOKEN_KEYWORD_ALLOWZERO)
p->tok_i++;
const AstNodeIndex align_expr = parseByteAlign(p);
const AstNodeIndex addrspace_expr = parseAddrSpace(p);
// const/volatile/allowzero again (can appear before or after
// align)
while (p->token_tags[p->tok_i] == TOKEN_KEYWORD_CONST
|| p->token_tags[p->tok_i] == TOKEN_KEYWORD_VOLATILE
|| p->token_tags[p->tok_i] == TOKEN_KEYWORD_ALLOWZERO)
p->tok_i++;
const AstNodeIndex elem_type = parseTypeExpr(p);
if (sentinel != 0) {
if (addrspace_expr != 0) {
fprintf(stderr,
"parseTypeExpr: [*:s] with addrspace not "
"implemented\n");
exit(1);
}
return addNode(&p->nodes,
(AstNodeItem) {
.tag = AST_NODE_PTR_TYPE_SENTINEL,
.main_token = lbracket,
.data = { .lhs = sentinel, .rhs = elem_type },
});
}
if (addrspace_expr != 0) {
return addNode(&p->nodes,
(AstNodeItem) {
.tag = AST_NODE_PTR_TYPE,
.main_token = lbracket,
.data = {
.lhs = addExtra(p,
(AstNodeIndex[]) {
0, align_expr, addrspace_expr },
3),
.rhs = elem_type,
},
});
}
return addNode(&p->nodes,
(AstNodeItem) {
.tag = AST_NODE_PTR_TYPE_ALIGNED,
.main_token = lbracket,
.data = { .lhs = align_expr, .rhs = elem_type },
});
}
const AstNodeIndex len_expr = parseExpr(p);
const AstNodeIndex sentinel

View File

@@ -1810,6 +1810,13 @@ test "zig fmt: nosuspend block" {
);
}
test "zig fmt: c pointer type" {
try testCanonical(
\\pub extern fn repro() [*c]const u8;
\\
);
}
test "zig fmt: top-level tuple function call type" {
try testCanonical(
\\foo()