LRDE Tiger Compiler
1.34a $Id: 7fef12e1f5fa43449d667a0eec1d837c40fc1202 $
|
Binding identifier uses to their definitions. More...
#include <binder.hh>
Public Types | |
typedef ast::DefaultVisitor | super_type |
Super class type. |
Public Member Functions | |
const misc::error & | error_get () const |
The error handler. | |
virtual void | operator() (ast::LetExp &e) override |
virtual void | operator() (typename Const< Ast >::type &e) |
The entry point: visit e. | |
virtual void | operator() (typename Const< ClassTy >::type &)=0 |
virtual void | operator() (typename Const< MethodCallExp >::type &)=0 |
virtual void | operator() (typename Const< MethodDec >::type &)=0 |
virtual void | operator() (typename Const< ObjectExp >::type &)=0 |
template<class E > | |
void | operator() (E *e) |
Helper to visit nodes manipulated via a pointer. | |
Type and Function declarations | |
template<class D > | |
void | decs_visit (ast::AnyDecs< D > &e) |
template<class D > | |
void | visit_dec_header (D &e) |
Check a Function or Type declaration header. | |
template<class D > | |
void | visit_dec_body (D &e) |
Check a Function or Type declaration body. | |
Visit Variable related nodes. | |
virtual void | operator() (typename Const< SimpleVar >::type &e) override |
virtual void | operator() (typename Const< FieldVar >::type &e) override |
virtual void | operator() (typename Const< SubscriptVar >::type &e) override |
virtual void | operator() (typename Const< CastVar >::type &e) override |
Visit Expression related nodes. | |
virtual void | operator() (typename Const< NilExp >::type &e) override |
virtual void | operator() (typename Const< IntExp >::type &e) override |
virtual void | operator() (typename Const< StringExp >::type &e) override |
virtual void | operator() (typename Const< CallExp >::type &e) override |
virtual void | operator() (typename Const< OpExp >::type &e) override |
virtual void | operator() (typename Const< RecordExp >::type &e) override |
virtual void | operator() (typename Const< SeqExp >::type &e) override |
virtual void | operator() (typename Const< AssignExp >::type &e) override |
virtual void | operator() (typename Const< IfExp >::type &e) override |
virtual void | operator() (typename Const< WhileExp >::type &e) override |
virtual void | operator() (typename Const< ForExp >::type &e) override |
virtual void | operator() (typename Const< BreakExp >::type &) override |
virtual void | operator() (typename Const< LetExp >::type &e) override |
virtual void | operator() (typename Const< ArrayExp >::type &e) override |
virtual void | operator() (typename Const< CastExp >::type &e) override |
virtual void | operator() (typename Const< FieldInit >::type &e) override |
Visit Declaration related nodes. | |
Visiting declarations is simple, but there are many clauses. This is because in Tiger, the declarations are processed by chunks (a chunk of Function declarations, then Var or Type, then ...). So we have to explain
| |
virtual void | operator() (typename Const< DecsList >::type &e) override |
Visit a list of function, type and/or variables declarations. | |
virtual void | operator() (typename Const< Decs >::type &e) |
Visit a Decs chunks. | |
virtual void | operator() (typename Const< VarDecs >::type &e) override |
Visit Var declarations. | |
virtual void | operator() (typename Const< VarDec >::type &e) override |
virtual void | operator() (typename Const< FunctionDec >::type &e) override |
virtual void | operator() (typename Const< TypeDec >::type &e) override |
template<typename DecsType > | |
void | decs_visit (typename Const< DecsType >::type &e) |
Visit a chunk (i.e., a list of Function, Var, and Type decs). | |
Visit Type related nodes. | |
virtual void | operator() (typename Const< NameTy >::type &e) override |
virtual void | operator() (typename Const< RecordTy >::type &e) override |
virtual void | operator() (typename Const< ArrayTy >::type &e) override |
Visit Field related nodes. | |
virtual void | operator() (typename Const< Field >::type &e) override |
Object-related visits. | |
virtual void | operator() (typename Const< ClassTy >::type &e) override |
virtual void | operator() (typename Const< MethodDecs >::type &e) override |
virtual void | operator() (typename Const< MethodDec >::type &e) override |
virtual void | operator() (typename Const< MethodCallExp >::type &e) override |
virtual void | operator() (typename Const< ObjectExp >::type &e) override |
Protected Member Functions | |
template<typename NodeType , typename DefType > | |
void | def_default (NodeType &e, DefType *def) |
template<typename E > | |
void | accept (E *e) |
Error handling | |
void | error (const ast::Ast &loc, const std::string &msg) |
Report an error. | |
template<typename T > | |
void | undeclared (const std::string &k, const T &e) |
template<typename T > | |
void | redefinition (const T &e1, const T &e2) |
Handling the environment | |
virtual void | scope_begin () |
Open a new var, fun, and type scope. | |
virtual void | scope_end () |
Close the latest var, fun, and type scope. |
Binding identifier uses to their definitions.
When the 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 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 names spaces: 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).
Env
models this full environment, i.e., the collection of three tables of symbols: one for functions, one for types, and one for variables. The `scope_begin ()', `scope_end ()', `*get_ ()' and `*put_ ()' are then just handy wrappers around accesses to the tables of symbols.
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 ast::DefaultVisitor
.
Super class type.
|
protectedinherited |
A convenient shortcut for recurring code like this:
However, the drawback of this approach is that it doesn't take care of the constness, and any const violation will be reported within the body of this method, not at its corresponding call site.
We cannot use the misc/select_const.hh approach here, since the compiler cannot resolve a function overloaded or specialized on an associated type of a template. E.g., writing accept like this:
won't work directly. Of course, one can help the compiler, providing it with E
but this is painful.
void bind::Binder::decs_visit | ( | ast::AnyDecs< D > & | e | ) |
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. Therefore there are three methods:
decs_visit
() performs the double traversal, composed of the two following functionsvisit_dec_header
() visit the declaration to register the function in the current environment,visit_dec_body
() visits the body. Of course for functions it also inserts the current arguments in the variable table.It turns out that decs_visit
can be written for both functions and types, but of course, traversals of headers and bodies differ. Check a set of definitions: unique names, browse headers, then bodies.
|
inlineinherited |
Visit a chunk (i.e., a list of Function, Var, and Type decs).
It is exactly the same in the three cases, so the code is factored via a template method.
|
protected |
Set the definition site of a node, if it isn't already set (an existing site won't be overwritten).
e | the bound node |
def | the definition |
|
protected |
Report an error.
const misc::error & bind::Binder::error_get | ( | ) | const |
The error handler.
Referenced by overload::bind().
|
pure virtualinherited |
Implemented in ast::GenNonObjectVisitor< Const >, and ast::GenObjectVisitor< Const >.
|
pure virtualinherited |
Implemented in ast::GenNonObjectVisitor< Const >, and ast::GenObjectVisitor< Const >.
|
pure virtualinherited |
Implemented in ast::GenNonObjectVisitor< Const >, and ast::GenObjectVisitor< Const >.
|
pure virtualinherited |
Implemented in ast::GenNonObjectVisitor< Const >, and ast::GenObjectVisitor< Const >.
|
virtualinherited |
The entry point: visit e.
Reimplemented from ast::GenVisitor< Const >.
Referenced by callgraph::CallGraphVisitor::operator()(), object::Renamer::operator()(), and translate::Translator::operator()().
|
overridevirtualinherited |
Implements ast::GenVisitor< Const >.
|
overridevirtualinherited |
Implements ast::GenVisitor< Const >.
|
overridevirtualinherited |
Implements ast::GenVisitor< Const >.
|
overridevirtualinherited |
Implements ast::GenVisitor< Const >.
|
overridevirtual |
Referenced by object::Binder::operator()().
|
overridevirtualinherited |
Implements ast::GenVisitor< Const >.
|
overridevirtualinherited |
Implements ast::GenVisitor< Const >.
|
overridevirtualinherited |
Implements ast::GenVisitor< Const >.
|
overridevirtualinherited |
Implements ast::GenVisitor< Const >.
|
inherited |
Helper to visit nodes manipulated via a pointer.
|
overridevirtualinherited |
Implements ast::GenVisitor< Const >.
|
overridevirtualinherited |
Implements ast::GenVisitor< Const >.
|
overridevirtualinherited |
Implements ast::GenVisitor< Const >.
|
overridevirtualinherited |
Implements ast::GenVisitor< Const >.
|
overridevirtualinherited |
Implements ast::GenVisitor< Const >.
|
overridevirtualinherited |
Implements ast::GenVisitor< Const >.
|
overridevirtualinherited |
Implements ast::GenVisitor< Const >.
|
overridevirtualinherited |
Implements ast::GenVisitor< Const >.
|
overridevirtualinherited |
Implements ast::GenVisitor< Const >.
|
overridevirtualinherited |
Implements ast::GenVisitor< Const >.
|
overridevirtualinherited |
Implements ast::GenVisitor< Const >.
|
overridevirtualinherited |
Implements ast::GenVisitor< Const >.
|
overridevirtualinherited |
Implements ast::GenVisitor< Const >.
|
overridevirtualinherited |
Implements ast::GenVisitor< Const >.
|
overridevirtualinherited |
Implements ast::GenVisitor< Const >.
|
overridevirtualinherited |
Implements ast::GenVisitor< Const >.
|
overridevirtualinherited |
Implements ast::GenVisitor< Const >.
|
overridevirtualinherited |
Visit a list of function, type and/or variables declarations.
Implements ast::GenVisitor< Const >.
References misc::for_each().
|
virtualinherited |
Visit a Decs chunks.
|
overridevirtualinherited |
Visit Var declarations.
Implements ast::GenVisitor< Const >.
|
overridevirtualinherited |
Implements ast::GenVisitor< Const >.
|
overridevirtualinherited |
Implements ast::GenVisitor< Const >.
|
overridevirtualinherited |
Implements ast::GenVisitor< Const >.
|
overridevirtualinherited |
Implements ast::GenVisitor< Const >.
|
overridevirtualinherited |
Implements ast::GenVisitor< Const >.
|
overridevirtualinherited |
Implements ast::GenVisitor< Const >.
|
overridevirtualinherited |
Implements ast::GenVisitor< Const >.
|
protected |
Report a symbol redefinition.
e1 | the first occurrence, the original |
e2 | the invalid duplicate |
|
protectedvirtual |
Open a new var, fun, and type scope.
Reimplemented in overload::Binder.
Referenced by object::Binder::operator()(), and overload::Binder::scope_begin().
|
protectedvirtual |
Close the latest var, fun, and type scope.
Reimplemented in overload::Binder.
Referenced by object::Binder::operator()(), and overload::Binder::scope_end().
|
protected |
Report an undefined symbol.
k | the kind of this node (function, variable, type) |
e | the node using an undefined name |
Referenced by overload::Binder::operator()().
void bind::Binder::visit_dec_body | ( | D & | e | ) |
Check a Function or Type declaration body.
Reimplemented in object::Binder.
void bind::Binder::visit_dec_header | ( | D & | e | ) |
Check a Function or Type declaration header.
Reimplemented in object::Binder.