Skip to content

Commit

Permalink
Add id field for struct and union type for ast dumper
Browse files Browse the repository at this point in the history
  • Loading branch information
leewei05 committed Jun 2, 2024
1 parent 96dbb8b commit d34f0f6
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 25 deletions.
14 changes: 10 additions & 4 deletions include/type.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,10 @@ class FuncType : public Type {

class StructType : public Type {
public:
explicit StructType(std::vector<std::unique_ptr<Type>> field_types)
: field_types_{std::move(field_types)} {}
/// @param id The identifier of a struct type.
explicit StructType(std::string id,
std::vector<std::unique_ptr<Type>> field_types)
: id_{std::move(id)}, field_types_{std::move(field_types)} {}

bool IsStruct() const noexcept override {
return true;
Expand All @@ -189,13 +191,16 @@ class StructType : public Type {
std::unique_ptr<Type> Clone() const override;

private:
std::string id_;
std::vector<std::unique_ptr<Type>> field_types_;
};

class UnionType : public Type {
public:
explicit UnionType(std::vector<std::unique_ptr<Type>> field_types)
: field_types_{std::move(field_types)} {}
/// @param id The identifier of a union type.
explicit UnionType(std::string id,
std::vector<std::unique_ptr<Type>> field_types)
: id_{std::move(id)}, field_types_{std::move(field_types)} {}

bool IsUnion() const noexcept override {
return true;
Expand All @@ -207,6 +212,7 @@ class UnionType : public Type {
std::unique_ptr<Type> Clone() const override;

private:
std::string id_;
std::vector<std::unique_ptr<Type>> field_types_;
};

Expand Down
24 changes: 18 additions & 6 deletions parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ init_declarator: declarator { $$ = $1; }
// Declares a struct or union variable.
auto rec_decl = std::make_unique<RecordVarDeclNode>(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);
}
Expand Down Expand Up @@ -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<StructType>(std::move(field_types));
type = std::make_unique<StructType>(std::move(type_id), std::move(field_types));
} else {
type = std::make_unique<UnionType>(std::move(field_types));
type = std::make_unique<UnionType>(std::move(type_id), std::move(field_types));
}

$$ = std::make_unique<RecordDeclNode>(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::unique_ptr<FieldNode>>{};
$$ = std::make_unique<RecordDeclNode>(Loc(@2), $2, $1, std::move(field_list));
auto field_types = std::vector<std::unique_ptr<Type>>{};

auto type_id = decl_id;
if (type->IsStruct()) {
type = std::make_unique<StructType>(std::move(type_id), std::move(field_types));
} else {
type = std::make_unique<UnionType>(std::move(type_id), std::move(field_types));
}

$$ = std::make_unique<RecordDeclNode>(Loc(@2), std::move(decl_id), std::move(type), std::move(field_list));
}
;

Expand Down Expand Up @@ -536,11 +548,11 @@ id_opt: ID {

struct_or_union: STRUCT {
auto field_types = std::vector<std::unique_ptr<Type>>{};
$$ = std::make_unique<StructType>(std::move(field_types));
$$ = std::make_unique<StructType>("", std::move(field_types));
}
| UNION {
auto field_types = std::vector<std::unique_ptr<Type>>{};
$$ = std::make_unique<UnionType>(std::move(field_types));
$$ = std::make_unique<UnionType>("", std::move(field_types));
}
;

Expand Down
6 changes: 1 addition & 5 deletions src/ast_dumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
14 changes: 10 additions & 4 deletions src/type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,15 +179,18 @@ std::size_t StructType::size() const {
}

std::string StructType::ToString() const {
return "struct";
if (id_ == "") {
return "struct";
}
return "struct " + id_;
}

std::unique_ptr<Type> StructType::Clone() const {
auto cloned_field_types = std::vector<std::unique_ptr<Type>>{};
for (const auto& field_type : field_types_) {
cloned_field_types.push_back(field_type->Clone());
}
return std::make_unique<StructType>(std::move(cloned_field_types));
return std::make_unique<StructType>(id_, std::move(cloned_field_types));
}

bool UnionType::IsEqual(const Type& that) const noexcept {
Expand All @@ -208,13 +211,16 @@ std::size_t UnionType::size() const {
}

std::string UnionType::ToString() const {
return "union";
if (id_ == "") {
return "union";
}
return "union " + id_;
}

std::unique_ptr<Type> UnionType::Clone() const {
auto cloned_field_types = std::vector<std::unique_ptr<Type>>{};
for (const auto& field_type : field_types_) {
cloned_field_types.push_back(field_type->Clone());
}
return std::make_unique<UnionType>(std::move(cloned_field_types));
return std::make_unique<UnionType>(id_, std::move(cloned_field_types));
}
1 change: 1 addition & 0 deletions src/type_checker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ void TypeChecker::Visit(RecordVarDeclNode& record_decl) {
auto symbol = std::make_unique<SymbolEntry>(record_decl.id,
record_decl.type->Clone());

// TODO: type check between fields and initialized members.
for (auto& init : record_decl.inits) {
init->Accept(*this);
}
Expand Down
6 changes: 3 additions & 3 deletions test/typecheck/struct.exp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
6 changes: 3 additions & 3 deletions test/typecheck/union.exp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit d34f0f6

Please sign in to comment.