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:
68
parser.c
68
parser.c
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user