diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-02-07 15:18:18 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-02-07 15:18:18 +0900 |
| commit | b8780671f6768e3b5a09084d9f80c01bd544d2e8 (patch) | |
| tree | 57a7e27baa0df450b98376db53ce46b3e1d594da | |
| parent | a76908958f4fb404ec24bf86d3aa59f0ec5f6be0 (diff) | |
| download | ducc-b8780671f6768e3b5a09084d9f80c01bd544d2e8.tar.gz ducc-b8780671f6768e3b5a09084d9f80c01bd544d2e8.tar.zst ducc-b8780671f6768e3b5a09084d9f80c01bd544d2e8.zip | |
feat: support anonymous struct members
| -rw-r--r-- | src/parse.c | 17 | ||||
| -rw-r--r-- | tests/structs.sh | 25 |
2 files changed, 37 insertions, 5 deletions
diff --git a/src/parse.c b/src/parse.c index 1b5db5b..88c2920 100644 --- a/src/parse.c +++ b/src/parse.c @@ -1410,7 +1410,7 @@ void parse_typedef_decl(Parser* p, AstNode* decls) { } } -static char* generate_new_anonymous_user_type_name(Parser* p) { +static char* generate_anonymous_name(Parser* p) { char* buf = calloc(32, sizeof(char)); sprintf(buf, "__anonymous_%d__", p->anonymous_user_type_counter++); return buf; @@ -1707,7 +1707,7 @@ static Type* parse_struct_specifier(Parser* p) { const Token* name; char* anonymous_name = NULL; if (peek_token(p)->kind == TokenKind_brace_l) { - anonymous_name = generate_new_anonymous_user_type_name(p); + anonymous_name = generate_anonymous_name(p); Token* anonymous_token = calloc(1, sizeof(Token)); anonymous_token->kind = TokenKind_ident; anonymous_token->value.string = anonymous_name; @@ -1768,7 +1768,7 @@ static Type* parse_union_specifier(Parser* p) { const Token* name; char* anonymous_name = NULL; if (peek_token(p)->kind == TokenKind_brace_l) { - anonymous_name = generate_new_anonymous_user_type_name(p); + anonymous_name = generate_anonymous_name(p); Token* anonymous_token = calloc(1, sizeof(Token)); anonymous_token->kind = TokenKind_ident; anonymous_token->value.string = anonymous_name; @@ -1840,7 +1840,14 @@ static AstNode* parse_member_declaration(Parser* p) { AstNode* decls = NULL; if (consume_token_if(p, TokenKind_semicolon)) { - unimplemented(); + char* name = generate_anonymous_name(p); + AstNode* decls = ast_new_list(1); + AstNode* member = ast_new(AstNodeKind_struct_member); + member->ty = base_ty; + member->as.struct_member = calloc(1, sizeof(StructMemberNode)); + member->as.struct_member->name = name; + ast_append(decls, member); + return decls; } decls = parse_member_declarator_list(p, base_ty); @@ -2051,7 +2058,7 @@ static Type* parse_enum_specifier(Parser* p) { const Token* name; char* anonymous_name = NULL; if (peek_token(p)->kind == TokenKind_brace_l) { - anonymous_name = generate_new_anonymous_user_type_name(p); + anonymous_name = generate_anonymous_name(p); Token* anonymous_token = calloc(1, sizeof(Token)); anonymous_token->kind = TokenKind_ident; anonymous_token->value.string = anonymous_name; diff --git a/tests/structs.sh b/tests/structs.sh index 4c8ff6d..3df4f9c 100644 --- a/tests/structs.sh +++ b/tests/structs.sh @@ -362,3 +362,28 @@ int main() { printf("%zu\n", sizeof(E)); } EOF + +cat <<'EOF' > expected +EOF + +test_diff <<'EOF' +int printf(); + +struct S1 { + struct { + int x; + int y; + }; + struct { + int z; + }; +}; + +int main() { + // TODO + // struct S1 a = {1, 2, 3}; + // printf("%d\n", a.x); + // printf("%d\n", a.y); + // printf("%d\n", a.z); +} +EOF |
