From d34f0f6a026e59ada6d0bd98c03709d13855c34e Mon Sep 17 00:00:00 2001 From: Lee Date: Sun, 2 Jun 2024 13:32:14 +0800 Subject: [PATCH] Add id field for struct and union type for ast dumper --- include/type.hpp | 14 ++++++++++---- parser.y | 24 ++++++++++++++++++------ src/ast_dumper.cpp | 6 +----- src/type.cpp | 14 ++++++++++---- src/type_checker.cpp | 1 + test/typecheck/struct.exp | 6 +++--- test/typecheck/union.exp | 6 +++--- 7 files changed, 46 insertions(+), 25 deletions(-) diff --git a/include/type.hpp b/include/type.hpp index ce6580db..5e4f3299 100644 --- a/include/type.hpp +++ b/include/type.hpp @@ -176,8 +176,10 @@ class FuncType : public Type { class StructType : public Type { public: - explicit StructType(std::vector> field_types) - : field_types_{std::move(field_types)} {} + /// @param id The identifier of a struct type. + explicit StructType(std::string id, + std::vector> field_types) + : id_{std::move(id)}, field_types_{std::move(field_types)} {} bool IsStruct() const noexcept override { return true; @@ -189,13 +191,16 @@ class StructType : public Type { std::unique_ptr Clone() const override; private: + std::string id_; std::vector> field_types_; }; class UnionType : public Type { public: - explicit UnionType(std::vector> field_types) - : field_types_{std::move(field_types)} {} + /// @param id The identifier of a union type. + explicit UnionType(std::string id, + std::vector> field_types) + : id_{std::move(id)}, field_types_{std::move(field_types)} {} bool IsUnion() const noexcept override { return true; @@ -207,6 +212,7 @@ class UnionType : public Type { std::unique_ptr Clone() const override; private: + std::string id_; std::vector> field_types_; }; diff --git a/parser.y b/parser.y index 11f9ded9..a9bc2332 100644 --- a/parser.y +++ b/parser.y @@ -448,7 +448,7 @@ init_declarator: declarator { $$ = $1; } // Declares a struct or union variable. auto rec_decl = std::make_unique(Loc(@1), std::move(var_decl->id), - var_decl->type->Clone(), + std::move(var_decl->type), std::move(init_expr_list)); decl = std::move(rec_decl); } @@ -476,17 +476,29 @@ struct_or_union_specifier: struct_or_union id_opt LEFT_CURLY struct_declaration_ field_types.push_back(field->type->Clone()); } + auto type_id = decl_id ? decl_id->id : ""; if (type->IsStruct()) { - type = std::make_unique(std::move(field_types)); + type = std::make_unique(std::move(type_id), std::move(field_types)); } else { - type = std::make_unique(std::move(field_types)); + type = std::make_unique(std::move(type_id), std::move(field_types)); } $$ = std::make_unique(Loc(@2), decl_id ? std::move(decl_id->id) : "", std::move(type), std::move(field_list)); } | struct_or_union ID { + auto type = $1; + auto decl_id = $2; auto field_list = std::vector>{}; - $$ = std::make_unique(Loc(@2), $2, $1, std::move(field_list)); + auto field_types = std::vector>{}; + + auto type_id = decl_id; + if (type->IsStruct()) { + type = std::make_unique(std::move(type_id), std::move(field_types)); + } else { + type = std::make_unique(std::move(type_id), std::move(field_types)); + } + + $$ = std::make_unique(Loc(@2), std::move(decl_id), std::move(type), std::move(field_list)); } ; @@ -536,11 +548,11 @@ id_opt: ID { struct_or_union: STRUCT { auto field_types = std::vector>{}; - $$ = std::make_unique(std::move(field_types)); + $$ = std::make_unique("", std::move(field_types)); } | UNION { auto field_types = std::vector>{}; - $$ = std::make_unique(std::move(field_types)); + $$ = std::make_unique("", std::move(field_types)); } ; diff --git a/src/ast_dumper.cpp b/src/ast_dumper.cpp index 4fd53bf6..f5afb592 100644 --- a/src/ast_dumper.cpp +++ b/src/ast_dumper.cpp @@ -113,12 +113,8 @@ void AstDumper::Visit(const ArrDeclNode& arr_decl) { } void AstDumper::Visit(const RecordDeclNode& record_decl) { - std::string id = ""; - if (!record_decl.id.empty()) { - id += " " + record_decl.id; - } std::cout << indenter_.Indent() << "RecordDeclNode <" << record_decl.loc - << "> " << record_decl.type->ToString() << id << " definition\n"; + << "> " << record_decl.type->ToString() << " definition\n"; indenter_.IncreaseLevel(); for (const auto& field : record_decl.fields) { diff --git a/src/type.cpp b/src/type.cpp index e7c7e6d4..e4c36f0f 100644 --- a/src/type.cpp +++ b/src/type.cpp @@ -179,7 +179,10 @@ std::size_t StructType::size() const { } std::string StructType::ToString() const { - return "struct"; + if (id_ == "") { + return "struct"; + } + return "struct " + id_; } std::unique_ptr StructType::Clone() const { @@ -187,7 +190,7 @@ std::unique_ptr StructType::Clone() const { for (const auto& field_type : field_types_) { cloned_field_types.push_back(field_type->Clone()); } - return std::make_unique(std::move(cloned_field_types)); + return std::make_unique(id_, std::move(cloned_field_types)); } bool UnionType::IsEqual(const Type& that) const noexcept { @@ -208,7 +211,10 @@ std::size_t UnionType::size() const { } std::string UnionType::ToString() const { - return "union"; + if (id_ == "") { + return "union"; + } + return "union " + id_; } std::unique_ptr UnionType::Clone() const { @@ -216,5 +222,5 @@ std::unique_ptr UnionType::Clone() const { for (const auto& field_type : field_types_) { cloned_field_types.push_back(field_type->Clone()); } - return std::make_unique(std::move(cloned_field_types)); + return std::make_unique(id_, std::move(cloned_field_types)); } diff --git a/src/type_checker.cpp b/src/type_checker.cpp index 7bcd282b..96f0dd2c 100644 --- a/src/type_checker.cpp +++ b/src/type_checker.cpp @@ -107,6 +107,7 @@ void TypeChecker::Visit(RecordVarDeclNode& record_decl) { auto symbol = std::make_unique(record_decl.id, record_decl.type->Clone()); + // TODO: type check between fields and initialized members. for (auto& init : record_decl.inits) { init->Accept(*this); } diff --git a/test/typecheck/struct.exp b/test/typecheck/struct.exp index e4e7cb41..d20fe9bb 100644 --- a/test/typecheck/struct.exp +++ b/test/typecheck/struct.exp @@ -10,7 +10,7 @@ ProgramNode <1:1> FieldNode <11:9> quarter: int FieldNode <12:9> dime: int FieldNode <13:9> penny: int - RecordVarDeclNode <16:16> bd1: struct + RecordVarDeclNode <16:16> bd1: struct birth InitExprNode <17:5> IdDesNode <17:6> date IntConstExprNode <17:13> 1: int @@ -20,14 +20,14 @@ ProgramNode <1:1> InitExprNode <17:5> IdDesNode <19:6> year IntConstExprNode <19:13> 1995: int - RecordVarDeclNode <22:16> bd2: struct + RecordVarDeclNode <22:16> bd2: struct birth InitExprNode <22:23> IntConstExprNode <22:23> 3: int InitExprNode <22:23> IntConstExprNode <22:26> 3: int InitExprNode <22:23> IntConstExprNode <22:29> 1998: int - ArrDeclNode <24:16> bd3: struct[3] + ArrDeclNode <24:16> bd3: struct birth[3] InitExprNode <24:27> ArrDesNode <24:28> IntConstExprNode <24:28> 0: int diff --git a/test/typecheck/union.exp b/test/typecheck/union.exp index bb2bd27f..0caa1064 100644 --- a/test/typecheck/union.exp +++ b/test/typecheck/union.exp @@ -12,18 +12,18 @@ ProgramNode <1:1> FieldNode <13:9> c: int FieldNode <14:9> d: int FieldNode <15:9> e: int - RecordVarDeclNode <20:15> s: union + RecordVarDeclNode <20:15> s: union shape InitExprNode <20:20> IntConstExprNode <20:20> 3: int InitExprNode <20:20> IntConstExprNode <20:23> 4: int InitExprNode <20:20> IntConstExprNode <20:26> 5: int - RecordVarDeclNode <22:15> circle: union + RecordVarDeclNode <22:15> circle: union shape InitExprNode <22:25> IdDesNode <22:26> circle IntConstExprNode <22:35> 1: int - ArrDeclNode <23:15> puzzles: union[3] + ArrDeclNode <23:15> puzzles: union shape[3] InitExprNode <23:30> ArrDesNode <23:31> IntConstExprNode <23:31> 0: int