diff options
| -rw-r--r-- | main.c | 112 | ||||
| -rw-r--r-- | tests/034.sh | 17 |
2 files changed, 76 insertions, 53 deletions
@@ -1195,59 +1195,6 @@ struct AstNode* parse_stmt(struct Parser* p) { } } -struct AstNode* parse_struct_member(struct Parser* p) { - struct Type* ty = parse_type(p); - char* name = parse_ident(p); - expect(p, TK_SEMICOLON); - struct AstNode* member = ast_new(AST_STRUCT_MEMBER); - member->name = name; - member->ty = ty; - return member; -} - -struct AstNode* parse_struct_members(struct Parser* p) { - struct AstNode* list = ast_new_list(AST_STRUCT_MEMBER_LIST); - for (0; peek_token(p)->kind != TK_BRACE_R; 0) { - struct AstNode* member = parse_struct_member(p); - list->last->next = member; - list->last = member; - } - return list; -} - -struct AstNode* parse_struct_decl_or_def(struct Parser* p) { - expect(p, TK_K_STRUCT); - char* name = parse_ident(p); - int struct_index; - for (struct_index = 0; struct_index < p->n_structs; struct_index = struct_index + 1) { - if (strcmp(name, p->structs[struct_index].name) == 0) { - break; - } - } - if (struct_index == p->n_structs) { - p->structs[struct_index].name = name; - p->n_structs = p->n_structs + 1; - } - if (peek_token(p)->kind == TK_SEMICOLON) { - next_token(p); - return ast_new(AST_STRUCT_DECL); - } - if (p->structs[struct_index].node1) { - char* buf = calloc(1024, sizeof(char)); - sprintf(buf, "parse_struct_decl_or_def: struct %s redefined", name); - fatal_error(buf); - } - expect(p, TK_BRACE_L); - struct AstNode* members = parse_struct_members(p); - expect(p, TK_BRACE_R); - expect(p, TK_SEMICOLON); - struct AstNode* s = ast_new(AST_STRUCT_DEF); - s->name = name; - s->node1 = members; - p->structs[struct_index].node1 = members; - return s; -} - void enter_func(struct Parser* p) { p->locals = calloc(LVAR_MAX, sizeof(struct LVar)); p->n_locals = 0; @@ -1319,6 +1266,65 @@ struct AstNode* parse_func_decl_or_def(struct Parser* p) { return func; } +struct AstNode* parse_struct_member(struct Parser* p) { + struct Type* ty = parse_type(p); + char* name = parse_ident(p); + expect(p, TK_SEMICOLON); + struct AstNode* member = ast_new(AST_STRUCT_MEMBER); + member->name = name; + member->ty = ty; + return member; +} + +struct AstNode* parse_struct_members(struct Parser* p) { + struct AstNode* list = ast_new_list(AST_STRUCT_MEMBER_LIST); + for (0; peek_token(p)->kind != TK_BRACE_R; 0) { + struct AstNode* member = parse_struct_member(p); + list->last->next = member; + list->last = member; + } + return list; +} + +struct AstNode* parse_struct_decl_or_def(struct Parser* p) { + expect(p, TK_K_STRUCT); + char* name = parse_ident(p); + + if (peek_token(p)->kind != TK_SEMICOLON && peek_token(p)->kind != TK_BRACE_L) { + p->pos = p->pos - 2; + return parse_func_decl_or_def(p); + } + + int struct_index; + for (struct_index = 0; struct_index < p->n_structs; struct_index = struct_index + 1) { + if (strcmp(name, p->structs[struct_index].name) == 0) { + break; + } + } + if (struct_index == p->n_structs) { + p->structs[struct_index].name = name; + p->n_structs = p->n_structs + 1; + } + if (peek_token(p)->kind == TK_SEMICOLON) { + next_token(p); + return ast_new(AST_STRUCT_DECL); + } + if (p->structs[struct_index].node1) { + char* buf = calloc(1024, sizeof(char)); + sprintf(buf, "parse_struct_decl_or_def: struct %s redefined", name); + fatal_error(buf); + } + expect(p, TK_BRACE_L); + struct AstNode* members = parse_struct_members(p); + expect(p, TK_BRACE_R); + expect(p, TK_SEMICOLON); + struct AstNode* s = ast_new(AST_STRUCT_DEF); + s->name = name; + s->node1 = members; + p->structs[struct_index].node1 = members; + return s; +} + struct AstNode* parse_toplevel(struct Parser* p) { if (peek_token(p)->kind == TK_K_STRUCT) { return parse_struct_decl_or_def(p); diff --git a/tests/034.sh b/tests/034.sh new file mode 100644 index 0000000..12391f4 --- /dev/null +++ b/tests/034.sh @@ -0,0 +1,17 @@ +set -e + +cat <<'EOF' > expected +EOF +bash ../../test_diff.sh <<'EOF' +struct S { + int a; +}; + +struct S* f(); + +struct S* g() {} + +int main() { + return 0; +} +EOF |
