From e8a2b6b6b56ed20b29583f783354696c785167d3 Mon Sep 17 00:00:00 2001 From: Lee Date: Sat, 19 Oct 2024 01:24:25 +0800 Subject: [PATCH] Update record type declaration while declaring variables --- parser.y | 22 ++++++++++++++++------ test/typecheck/struct.exp | 25 +++++++++++++++++++++++-- test/typecheck/union.exp | 20 ++++++++++++++++++-- 3 files changed, 57 insertions(+), 10 deletions(-) diff --git a/parser.y b/parser.y index 75ea12f6..3b697b63 100644 --- a/parser.y +++ b/parser.y @@ -31,6 +31,7 @@ std::unique_ptr ResolveType(std::unique_ptr resolved_type, // inserts verbatim to the header file. %code requires { #include + #include #include #include #include @@ -47,6 +48,9 @@ std::unique_ptr ResolveType(std::unique_ptr resolved_type, Location Loc(const yy::location& loc) { return Location{loc.begin.line, loc.begin.column}; } + + /// @brief A set that stores unique custom types for every file. + std::set custom_types; } %skeleton "lalr1.cc" @@ -420,12 +424,9 @@ decl: declaration_specifiers init_declarator_list_opt SEMICOLON { } } else { auto decl = std::move(std::get>(decl_specifiers)); - // A record declaration that doesn't declare any identifier, e.g., `struct point {int x, int y};`. - if (init_decl_list.empty()) { - decl_list.push_back(std::move(decl)); - } else { - auto& rec_decl = dynamic_cast(*decl); - // Initialize record variable. + auto& rec_decl = dynamic_cast(*decl); + + if (!init_decl_list.empty()) { for (auto& init_decl : init_decl_list) { if (init_decl) { init_decl->type = ResolveType(rec_decl.type->Clone(), std::move(init_decl->type)); @@ -433,6 +434,15 @@ decl: declaration_specifiers init_declarator_list_opt SEMICOLON { decl_list.push_back(std::move(init_decl)); } } + + auto rec_type_id = dynamic_cast(*rec_decl.type).id(); + // Insert RecordDeclNode if it is a newly create type. + if (custom_types.find(rec_type_id) == custom_types.end()) { + // To dump type declarations in front of variable declarations, + // insert decl at the beginning of the vector. + decl_list.insert(decl_list.begin(), std::move(decl)); + custom_types.insert(rec_type_id); + } } $$ = std::make_unique(Loc(@1), std::move(decl_list)); } diff --git a/test/typecheck/struct.exp b/test/typecheck/struct.exp index 7f3ffce0..7c79b8d6 100644 --- a/test/typecheck/struct.exp +++ b/test/typecheck/struct.exp @@ -52,5 +52,26 @@ TransUnitNode <1:1> ExprStmtNode <28:3> RecordMemExprNode <28:3> .date: int IdExprNode <28:3> bd1: struct birth - ReturnStmtNode <30:3> - IntConstExprNode <30:10> 0: int + DeclStmtNode <30:3> + RecordDeclNode <30:10> struct animal definition + FieldNode <31:9> lion: int + FieldNode <32:9> tiger: int + FieldNode <33:9> giraffe: int + VarDeclNode <34:5> zoo: struct animal + DeclStmtNode <36:3> + RecordDeclNode <36:10> struct book definition + FieldNode <37:9> fiction: int + FieldNode <38:9> sci_fi: int + FieldNode <39:9> history: int + RecordVarDeclNode <40:5> library: struct book + InitExprNode <41:5> int + IdDesNode <41:6> fiction + IntConstExprNode <41:16> 100: int + InitExprNode <41:5> int + IdDesNode <42:6> sci_fi + IntConstExprNode <42:15> 50: int + InitExprNode <41:5> int + IdDesNode <43:6> history + IntConstExprNode <43:16> 500: int + ReturnStmtNode <46:3> + IntConstExprNode <46:10> 0: int diff --git a/test/typecheck/union.exp b/test/typecheck/union.exp index 905d445f..7c7ccdd9 100644 --- a/test/typecheck/union.exp +++ b/test/typecheck/union.exp @@ -53,5 +53,21 @@ TransUnitNode <1:1> ExprStmtNode <27:3> RecordMemExprNode <27:3> .circle: int IdExprNode <27:3> s: union shape - ReturnStmtNode <29:3> - IntConstExprNode <29:10> 0: int + DeclStmtNode <29:3> + RecordDeclNode <29:9> union gender definition + FieldNode <30:9> male: int + FieldNode <31:9> female: int + RecordVarDeclNode <32:5> girl: union gender + InitExprNode <33:5> int + IdDesNode <33:6> female + IntConstExprNode <33:15> 1: int + DeclStmtNode <36:3> + RecordDeclNode <36:9> union birth_place definition + FieldNode <37:9> tw: int + FieldNode <38:9> us: int + RecordVarDeclNode <39:5> yt: union birth_place + InitExprNode <40:5> int + IdDesNode <40:6> tw + IntConstExprNode <40:11> 1: int + ReturnStmtNode <43:3> + IntConstExprNode <43:10> 0: int