summaryrefslogtreecommitdiff
path: root/tiger-compiler/src/escapes/escapes-visitor.hh
diff options
context:
space:
mode:
Diffstat (limited to 'tiger-compiler/src/escapes/escapes-visitor.hh')
-rw-r--r--tiger-compiler/src/escapes/escapes-visitor.hh75
1 files changed, 75 insertions, 0 deletions
diff --git a/tiger-compiler/src/escapes/escapes-visitor.hh b/tiger-compiler/src/escapes/escapes-visitor.hh
new file mode 100644
index 0000000..3b4023f
--- /dev/null
+++ b/tiger-compiler/src/escapes/escapes-visitor.hh
@@ -0,0 +1,75 @@
+/**
+ ** \file escapes/escapes-visitor.hh
+ ** \brief Compute the escapes.
+ **
+ ** Variables and formals of a function may escape, i.e., be accessed
+ ** by an inner function.
+ **
+ ** When the semantic analysis finds a declaration of variable or
+ ** formal FOO, it needs to know whether it escapes or not. This
+ ** requires an additional pass, before the semantic analysis, just to
+ ** spot the potential escapes of FOO.
+ **
+ ** In order to pass the result to the semantic analysis which walks
+ ** across the ast, the most natural and easy solution consists in
+ ** tagging the various VarDec and Field.
+ **
+ ** Now, how shall we compute the escapes?
+ ** The answer is obvious: we need to walk the ast, searching for variables
+ ** declared then accessed by an inner function.
+ **
+ ** If a variable is accessed from a nested function
+ **
+ ** 2è possibilité :
+ ** - Aucune n'échappe
+ ** - Echappe si accessed dans une fonction nestée
+ ** Attention
+ */
+
+#pragma once
+
+#include <map>
+
+#include <ast/default-visitor.hh>
+#include <ast/non-assert-visitor.hh>
+#include <ast/non-object-visitor.hh>
+
+namespace escapes
+{
+ /** \brief Compute the escapes.
+ **
+ ** The EscapeVisitor is extremely similar to type::TypeChecker:
+ ** in its course of operation it must relate uses to
+ ** definitions. Therefore it will be run after the bind::Binder.
+ ** It also needs auxiliary information about the definitions (their
+ ** depth): a simple map suffices, since scoping issues were handled
+ ** by the bind::Binder.
+ **
+ ** Note that this EscapesVisitor is mainly doing nothing: it is just
+ ** interested in declaration and uses of variables/formals (and, of
+ ** course, function declaration...). It would be somewhat stupid to
+ ** write all the methods that `do nothing but walk'. This is why we
+ ** will inherit from the non const ast::DefaultVisitor.
+ **/
+ class EscapesVisitor
+ : public ast::DefaultVisitor
+ , public ast::NonObjectVisitor
+ , public ast::NonAssertVisitor
+ {
+ public:
+ /// Super class type.
+ using super_type = ast::DefaultVisitor;
+ /// Import all the overloaded visit methods.
+ using super_type::operator();
+
+ // FIXME DONE: Some code was deleted here.
+ void operator()(ast::SimpleVar& e) override;
+ void operator()(ast::VarDec& e) override;
+ void operator()(ast::FunctionDec& e) override;
+ protected:
+ std::map<ast::VarDec*, size_t> depth_map_;
+ private:
+ size_t current_depth_ = 0;
+ };
+
+} // namespace escapes