summaryrefslogtreecommitdiff
path: root/tiger-compiler/src/bind/binder.hh
diff options
context:
space:
mode:
Diffstat (limited to 'tiger-compiler/src/bind/binder.hh')
-rw-r--r--tiger-compiler/src/bind/binder.hh138
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>