1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
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>
|