Skip to content

Commit

Permalink
Create struct and union type
Browse files Browse the repository at this point in the history
  • Loading branch information
leewei05 committed May 10, 2024
1 parent d4e7ba0 commit 3f91bec
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 0 deletions.
45 changes: 45 additions & 0 deletions include/type.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ class Type {
virtual bool IsFunc() const noexcept {
return false;
}
virtual bool IsStruct() const noexcept {
return false;
}
virtual bool IsUnion() const noexcept {
return false;
}

virtual bool IsEqual(const Type& that) const noexcept = 0;
/// @brief A convenience function to compare with a primitive type.
Expand Down Expand Up @@ -168,4 +174,43 @@ class FuncType : public Type {
bool ConvertibleHook_(const Type& that) const noexcept override;
};

class StructType : public Type {
public:
explicit StructType(std::vector<std::unique_ptr<Type>> field_types)
: field_types_{std::move(field_types)} {}

bool IsStruct() const noexcept override {
return true;
}

bool IsEqual(const Type& that) const noexcept override;
std::size_t size() const override;
std::string ToString() const override;
std::unique_ptr<Type> Clone() const override;

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

class UnionType : public Type {
public:
/// @param selected_ The index of the selected field in the union.
explicit UnionType(std::vector<std::unique_ptr<Type>> field_types,
std::size_t selected = 0)
: field_types_{std::move(field_types)}, selected_{selected} {}

bool IsStruct() const noexcept override {
return true;
}

bool IsEqual(const Type& that) const noexcept override;
std::size_t size() const override;
std::string ToString() const override;
std::unique_ptr<Type> Clone() const override;

private:
std::vector<std::unique_ptr<Type>> field_types_;
std::size_t selected_;
};

#endif // TYPE_HPP_
71 changes: 71 additions & 0 deletions src/type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include <utility>
#include <vector>

#include "ast.hpp"

bool Type::IsEqual(PrimitiveType that) const noexcept {
return IsEqual(PrimType{that});
}
Expand Down Expand Up @@ -152,3 +154,72 @@ std::unique_ptr<Type> FuncType::Clone() const {
return std::make_unique<FuncType>(std::move(cloned_return_type),
std::move(cloned_param_types));
}

bool StructType::IsEqual(const Type& that) const noexcept {
if (const auto* that_struct = dynamic_cast<const StructType*>(&that)) {
if (that_struct->size() != that.size()) {
return false;
}
for (auto i = std::size_t{0}, e = field_types_.size(); i < e; ++i) {
if (!that_struct->field_types_.at(i)->IsEqual(*field_types_.at(i))) {
return false;
}
}
return true;
}
return false;
}

std::size_t StructType::size() const {
// TODO: There may be unnamed padding at the end of a structure or union.
auto size = std::size_t{0};
for (auto i = std::size_t{0}, e = field_types_.size(); i < e; ++i) {
size += field_types_.at(i)->size();
}
return size;
}

std::string StructType::ToString() const {
if (field_types_.size() > 0) {
return "definition";
}

return "";
}

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));
}

bool UnionType::IsEqual(const Type& that) const noexcept {
if (const auto* that_union = dynamic_cast<const UnionType*>(&that)) {
return (that_union->selected_ == selected_) &&
(that_union->size() == size());
}
return false;
}

std::size_t UnionType::size() const {
// TODO: There may be unnamed padding at the end of a structure or union.
return field_types_.at(selected_)->size();
}

std::string UnionType::ToString() const {
if (field_types_.size() > 0) {
return "definition";
}

return "";
}

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));
}

0 comments on commit 3f91bec

Please sign in to comment.