summaryrefslogtreecommitdiff
path: root/tiger-compiler/src/type/class.cc
diff options
context:
space:
mode:
authorMartial Simon <msimon_fr@hotmail.com>2025-09-15 01:07:58 +0200
committerMartial Simon <msimon_fr@hotmail.com>2025-09-15 01:07:58 +0200
commit967be9e750221ab2ab783f95df79bb26d290a45e (patch)
tree6802900a5e975f9f68b169f0f503f040056d6952 /tiger-compiler/src/type/class.cc
add: added projectsHEADmain
Diffstat (limited to 'tiger-compiler/src/type/class.cc')
-rw-r--r--tiger-compiler/src/type/class.cc123
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