summaryrefslogtreecommitdiff
path: root/tiger-compiler/src/bind
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/bind
add: added projectsHEADmain
Diffstat (limited to 'tiger-compiler/src/bind')
-rw-r--r--tiger-compiler/src/bind/binder.cc183
-rw-r--r--tiger-compiler/src/bind/binder.hh138
-rw-r--r--tiger-compiler/src/bind/binder.hxx124
-rw-r--r--tiger-compiler/src/bind/libbind.cc31
-rw-r--r--tiger-compiler/src/bind/libbind.hh29
-rw-r--r--tiger-compiler/src/bind/local.am17
-rw-r--r--tiger-compiler/src/bind/renamer.cc63
-rw-r--r--tiger-compiler/src/bind/renamer.hh62
-rw-r--r--tiger-compiler/src/bind/renamer.hxx24
-rw-r--r--tiger-compiler/src/bind/tasks.cc34
-rw-r--r--tiger-compiler/src/bind/tasks.hh42
11 files changed, 747 insertions, 0 deletions
diff --git a/tiger-compiler/src/bind/binder.cc b/tiger-compiler/src/bind/binder.cc
new file mode 100644
index 0000000..171e199
--- /dev/null
+++ b/tiger-compiler/src/bind/binder.cc
@@ -0,0 +1,183 @@
+/**
+ ** \file bind/binder.cc
+ ** \brief Implementation for bind/binder.hh.
+ */
+
+#include <ast/all.hh>
+#include <bind/binder.hh>
+
+#include <misc/contract.hh>
+
+namespace bind
+{
+ /*-----------------.
+ | Error handling. |
+ `-----------------*/
+
+ /// The error handler.
+ const misc::error& Binder::error_get() const { return error_; }
+
+ // FIXME DONE: Some code was deleted here.
+ void Binder::operator()(ast::SimpleVar& e)
+ {
+ ast::VarDec* init = scoped_map_var_.get(e.name_get());
+ if (init == nullptr)
+ {
+ err_undef(e.location_get(), e.name_get());
+ return;
+ }
+ e.def_set(init);
+ }
+
+ void Binder::operator()(ast::CallExp& e)
+ {
+ ast::FunctionDec* init = scoped_map_fun_.get(e.name_get());
+ if (init == nullptr)
+ {
+ err_undef(e.location_get(), e.name_get());
+ return;
+ }
+ e.def_set(init);
+ super_type::operator()(e);
+ }
+
+ void Binder::operator()(ast::NameTy& e)
+ {
+ misc::symbol test_string("string");
+ misc::symbol test_int("int");
+ if (e.name_get() == test_int || e.name_get() == test_string)
+ {
+ auto init = scoped_map_ty_.get(e.name_get());
+ e.def_set(init);
+ }
+ else
+ {
+ auto init = scoped_map_ty_.get(e.name_get());
+ if (init == nullptr)
+ {
+ err_type_undef(e.location_get(), e.name_get());
+ return;
+ }
+ e.def_set(init);
+ }
+ }
+
+ void Binder::operator()(ast::WhileExp& e)
+ {
+ bool actual = in_a_while_;
+ e.test_get().accept(*this);
+ loop_.emplace_back(&e);
+ in_a_while_ = true;
+ begin_scope();
+ e.body_get().accept(*this);
+ end_scope();
+ loop_.pop_back();
+ in_a_while_ = actual;
+ }
+
+ void Binder::operator()(ast::ForExp& e)
+ {
+ bool actual = in_a_while_;
+ begin_scope();
+ in_a_while_ = true;
+ e.vardec_get().accept(*this);
+ e.hi_get().accept(*this);
+ loop_.emplace_back(&e);
+ e.body_get().accept(*this);
+ end_scope();
+ loop_.pop_back();
+ in_a_while_ = actual;
+ }
+
+ void Binder::operator()(ast::BreakExp& e)
+ {
+ if (loop_.empty() || !in_a_while_)
+ {
+ error_ << misc::error::error_type::bind;
+ error_ << e.location_get() << ": 'break' outside any loop\n";
+ }
+ else
+ {
+ e.def_set(loop_.back());
+ }
+ }
+
+ //Declaration of function
+
+ void Binder::operator()(ast::VarDec& e)
+ {
+ bool actual = in_a_while_;
+ scoped_map_var_.put(e.name_get(), &e);
+ in_a_while_ = false;
+ super_type::operator()(e);
+ in_a_while_ = actual;
+ }
+
+ void Binder::operator()(ast::FunctionChunk& e)
+ {
+ chunk_visit<ast::FunctionDec>(e);
+ }
+
+ void Binder::operator()(ast::TypeChunk& e)
+ {
+ chunk_visit<ast::TypeDec>(e);
+ }
+
+ template <class D> void Binder::chunk_visit(ast::Chunk<D>& e)
+ {
+ misc::scoped_map<const misc::symbol, D*> def = misc::scoped_map<const misc::symbol, D*>();
+ for (auto machala : e)
+ {
+ visit_dec_head<D>(*machala);
+ }
+ for (auto dec : e)
+ {
+ auto init = def.get(dec->name_get());
+ if (init == nullptr)
+ {
+ def.put(dec->name_get(), dec);
+ visit_dec_bod<D>(*dec);
+ }
+ else
+ {
+ err_ddec(dec->location_get(), init->location_get(), dec->name_get());
+ }
+ }
+ }
+
+ void Binder::operator()(ast::FunctionDec& e)
+ {
+ if (e.name_get() == "_main")
+ {
+ if (is_main_already_)
+ {
+ error_ << misc::error::error_type::bind;
+ error_ << "Un deuxieme _main??????\n";
+ return;
+ }
+ is_main_already_ = true;
+ if (in_a_scope_)
+ {
+ error_ << misc::error::error_type::bind;
+ error_ << "BRADDOCK, je vous préviens, attention ou vous mettez votre _main!!";
+ return;
+ }
+ }
+ scoped_map_fun_.put(e.name_get(), &e);
+ bool scope = in_a_scope_;
+ bool actual = in_a_while_;
+ in_a_while_ = false;
+ in_a_scope_ = true;
+ this->accept(e.result_get());
+ body_func(e);
+ in_a_while_ = actual;
+ in_a_scope_ = scope;
+ }
+
+ void Binder::operator()(ast::TypeDec& e)
+ {
+ scoped_map_ty_.put(e.name_get(), &e);
+ super_type::operator()(e);
+ }
+
+} // namespace bind
diff --git a/tiger-compiler/src/bind/binder.hh b/tiger-compiler/src/bind/binder.hh
new file mode 100644
index 0000000..f5a4ab3
--- /dev/null
+++ b/tiger-compiler/src/bind/binder.hh
@@ -0,0 +1,138 @@
+/**
+ ** \file bind/binder.hh
+ ** \brief Declaration of bind::Binder.
+ **/
+
+#pragma once
+
+#include <unordered_map>
+
+#include <ast/assert-visitor.hh>
+#include <ast/default-visitor.hh>
+#include <ast/object-visitor.hh>
+
+#include <misc/error.hh>
+#include <misc/fwd.hh>
+#include <misc/scoped-map.hh>
+
+namespace bind
+{
+ /** \brief Binding identifier uses to their definitions.
+ **
+ ** When the \c Binder finds a declaration (of a variable/formal, function,
+ ** or type), it keeps a pointer to it. When it finds a use, it binds it
+ ** to its definition, i.e., it annotates it with a pointer to the
+ ** declaration.
+ **
+ ** The \c Binder diagnoses identifier use errors (invalid multiple
+ ** definitions, unbound identifiers etc.).
+ **
+ ** Since identifier bindings depend on scopes, it needs an environment.
+ **
+ ** In the original Tiger by A. Appel, there are two namespaces: on
+ ** the one hand types, and on the other hand functions and variables.
+ ** Here, at EPITA, we will use three name spaces: we will allow
+ ** variables and functions with the same name.
+ **
+ ** Moreover, object constructs make use of two additional name
+ ** spaces: one for class attributes and one for methods (actually
+ ** these two name spaces only live within the scope of a class).
+ **
+ ** Note that this Binder is mainly doing nothing: it is just
+ ** interested in declarations and uses. To avoid writing
+ ** all the methods that `do nothing but walk', it derives
+ ** from \c ast::DefaultVisitor.
+ **/
+ class Binder
+ : public ast::DefaultVisitor
+ , public ast::ObjectVisitor
+ , public ast::AssertVisitor
+ {
+ public:
+ /// Super class type.
+ using super_type = ast::DefaultVisitor;
+ /// Import all the overloaded \c operator() methods.
+ using super_type::operator();
+
+ /// The error handler.
+ const misc::error& error_get() const;
+
+ // FIXME DONE: Some code was deleted here.
+
+ void operator()(ast::SimpleVar& e) override;
+ void operator()(ast::CallExp& e) override;
+ void operator()(ast::WhileExp& e) override;
+ void operator()(ast::ForExp& e) override;
+ void operator()(ast::BreakExp&) override;
+ void operator()(ast::NameTy& e) override;
+
+ // ---------------- //
+ // Visiting /Dec/. //
+ // ---------------- //
+
+ /// Visit Var declarations.
+ void operator()(ast::VarDec& e) override;
+
+ /// Visit Chunk
+ template <class D> void chunk_visit(ast::Chunk<D>& e);
+
+ /// Visit Function declarations.
+ void operator()(ast::FunctionChunk& e) override;
+ void operator()(ast::FunctionDec& e) override;
+ /// Visit Type declarations.
+ void operator()(ast::TypeChunk& e) override;
+ void operator()(ast::TypeDec& e) override;
+
+ Binder();
+
+
+ /// \name Type and Function declarations
+ /// \{
+
+ /// When traversing a function (or a type) we both have to bind
+ /// its body (i.e., we need to enter a new scope and push the
+ /// arguments in it), *and* we have to store the function's
+ /// declaration in the current scope (so that other functions can
+ /// call it).
+
+ /// We first introduce the function's name in the outer
+ /// environment so that the function can call itself recursively.
+ /// In the mean time, we also check for uniqueness. Then, as a
+ /// second step, we process the contents of all the functions
+ /// belonging to the current chunk.
+
+ // FIXME DONE: Some code was deleted here.
+ //function a effect sur les scoped map
+ void body_func(ast::FunctionDec& e);
+ void begin_scope();
+ void end_scope();
+ template <class D> void visit_dec_bod(D& e);
+ template <class D> void visit_dec_head(D& e);
+
+
+ //function that handles error
+ void err_undef(const ast::Location& loc, const misc::symbol& name);
+ void err_type_undef(const ast::Location& loc, const misc::symbol& name);
+ void err_ddec(const ast::Location& loc,
+ const ast::Location& first,
+ const misc::symbol& name);
+ void is_there__main(void);
+
+ protected:
+ /// Binding errors handler.
+ misc::error error_;
+
+ // FIXME DONE: Some code was deleted here (More members).
+ // J'ai copier pretty print en sah
+ template <typename Type> using t = typename Type::type;
+ misc::scoped_map<const misc::symbol, ast::VarDec*> scoped_map_var_;
+ misc::scoped_map<const misc::symbol, ast::TypeDec*> scoped_map_ty_;
+ misc::scoped_map<const misc::symbol, ast::FunctionDec*> scoped_map_fun_;
+ std::vector<ast::Exp*> loop_;
+ bool is_main_already_ = false;
+ bool in_a_while_ = false;
+ bool in_a_scope_ = false;
+ };
+} // namespace bind
+
+#include <bind/binder.hxx>
diff --git a/tiger-compiler/src/bind/binder.hxx b/tiger-compiler/src/bind/binder.hxx
new file mode 100644
index 0000000..0facad9
--- /dev/null
+++ b/tiger-compiler/src/bind/binder.hxx
@@ -0,0 +1,124 @@
+/**
+ ** \file bind/binder.hxx
+ ** \brief Inline methods of bind::Binder.
+ **/
+
+// FIXME DONE: Some code was deleted here.
+
+#pragma once
+
+#include <bind/binder.hh>
+
+namespace bind
+{
+ inline Binder::Binder()
+ {
+ scoped_map_fun_ = misc::scoped_map<const misc::symbol, ast::FunctionDec*>();
+ scoped_map_var_ = misc::scoped_map<const misc::symbol, ast::VarDec*>();
+ scoped_map_ty_ = misc::scoped_map<const misc::symbol, ast::TypeDec*>();
+ loop_ = std::vector<ast::Exp*>();
+ error_ = misc::error();
+ }
+
+ inline void Binder::body_func(ast::FunctionDec& e)
+ {
+ begin_scope();
+ bool tmp = in_a_scope_;
+ in_a_scope_ = true;
+ e.formals_get().accept(*this);
+ this->accept(e.body_get());
+ in_a_scope_ = tmp;
+ end_scope();
+ }
+
+ template <>
+ inline void Binder::visit_dec_head<ast::FunctionDec>(ast::FunctionDec& e)
+ {
+ if (e.name_get() == "_main")
+ {
+ if (is_main_already_)
+ {
+ error_ << misc::error::error_type::bind;
+ error_ << "Un deuxieme _main??????\n";
+ return;
+ }
+ is_main_already_ = true;
+ if (in_a_scope_)
+ {
+ error_ << misc::error::error_type::bind;
+ error_ << "BRADDOCK, je vous préviens, attention ou vous mettez votre _main!!";
+ return;
+ }
+ }
+ scoped_map_fun_.put(e.name_get(), &e);
+ }
+
+ template <>
+ inline void Binder::visit_dec_bod<ast::FunctionDec>(ast::FunctionDec& e)
+ {
+ bool actual = in_a_while_;
+ in_a_while_ = false;
+ this->accept(e.result_get());
+ body_func(e);
+ in_a_while_ = actual;
+ }
+
+ /// @brief visit header so the Ast can know this type exist
+ /// @param e an Dec of a funcrion or ast
+ template <>
+ inline void Binder::visit_dec_head<ast::TypeDec>(ast::TypeDec& e)
+ {
+ scoped_map_ty_.put(e.name_get(), &e);
+ }
+
+ template <>
+ inline void Binder::visit_dec_bod<ast::TypeDec>(ast::TypeDec& e)
+ {
+ super_type::operator()(e);
+ }
+
+ inline void Binder::begin_scope()
+ {
+ scoped_map_fun_.scope_begin();
+ scoped_map_ty_.scope_begin();
+ scoped_map_var_.scope_begin();
+ }
+
+ inline void Binder::end_scope()
+ {
+ scoped_map_fun_.scope_end();
+ scoped_map_ty_.scope_end();
+ scoped_map_var_.scope_end();
+ }
+
+ inline void Binder::err_undef(const ast::Location& loc, const misc::symbol& name)
+ {
+ error_ << misc::error::error_type::bind;
+ error_ << loc << ": undeclared variable: " << name << "\n";
+ }
+
+ inline void Binder::err_type_undef(const ast::Location& loc, const misc::symbol& name)
+ {
+ error_ << misc::error::error_type::bind;
+ error_ << loc << ": undeclared type: " << name << "\n";
+ }
+
+ inline void Binder::is_there__main()
+ {
+ if (!is_main_already_)
+ {
+ error_ << misc::error::error_type::bind;
+ error_ << "Bah bro il est ou ton _main??????\n";
+ }
+ }
+
+ inline void Binder::err_ddec(const ast::Location& loc,
+ const ast::Location& first,
+ const misc::symbol& name)
+ {
+ error_ << misc::error::error_type::bind;
+ error_ << loc << ": redefinition: " << name << "\n";
+ error_ << first << ": first definition\n";
+ }
+
+} // namespace bind \ No newline at end of file
diff --git a/tiger-compiler/src/bind/libbind.cc b/tiger-compiler/src/bind/libbind.cc
new file mode 100644
index 0000000..63dc4ee
--- /dev/null
+++ b/tiger-compiler/src/bind/libbind.cc
@@ -0,0 +1,31 @@
+/**
+ ** \file bind/libbind.cc
+ ** \brief Define exported bind functions.
+ */
+
+
+// FIXME DONE: Some code was deleted here.
+
+#include <ast/ast.hh>
+#include <misc/error.hh>
+
+#include "renamer.hh"
+#include "binder.hh"
+
+namespace bind
+{
+ misc::error bind(ast::ChunkList* d)
+ {
+ Binder bdc = Binder();
+ bdc(d);
+ bdc.is_there__main();
+ return bdc.error_get();
+ }
+
+ misc::error rename(ast::Ast& tree)
+ {
+ Renamer renamer;
+ renamer(tree);
+ return misc::error{};
+ }
+}
diff --git a/tiger-compiler/src/bind/libbind.hh b/tiger-compiler/src/bind/libbind.hh
new file mode 100644
index 0000000..f4b8bb5
--- /dev/null
+++ b/tiger-compiler/src/bind/libbind.hh
@@ -0,0 +1,29 @@
+/**
+** \file bind/libbind.hh
+ ** \brief Interface of the bind module.
+ */
+
+// FIXME DONE: Some code was deleted here.
+
+#pragma once
+
+#include <ast/fwd.hh>
+#include <misc/error.hh>
+#include <bind/binder.hh>
+
+namespace bind
+{
+ /// \brief Bind the whole ast in place, return the error code
+ ///
+ /// \param last the ast you want to bind
+ ///
+ /// \return a misc::error that serve to indicate possible failure
+ misc::error bind(ast::ChunkList* d);
+
+ /// \brief Rename the whole ast in place
+ ///
+ /// \param ast the ast you want to rename
+ ///
+ /// \return a misc::error that serve to indicate possible failure
+ misc::error rename(ast::Ast& ast);
+} // namespace bind
diff --git a/tiger-compiler/src/bind/local.am b/tiger-compiler/src/bind/local.am
new file mode 100644
index 0000000..ae4d7b4
--- /dev/null
+++ b/tiger-compiler/src/bind/local.am
@@ -0,0 +1,17 @@
+## bind module.
+
+src_libtc_la_SOURCES += \
+ %D%/binder.hh %D%/binder.hxx %D%/binder.cc \
+ %D%/libbind.hh %D%/libbind.cc
+src_libtc_la_SOURCES += \
+ %D%/renamer.hh %D%/renamer.hxx %D%/renamer.cc
+
+
+TASKS += %D%/tasks.hh %D%/tasks.cc
+
+## ------- ##
+## Tests. ##
+## ------- ##
+
+check_PROGRAMS += %D%/test-bind
+%C%_test_bind_LDADD = src/libtc.la
diff --git a/tiger-compiler/src/bind/renamer.cc b/tiger-compiler/src/bind/renamer.cc
new file mode 100644
index 0000000..1f13de0
--- /dev/null
+++ b/tiger-compiler/src/bind/renamer.cc
@@ -0,0 +1,63 @@
+/**
+ ** \file bind/renamer.cc
+ ** \brief Implementation of bind::Renamer.
+ */
+
+#include <bind/renamer.hh>
+
+namespace bind
+{
+ using namespace ast;
+
+ // FIXME DONE: Some code was deleted here.
+
+ void Renamer::operator()(ast::VarDec& e)
+ {
+ if (renames_.find(&e) != renames_.end())
+ super_type::operator()(e);
+ new_name_(&e);
+ e.name_set(renames_.at(&e));
+ super_type::operator()(e);
+ }
+ void Renamer::operator()(ast::TypeDec& e)
+ {
+ if (renames_.find(&e) != renames_.end())
+ super_type::operator()(e);
+ new_name_(&e);
+ e.name_set(renames_.at(&e));
+ super_type::operator()(e);
+ }
+ void Renamer::operator()(ast::FunctionDec& e)
+ {
+ if (e.body_get() == nullptr || e.name_get() == "_main"
+ || renames_.find(&e) != renames_.end())
+ {
+ super_type::operator()(e);
+ return;
+ }
+ new_name_(&e);
+ e.name_set(renames_.at(&e));
+ super_type::operator()(e);
+ }
+ void Renamer::operator()(ast::SimpleVar& e)
+ {
+ if (renames_.find(e.def_get()) != renames_.end())
+ e.name_set(renames_.at(e.def_get()));
+ }
+ void Renamer::operator()(ast::NameTy& e)
+ {
+ if (renames_.find(e.def_get()) != renames_.end())
+ e.name_set(renames_.at(e.def_get()));
+ }
+ void Renamer::operator()(ast::CallExp& e)
+ {
+ if (e.def_get() == nullptr || e.def_get()->body_get() == nullptr
+ || e.name_get() == "_main")
+ super_type::operator()(e);
+ else
+ {
+ e.name_set(renames_.at(e.def_get()));
+ super_type::operator()(e);
+ }
+ }
+} // namespace bind
diff --git a/tiger-compiler/src/bind/renamer.hh b/tiger-compiler/src/bind/renamer.hh
new file mode 100644
index 0000000..f4a1e82
--- /dev/null
+++ b/tiger-compiler/src/bind/renamer.hh
@@ -0,0 +1,62 @@
+/**
+ ** \file bind/renamer.hh
+ ** \brief Implementation of bind::Renamer.
+ */
+
+#pragma once
+
+#include <map>
+#include <ast/default-visitor.hh>
+#include <ast/non-assert-visitor.hh>
+#include <ast/non-object-visitor.hh>
+
+namespace bind
+{
+ /// Perform identifier renaming within an AST (in place),
+ /// without support for objects.
+ class Renamer
+ : public ast::DefaultVisitor
+ , public ast::NonObjectVisitor
+ , public ast::NonAssertVisitor
+ {
+ public:
+ using super_type = ast::DefaultVisitor;
+
+ // Import overloaded virtual functions.
+ using super_type::operator();
+
+ // FIXME DONE: Some code was deleted here.
+
+ // Visit methods.
+ /// \brief Process a declaration body or a usage site.
+ ///
+ /// \a def is the definition site of \e (must be equal to
+ /// \a e if it is a Dec node).
+ template <class E, class Def> void visit(E& e, const Def* def);
+
+ /// \name Visiting definition sites.
+ /// \{
+ // FIXME DONE: Some code was deleted here.
+ void operator()(ast::VarDec& e) override;
+ void operator()(ast::TypeDec& e) override;
+ void operator()(ast::FunctionDec& e) override;
+ /// \}
+
+ /// \name Visiting usage sites.
+ /// \{
+ // FIXME DONE: Some code was deleted here.
+ void operator()(ast::SimpleVar& e) override;
+ void operator()(ast::NameTy& e) override;
+ void operator()(ast::CallExp& e) override;
+ /// \}
+
+ private:
+ // FIXME DONE: Some code was deleted here.
+ std::map<const ast::Dec*, misc::symbol> renames_;
+
+ void new_name_(const ast::Dec*);
+ };
+
+} // namespace bind
+
+#include <bind/renamer.hxx>
diff --git a/tiger-compiler/src/bind/renamer.hxx b/tiger-compiler/src/bind/renamer.hxx
new file mode 100644
index 0000000..f01b7c8
--- /dev/null
+++ b/tiger-compiler/src/bind/renamer.hxx
@@ -0,0 +1,24 @@
+/**
+ ** \file bind/renamer.hxx
+ ** \brief Template methods of bind::Renamer.
+ */
+
+#pragma once
+
+#include <sstream>
+#include <bind/renamer.hh>
+
+namespace bind
+{
+ // FIXME DONE: Some code was deleted here.
+ inline void Renamer::new_name_(const ast::Dec* dec)
+ {
+ renames_.insert_or_assign(dec, misc::symbol::fresh(dec->name_get()));
+ }
+
+ template <class E, class Def> void Renamer::visit(E& e, const Def* def)
+ {
+ // FIXME DONE: Some code was deleted here.
+ operator()(e);
+ }
+} // namespace bind
diff --git a/tiger-compiler/src/bind/tasks.cc b/tiger-compiler/src/bind/tasks.cc
new file mode 100644
index 0000000..6492463
--- /dev/null
+++ b/tiger-compiler/src/bind/tasks.cc
@@ -0,0 +1,34 @@
+/**
+ ** \file bind/tasks.cc
+ ** \brief Bind module tasks implementation.
+ */
+
+// FIXME DONE: Some code was deleted here.
+#include <ast/libast.hh>
+#include <ast/tasks.hh>
+#include <bind/libbind.hh>
+#define DEFINE_TASKS 1
+#include <bind/tasks.hh>
+#undef DEFINE_TASKS
+#include <common.hh>
+
+namespace bind::tasks
+{
+
+ void bind() {
+ misc::error& program_error = task_error();
+ program_error << bind::bind(ast::tasks::the_program.get());
+ program_error.exit_on_error();
+ }
+
+ void display_bind() {
+ ast::bindings_display(std::cout) = true;
+ }
+
+ void rename() {
+ misc::error& program_error = task_error();
+ program_error << bind::rename(*ast::tasks::the_program);
+ program_error.exit_on_error();
+ }
+
+}
diff --git a/tiger-compiler/src/bind/tasks.hh b/tiger-compiler/src/bind/tasks.hh
new file mode 100644
index 0000000..5ad970d
--- /dev/null
+++ b/tiger-compiler/src/bind/tasks.hh
@@ -0,0 +1,42 @@
+/**
+ ** \file bind/tasks.hh
+ ** \brief Bind module related tasks.
+ */
+
+// FIXME DONE: Some code was deleted here.
+#pragma once
+
+#include <task/libtask.hh>
+
+namespace bind::tasks
+{
+ TASK_GROUP("4. Binding");
+
+ // Binding tasks
+ DISJUNCTIVE_TASK_DECLARE("bound",
+ "default the binding to Tiger "
+ "(without objects nor overloading)",
+ "bindings-compute"
+ " combine-bindings-compute"
+ " object-bindings-compute"
+ " assert-bindings-compute");
+
+ TASK_DECLARE("b|bindings-compute",
+ "bind the name uses to their definitions",
+ bind,
+ "parse");
+
+ TASK_DECLARE("B|bindings-display",
+ "enable the bindings display in the next --ast-display "
+ "invocation. does not imply --bindings-compute",
+ display_bind,
+ "");
+
+ // Renaming tasks
+
+ TASK_DECLARE("rename",
+ "rename identifiers",
+ rename,
+ "bindings-compute");
+
+}