diff options
| author | Martial Simon <msimon_fr@hotmail.com> | 2025-09-15 01:07:58 +0200 |
|---|---|---|
| committer | Martial Simon <msimon_fr@hotmail.com> | 2025-09-15 01:07:58 +0200 |
| commit | 967be9e750221ab2ab783f95df79bb26d290a45e (patch) | |
| tree | 6802900a5e975f9f68b169f0f503f040056d6952 /tiger-compiler/src/object/renamer.cc | |
Diffstat (limited to 'tiger-compiler/src/object/renamer.cc')
| -rw-r--r-- | tiger-compiler/src/object/renamer.cc | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/tiger-compiler/src/object/renamer.cc b/tiger-compiler/src/object/renamer.cc new file mode 100644 index 0000000..0abae10 --- /dev/null +++ b/tiger-compiler/src/object/renamer.cc @@ -0,0 +1,142 @@ +/** + ** \file object/renamer.cc + ** \brief Implementation of object::Renamer. + */ + +#include <memory> + +#include <object/renamer.hh> + +namespace object +{ + using namespace ast; + + Renamer::Renamer() + : super_type() + , class_names_(new class_names_type) + , within_class_ty_(false) + { + // Give a name to the built-in class Object. + misc::put(*class_names_, &type::Class::object_instance(), "Object"); + } + + /** + * Get the node's type as a class, if it references one + * @param ast Any typable node + * @return The node's referenced class type if there is one, nullptr if not + */ + static inline const type::Class* get_referenced_class_type(const Typable& ast) + { + return dynamic_cast<const type::Class*>(&ast.type_get()->actual()); + } + + /*----------------------------. + | Visiting definition sites. | + `----------------------------*/ + + void Renamer::operator()(ast::VarDec& e) + { + if (within_class_ty_) + // Don't rename class attributes. + super_type::super_type::operator()(e); + else + // But still rename other variable declarations. + super_type::operator()(e); + } + + void Renamer::operator()(ast::MethodChunk& e) + { + // FIXME DONE: Some code was deleted here (Just recurse on children nodes). + chunk_visit<MethodChunk>(e); + } + + void Renamer::operator()(ast::MethodDec& e) + { + bool saved_within_class_ty = within_class_ty_; + within_class_ty_ = false; + /* We can't call bind::Binder::visit directly, because this method + delegates the recursion task to DefaultVisitor, which doesn't + have a proper operator() for MethodDec. This visitor however + knows how to handle a FunctionDec; therefore we upcast the + MethodDec to a FunctionDec before visiting it. */ + ast::FunctionDec& fundec = e; + visit(fundec, &fundec); + within_class_ty_ = saved_within_class_ty; + } + + void Renamer::operator()(ast::TypeDec& e) + { + // Rename. + // FIXME DONE: Some code was deleted here. + if (class_names_->find(get_referenced_class_type(e)) == class_names_->end()) + super_type::operator()(e); + + // Collect the name of the classes. + // FIXME DONE: Some code was deleted here. + if (auto classtype = get_referenced_class_type(e)) + { + class_names_->insert(std::make_pair(classtype, e.name_get())); + } + } + + /*-----------------------. + | Visiting usage sites. | + `-----------------------*/ + + void Renamer::operator()(ast::MethodCallExp& e) + { + // FIXME DONE: Some code was deleted here. + super_type::operator()(e.object_get()); + e.name_set(e.def_get()->name_get()); + CallExp& upcast = e; + precondition(upcast.def_get() == nullptr); + super_type::operator()(upcast); + } + + /*--------------------------------------. + | Visiting other object-related nodes. | + `--------------------------------------*/ + + void Renamer::operator()(ast::ClassTy& e) + { + // FIXME DONE: Some code was deleted here. + bool saved_within_class_ty = within_class_ty_; + within_class_ty_ = true; + if (e.super_get().name_get() != "Object") + e.super_get().name_set(e.super_get().def_get()->name_get()); + super_type::operator()(e.chunks_get()); + within_class_ty_ = saved_within_class_ty; + } + + void Renamer::operator()(ast::ObjectExp& e) + { + // FIXME DONE: Some code was deleted here. + if (auto name = class_names_->find(get_referenced_class_type(e)); + name != class_names_->end()) + e.type_name_get().name_set(name->second); + else + { + this->accept(e.type_name_get().def_get()); + e.type_name_get().name_set(e.type_name_get().def_get()->name_get()); + class_names_->insert( + std::make_pair(get_referenced_class_type(e), + e.type_name_get().name_get())); + } + } + + void Renamer::operator()(ast::LetExp& e) + { + // FIXME DONE: Some code was deleted here. + bool saved_within_class_ty = within_class_ty_; + within_class_ty_ = false; + super_type::operator()(e); + within_class_ty_ = saved_within_class_ty; + } + + /*--------------. + | Class names. | + `--------------*/ + + class_names_type* Renamer::class_names_get() const { return class_names_; } + +} // namespace object |
