diff options
Diffstat (limited to 'tiger-compiler/src/escapes')
| -rw-r--r-- | tiger-compiler/src/escapes/escapes-visitor.cc | 31 | ||||
| -rw-r--r-- | tiger-compiler/src/escapes/escapes-visitor.hh | 75 | ||||
| -rw-r--r-- | tiger-compiler/src/escapes/libescapes.cc | 23 | ||||
| -rw-r--r-- | tiger-compiler/src/escapes/libescapes.hh | 23 | ||||
| -rw-r--r-- | tiger-compiler/src/escapes/local.am | 7 | ||||
| -rw-r--r-- | tiger-compiler/src/escapes/tasks.cc | 38 | ||||
| -rw-r--r-- | tiger-compiler/src/escapes/tasks.hh | 28 |
7 files changed, 225 insertions, 0 deletions
diff --git a/tiger-compiler/src/escapes/escapes-visitor.cc b/tiger-compiler/src/escapes/escapes-visitor.cc new file mode 100644 index 0000000..f0fd5e2 --- /dev/null +++ b/tiger-compiler/src/escapes/escapes-visitor.cc @@ -0,0 +1,31 @@ +/** + ** \file escapes/escapes-visitor.cc + ** \brief Implementation for escapes/escapes-visitor.hh. + */ + +#include <ast/all.hh> +#include <escapes/escapes-visitor.hh> +#include <misc/contract.hh> + +namespace escapes +{ + // FIXME DONE: Some code was deleted here. + + void EscapesVisitor::operator()(ast::SimpleVar& e) + { + if (depth_map_.at(e.def_get()) < current_depth_) + e.def_get()->escape_set(true); + } + void EscapesVisitor::operator()(ast::VarDec& e) + { + e.escape_set(false); + depth_map_.insert_or_assign(&e, current_depth_); + super_type::operator()(e); + } + void EscapesVisitor::operator()(ast::FunctionDec& e) + { + current_depth_++; + super_type::operator()(e); + current_depth_--; + } +} // namespace escapes 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 diff --git a/tiger-compiler/src/escapes/libescapes.cc b/tiger-compiler/src/escapes/libescapes.cc new file mode 100644 index 0000000..6124d54 --- /dev/null +++ b/tiger-compiler/src/escapes/libescapes.cc @@ -0,0 +1,23 @@ +/** + ** \file escapes/libescapes.cc + ** \brief Define exported escapes functions. + */ + +#include <escapes/escapes-visitor.hh> +#include <escapes/libescapes.hh> + +namespace escapes +{ + /** Walk the tree, and set the escape flag of variables and arguments + if they do escape. */ + void escapes_compute(ast::Ast& tree) + { + /// boolean to check if an escapes pass was done in desugar + escapes::escaped = true; + EscapesVisitor escapes_compute; + escapes_compute(tree); + } + + bool escaped = false; + +} // namespace escapes diff --git a/tiger-compiler/src/escapes/libescapes.hh b/tiger-compiler/src/escapes/libescapes.hh new file mode 100644 index 0000000..2d3dd73 --- /dev/null +++ b/tiger-compiler/src/escapes/libescapes.hh @@ -0,0 +1,23 @@ +/** + ** \file escapes/libescapes.hh + ** \brief Declare functions and variables exported by escapes module. + */ + +#pragma once + +#include <ast/fwd.hh> +#include <misc/error.hh> + +/// Computing escape and static link related information. +namespace escapes +{ + /// Compute the escaping variables. + void escapes_compute(ast::Ast& tree); + + /// This boolean is used to know whether escape pass + /// was made + /// FIXME: this is a dirty fix it should be replaced with a + /// new implementation of tasks + extern bool escaped; + +} // namespace escapes diff --git a/tiger-compiler/src/escapes/local.am b/tiger-compiler/src/escapes/local.am new file mode 100644 index 0000000..ab6c63a --- /dev/null +++ b/tiger-compiler/src/escapes/local.am @@ -0,0 +1,7 @@ +## escape module. + +src_libtc_la_SOURCES += \ + %D%/libescapes.hh %D%/libescapes.cc \ + %D%/escapes-visitor.hh %D%/escapes-visitor.cc + +TASKS += %D%/tasks.hh %D%/tasks.cc diff --git a/tiger-compiler/src/escapes/tasks.cc b/tiger-compiler/src/escapes/tasks.cc new file mode 100644 index 0000000..42e6919 --- /dev/null +++ b/tiger-compiler/src/escapes/tasks.cc @@ -0,0 +1,38 @@ +/** + ** \file escapes/tasks.cc + ** \brief Escapes module related tasks' implementation. + */ + +#include <ostream> + +#include <ast/libast.hh> +#include <ast/tasks.hh> +#include <escapes/libescapes.hh> +#define DEFINE_TASKS 1 +#include <escapes/tasks.hh> +#undef DEFINE_TASKS +#include <misc/xalloc.hh> + +namespace escapes::tasks +{ + + /*--------------------. + | Static Link tasks. | + `--------------------*/ + + void escapes_compute() { escapes::escapes_compute(*ast::tasks::the_program); } + + /* WARNING. It is very tempting to use BOOLEAN_TASK_DECLARE with + these stream flags, since it factors out the need for the + following routines. Unfortunately when the Tasks are created, + not all the misc::xalloc are instantiated, so the registered + address of these flags is likely to change if there are other + xalloc in between. It is the index that is constant, not the + address of the pword. + + Of course we could have Tasks dedicated to misc::xalloc, but + that's not nice. */ + + void escapes_display() { ast::escapes_display(std::cout) = true; } + +} // namespace escapes::tasks diff --git a/tiger-compiler/src/escapes/tasks.hh b/tiger-compiler/src/escapes/tasks.hh new file mode 100644 index 0000000..636c13f --- /dev/null +++ b/tiger-compiler/src/escapes/tasks.hh @@ -0,0 +1,28 @@ +/** + ** \file escapes/tasks.hh + ** \brief Escapes module related tasks. + */ + +#pragma once + +#include <task/libtask.hh> + +/// The Tasks of the escapes module. +namespace escapes::tasks +{ + TASK_GROUP("3. Escapes"); + + /// Compute variables escaping. + TASK_DECLARE("e|escapes-compute", + "compute the escaping variables " + "and the functions requiring a static link", + escapes_compute, + "bound"); + + /// Display escaped variables. + TASK_DECLARE("E|escapes-display", + "enable escape display in the AST", + escapes_display, + "parse"); + +} // namespace escapes::tasks |
