/** ** \file bind/binder.hh ** \brief Declaration of bind::Binder. **/ #pragma once #include #include #include #include #include #include #include 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 void chunk_visit(ast::Chunk& 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 void visit_dec_bod(D& e); template 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 using t = typename Type::type; misc::scoped_map scoped_map_var_; misc::scoped_map scoped_map_ty_; misc::scoped_map scoped_map_fun_; std::vector loop_; bool is_main_already_ = false; bool in_a_while_ = false; bool in_a_scope_ = false; }; } // namespace bind #include