diff options
Diffstat (limited to 'tiger-compiler/src/type/class.cc')
| -rw-r--r-- | tiger-compiler/src/type/class.cc | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/tiger-compiler/src/type/class.cc b/tiger-compiler/src/type/class.cc new file mode 100644 index 0000000..a1876d3 --- /dev/null +++ b/tiger-compiler/src/type/class.cc @@ -0,0 +1,123 @@ +/** + ** \file type/class.cc + ** \brief Implementation for type/class.hh. + */ + +#include <ostream> + +#include <misc/algorithm.hh> +#include <type/class.hh> +#include <type/visitor.hh> + +namespace type +{ + Class::Class(const Class* super) + : Type() + , id_(fresh_id()) + , super_(super) + , subclasses_() + {} + + void Class::accept(ConstVisitor& v) const { v(*this); } + + void Class::accept(Visitor& v) { v(*this); } + + const Type* Class::attr_type(misc::symbol key) const + { + // FIXME DONE: Some code was deleted here. + const auto& attribute = std::ranges::find_if( + attrs_, + [&key] (const misc::symbol& name) { return name == key; }, + [] (const Attribute& attr) { return attr.name_get(); } + ); + + return attribute != attrs_.end() ? &attribute->type_get() : nullptr; + } + + const Type* Class::meth_type(misc::symbol key) const + { + // FIXME DONE: Some code was deleted here. + const auto& method = std::ranges::find_if( + meths_, + [&key] (const misc::symbol& name) { return name == key; }, + [] (const Method* const meth) { return meth->name_get(); } + ); + + return method != meths_.end() ? &(*method)->type_get() : nullptr; + } + + // FIXME DONE: Some code was deleted here (Find common super class). + const Class* Class::common_root(const Class& other) const + { + // temporary note: i'm tired so maybe the algo sucks ass :c + if (*this == other) + { + return this; + } + + std::vector<const Class*> super_classes; + + for (auto this_sc = this; this_sc != nullptr; this_sc = this_sc->super_) + { + super_classes.push_back(this_sc); + } + + for (auto other_sc = &other; other_sc != nullptr; other_sc = other_sc->super_) + { + if (auto matching = std::ranges::find(super_classes, other_sc); + matching != super_classes.end()) + { + return *matching; + } + } + + return nullptr; + } + + // FIXME DONE: Some code was deleted here (Super class soundness test). + bool Class::sound() const + { + auto reference = this; + std::vector<const Class*> previous; + + while (reference != nullptr) + { + if (std::ranges::find(previous, reference) != previous.end()) + { + return false; + } + + previous.push_back(reference); + reference = reference->super_; + } + + return true; + } + + // FIXME DONE: Some code was deleted here (Special implementation of "compatible_with" for Class). + bool Class::compatible_with(const Type& other) const + { + if (Type::compatible_with(other) || dynamic_cast<const Nil*>(&other)) + { + return true; + } + + const auto ptr = dynamic_cast<const Class*>(&other); + + return ptr && common_root(*ptr); + } + + const Class& Class::object_instance() + { + // FIXME DONE: Some code was deleted here. + static const Class object { nullptr }; + return object; + } + + unsigned Class::fresh_id() + { + static unsigned counter_ = 0; + return counter_++; + } + +} // namespace type |
