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/bind/binder.hh | |
Diffstat (limited to 'tiger-compiler/src/bind/binder.hh')
| -rw-r--r-- | tiger-compiler/src/bind/binder.hh | 138 |
1 files changed, 138 insertions, 0 deletions
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> |
