summaryrefslogtreecommitdiff
path: root/tiger-compiler/src/assert
diff options
context:
space:
mode:
Diffstat (limited to 'tiger-compiler/src/assert')
-rw-r--r--tiger-compiler/src/assert/binder.cc12
-rw-r--r--tiger-compiler/src/assert/binder.hh22
-rw-r--r--tiger-compiler/src/assert/desugar-visitor.cc33
-rw-r--r--tiger-compiler/src/assert/desugar-visitor.hh42
-rw-r--r--tiger-compiler/src/assert/desugar-visitor.hxx39
-rw-r--r--tiger-compiler/src/assert/libassert.cc36
-rw-r--r--tiger-compiler/src/assert/libassert.hh79
-rw-r--r--tiger-compiler/src/assert/libassert.hxx45
-rw-r--r--tiger-compiler/src/assert/local.am17
-rw-r--r--tiger-compiler/src/assert/renamer.cc18
-rw-r--r--tiger-compiler/src/assert/renamer.hh30
-rw-r--r--tiger-compiler/src/assert/tasks.cc53
-rw-r--r--tiger-compiler/src/assert/tasks.hh59
-rw-r--r--tiger-compiler/src/assert/type-checker.cc21
-rw-r--r--tiger-compiler/src/assert/type-checker.hh30
15 files changed, 536 insertions, 0 deletions
diff --git a/tiger-compiler/src/assert/binder.cc b/tiger-compiler/src/assert/binder.cc
new file mode 100644
index 0000000..04008bc
--- /dev/null
+++ b/tiger-compiler/src/assert/binder.cc
@@ -0,0 +1,12 @@
+/**
+ ** \file assert/binder.cc
+ ** \brief Implementation of assert::Binder.
+ */
+
+#include <assert/binder.hh>
+
+namespace assert {
+
+ Binder::Binder() = default;
+
+} // namespace assert
diff --git a/tiger-compiler/src/assert/binder.hh b/tiger-compiler/src/assert/binder.hh
new file mode 100644
index 0000000..7ede6d7
--- /dev/null
+++ b/tiger-compiler/src/assert/binder.hh
@@ -0,0 +1,22 @@
+/**
+ ** \file assert/binder.hh
+ ** \brief Declaration of assert::Binder.
+ */
+
+#pragma once
+
+#include <bind/binder.hh>
+
+namespace assert {
+
+ class Binder
+ : public bind::Binder
+ {
+ public:
+ using super_class = bind::Binder;
+
+ // Build a Binder
+ Binder();
+ };
+
+} // namespace assert
diff --git a/tiger-compiler/src/assert/desugar-visitor.cc b/tiger-compiler/src/assert/desugar-visitor.cc
new file mode 100644
index 0000000..5f18a07
--- /dev/null
+++ b/tiger-compiler/src/assert/desugar-visitor.cc
@@ -0,0 +1,33 @@
+/**
+ ** \file assert/desugar-visitor.cc
+ ** \brief Implementation of assert::DesugarVisitor.
+ */
+
+#include <assert/desugar-visitor.hh>
+
+namespace assert
+{
+
+ DesugarVisitor::DesugarVisitor(const bool desugar_for_p,
+ const bool desugar_string_cmp_p)
+ : super_type(desugar_for_p, desugar_string_cmp_p)
+ {}
+
+ void DesugarVisitor::operator()(const ast::AssertExp& e)
+ {
+ // FIXME DONE: Some code was deleted here. (replace the AssertExp to a CallExp)
+ const ast::Location location = e.location_get();
+
+ const auto args = new ast::exps_type;
+
+ const std::string condition_text = get_formatted_assert_cond(e);
+ const std::string filename = get_formatted_location(e.location_get());
+
+ args->push_back(recurse(e.cond_get()));
+ args->push_back(new ast::StringExp(location, condition_text));
+ args->push_back(new ast::StringExp(location, filename));
+
+ result_ = new ast::CallExp(location, "assertion", args);
+ }
+
+} // namespace assert
diff --git a/tiger-compiler/src/assert/desugar-visitor.hh b/tiger-compiler/src/assert/desugar-visitor.hh
new file mode 100644
index 0000000..88d689e
--- /dev/null
+++ b/tiger-compiler/src/assert/desugar-visitor.hh
@@ -0,0 +1,42 @@
+/**
+ ** \file assert/desugar-visitor.hh
+ ** \brief Declaration of assert::DesugarVisitor.
+ */
+
+#pragma once
+
+#include <ast/assert-visitor.hh>
+#include <desugar/desugar-visitor.hh>
+
+namespace assert {
+
+ class DesugarVisitor
+ : public desugar::DesugarVisitor
+ , public ast::AssertConstVisitor
+ {
+ public:
+ using super_type = desugar::DesugarVisitor;
+ using super_type::operator();
+
+ // Build a DesugarVisitor
+ DesugarVisitor(bool desugar_for_p, bool desugar_string_cmp_p);
+
+ // Desugar assertions
+ // \param e Node to visit
+ void operator()(const ast::AssertExp& e) override;
+
+ private:
+
+ // Retrieve the pretty-printed version of an assertion's condition as a
+ // string
+ // \param e Node to pretty-print.
+ inline std::string get_formatted_assert_cond(const ast::AssertExp& e);
+
+ // Retrieve the pretty-printed version of a Location as a string
+ // \param loc Location record to pretty-print
+ inline std::string get_formatted_location(const ast::Location& loc);
+ };
+
+} // namespace assert
+
+#include <assert/desugar-visitor.hxx>
diff --git a/tiger-compiler/src/assert/desugar-visitor.hxx b/tiger-compiler/src/assert/desugar-visitor.hxx
new file mode 100644
index 0000000..9e839c1
--- /dev/null
+++ b/tiger-compiler/src/assert/desugar-visitor.hxx
@@ -0,0 +1,39 @@
+/**
+ ** \file assert/desugar-visitor.hxx
+ ** \brief Implementation of assert::DesugarVisitor (inlined methods).
+ */
+
+#pragma once
+
+#include <assert/desugar-visitor.hh>
+
+#include <sstream>
+#include <string>
+
+#include <ast/pretty-printer.hh>
+
+namespace assert
+{
+
+ inline std::string
+ DesugarVisitor::get_formatted_assert_cond(const ast::AssertExp& e)
+ {
+ std::stringstream stream{};
+ ast::PrettyPrinter pretty_printer(stream);
+
+ pretty_printer(e.cond_get());
+
+ return stream.str();
+ }
+
+ inline std::string
+ DesugarVisitor::get_formatted_location(const ast::Location& loc)
+ {
+ std::stringstream stream{};
+
+ stream << loc;
+
+ return stream.str();
+ }
+
+}
diff --git a/tiger-compiler/src/assert/libassert.cc b/tiger-compiler/src/assert/libassert.cc
new file mode 100644
index 0000000..8114b74
--- /dev/null
+++ b/tiger-compiler/src/assert/libassert.cc
@@ -0,0 +1,36 @@
+/**
+ ** \file assert/libassert.cc
+ ** \brief Implementation of functions exported by the assert module.
+ */
+
+#include <assert/binder.hh>
+#include <assert/libassert.hh>
+#include <assert/renamer.hh>
+#include <assert/type-checker.hh>
+#include <misc/error.hh>
+
+namespace assert
+{
+
+ misc::error bind(ast::Ast& last)
+ {
+ Binder binder;
+ binder(last);
+ return binder.error_get();
+ }
+
+ misc::error types_check(ast::Ast& tree)
+ {
+ TypeChecker typer;
+ typer(tree);
+ return typer.error_get();
+ }
+
+ misc::error rename(ast::Ast& ast)
+ {
+ Renamer renamer;
+ renamer(ast);
+ return misc::error{};
+ }
+
+}
diff --git a/tiger-compiler/src/assert/libassert.hh b/tiger-compiler/src/assert/libassert.hh
new file mode 100644
index 0000000..aba01b1
--- /dev/null
+++ b/tiger-compiler/src/assert/libassert.hh
@@ -0,0 +1,79 @@
+/**
+ ** \file assert/libassert.hh
+ ** \brief Declare functions and variables exported by assert module.
+ */
+
+#pragma once
+
+#include <ast/fwd.hh>
+#include <misc/error.hh>
+
+namespace assert
+{
+ /*-------.
+ | Bind. |
+ `-------*/
+
+ /// \brief Bind the whole AST in place, return the error code
+ ///
+ /// \param last the ast you want to bind
+ ///
+ /// \return a misc::error that serve to indicate possible failure
+ misc::error bind(ast::Ast& last);
+
+ /*----------------.
+ | Compute types. |
+ `----------------*/
+
+ /** \brief Check types allowing assertions.
+
+ \param tree abstract syntax tree's root.
+
+ \return success of the type-checking. */
+ misc::error types_check(ast::Ast& tree);
+
+ /*---------.
+ | Rename. |
+ `---------*/
+
+ /// \brief Rename the whole ast in place
+ ///
+ /// \param ast the ast you want to rename
+ ///
+ /// \return a misc::error that serve to indicate possible failure
+ misc::error rename(ast::Ast& ast);
+
+ /*---------------------.
+ | Desugar assertions. |
+ `---------------------*/
+
+ /** \brief Remove assertions constructs from an AST.
+
+ \param tree abstract syntax tree's root, whose bindings
+ and types have been computed, and whose
+ identifiers are all unique.
+ \param class_names the names of the class types of the AST
+
+ \return the desugared, bound and type-checked AST. */
+ template <typename A>
+ A* desugar(const A& tree, bool desugar_for_p, bool desugar_string_cmp_p);
+
+ /** \brief Remove assertions constructs from an AST without recomputing
+ its bindings nor its types.
+
+ This function acts like assertions::assertions_desugar, but stops just
+ after the desugaring step (in fact, assertions::desugar is built
+ upon this function). It is meant to be used as a test of
+ DesugarVisitor (i.e., even if the desugared tree is badly bound
+ or typed, it can still be pretty-printed).
+
+ \param tree AST to desugar.
+ \param class_names the names of the class types of the AST
+
+ \return the desugared AST. */
+ template <typename A>
+ A* raw_desugar(const A& tree, bool desugar_for_p, bool desugar_string_cmp_p);
+
+}
+
+#include <assert/libassert.hxx>
diff --git a/tiger-compiler/src/assert/libassert.hxx b/tiger-compiler/src/assert/libassert.hxx
new file mode 100644
index 0000000..fcd2eb4
--- /dev/null
+++ b/tiger-compiler/src/assert/libassert.hxx
@@ -0,0 +1,45 @@
+/**
+ ** \file assert/libassert.hxx
+ ** \brief Implementation of functions exported by the assert module.
+ */
+
+#pragma once
+
+#include <memory>
+
+#include <assert/desugar-visitor.hh>
+#include <assert/libassert.hh>
+#include <misc/contract.hh>
+#include <misc/error.hh>
+
+namespace assert
+{
+
+ template <typename A> void bind_and_types_check(A& tree)
+ {
+ misc::error e;
+ e << ::assert::bind(tree);
+ e.ice_on_error_here();
+ e << ::assert::types_check(tree);
+ e.ice_on_error_here();
+ }
+
+ template <typename A>
+ A* raw_desugar(const A& tree, bool desugar_for_p, bool desugar_string_cmp_p)
+ {
+ DesugarVisitor desugar(desugar_for_p, desugar_string_cmp_p);
+ desugar(tree);
+ return dynamic_cast<A*>(desugar.result_get());
+ }
+
+ template <typename A>
+ A* desugar(const A& tree, bool desugar_for_p, bool desugar_string_cmp_p)
+ {
+ A* desugared = raw_desugar(tree, desugar_for_p, desugar_string_cmp_p);
+ assertion(desugared);
+ std::unique_ptr<A> desugared_ptr(desugared);
+ bind_and_types_check(*desugared_ptr);
+ return desugared_ptr.release();
+ }
+
+}
diff --git a/tiger-compiler/src/assert/local.am b/tiger-compiler/src/assert/local.am
new file mode 100644
index 0000000..18a8421
--- /dev/null
+++ b/tiger-compiler/src/assert/local.am
@@ -0,0 +1,17 @@
+## assert module
+
+src_libtc_la_SOURCES += \
+ %D%/libassert.hh \
+ %D%/libassert.cc \
+ %D%/libassert.hxx
+
+src_libtc_la_SOURCES += \
+ %D%/binder.hh %D%/binder.cc \
+ %D%/desugar-visitor.hh %D%/desugar-visitor.cc %D%/desugar-visitor.hxx \
+ %D%/type-checker.hh %D%/type-checker.cc \
+ %D%/renamer.hh %D%/renamer.cc
+
+
+## tasks
+
+TASKS += %D%/tasks.hh %D%/tasks.cc
diff --git a/tiger-compiler/src/assert/renamer.cc b/tiger-compiler/src/assert/renamer.cc
new file mode 100644
index 0000000..7c63cfa
--- /dev/null
+++ b/tiger-compiler/src/assert/renamer.cc
@@ -0,0 +1,18 @@
+/**
+ ** \file assert/renamer.cc
+ ** \brief Implementation of assert::Renamer.
+ */
+
+#include <assert/renamer.hh>
+
+namespace assert
+{
+
+ Renamer::Renamer() = default;
+
+ void Renamer::operator()(ast::AssertExp& e)
+ {
+ ast::AssertVisitor::operator()(e);
+ }
+
+} // namespace assert
diff --git a/tiger-compiler/src/assert/renamer.hh b/tiger-compiler/src/assert/renamer.hh
new file mode 100644
index 0000000..6a5bd14
--- /dev/null
+++ b/tiger-compiler/src/assert/renamer.hh
@@ -0,0 +1,30 @@
+/**
+ ** \file assert/renamer.hh
+ ** \brief Declaration of assert::Renamer.
+ */
+
+#pragma once
+
+#include <ast/assert-visitor.hh>
+#include <bind/renamer.hh>
+
+namespace assert {
+
+ class Renamer
+ : public bind::Renamer
+ , public ast::AssertVisitor
+ {
+ public:
+ using super_type = ::bind::Renamer;
+ using super_type::operator();
+
+ // Build a renamer
+ Renamer();
+
+ // Visiting method for AssertExp nodes (redirects to
+ // `ast::AssertVisitor::operator()(ast::AssertExp&)`)
+ // \param e Node to visit
+ void operator()(ast::AssertExp& e) override;
+ };
+
+} // namespace assert
diff --git a/tiger-compiler/src/assert/tasks.cc b/tiger-compiler/src/assert/tasks.cc
new file mode 100644
index 0000000..3e43ecd
--- /dev/null
+++ b/tiger-compiler/src/assert/tasks.cc
@@ -0,0 +1,53 @@
+/**
+ ** \file assert/tasks.cc
+ ** \brief Assert module related tasks' implementation.
+ */
+
+#include <ast/tasks.hh>
+#include <astclone/libastclone.hh>
+#include <assert/libassert.hh>
+#include <common.hh>
+#include <desugar/tasks.hh>
+#include <escapes/tasks.hh>
+#include <llvmtranslate/tasks.hh>
+#define DEFINE_TASKS 1
+#include <assert/tasks.hh>
+#undef DEFINE_TASKS
+
+namespace assert::tasks
+{
+ void parse() {}
+
+ void bind()
+ {
+ task_error() << ::assert::bind(*ast::tasks::the_program.get())
+ << &misc::error::exit_on_error;
+ }
+
+ void types_compute()
+ {
+ task_error() << ::assert::types_check(*ast::tasks::the_program.get())
+ << &misc::error::exit_on_error;
+ }
+
+ void rename()
+ {
+ task_error() << ::assert::rename(*ast::tasks::the_program.get())
+ << &misc::error::exit_on_error;
+ }
+
+ void desugar()
+ {
+ astclone::apply(::assert::desugar, ast::tasks::the_program,
+ desugar::tasks::desugar_for_p,
+ desugar::tasks::desugar_string_cmp_p);
+ }
+
+ void raw_desugar()
+ {
+ astclone::apply(::assert::raw_desugar, ast::tasks::the_program,
+ desugar::tasks::desugar_for_p,
+ desugar::tasks::desugar_string_cmp_p);
+ }
+
+} // namespace assert::tasks
diff --git a/tiger-compiler/src/assert/tasks.hh b/tiger-compiler/src/assert/tasks.hh
new file mode 100644
index 0000000..7f062de
--- /dev/null
+++ b/tiger-compiler/src/assert/tasks.hh
@@ -0,0 +1,59 @@
+/**
+ ** \file assert/tasks.hh
+ ** \brief Assert module related tasks.
+ */
+
+#pragma once
+
+#include <task/libtask.hh>
+
+// The tasks of the assert module
+namespace assert::tasks
+{
+ TASK_GROUP("Assert");
+
+ // Enable assert extensions.
+ BOOLEAN_TASK_DECLARE("assert",
+ "enable assert extensions",
+ enable_assert_extensions_p,
+ "");
+
+ // Parse the input file, allowing assertions.
+ TASK_DECLARE("assert-parse",
+ "parse a file, allowing assertions",
+ parse,
+ "assert parse");
+
+ // Bind the parsed file, allowing assertions.
+ TASK_DECLARE("assert-bindings-compute",
+ "bind the name uses to their definitions, allowing assertions",
+ bind,
+ "assert-parse");
+
+ // Check for type violation, allowing assertions.
+ TASK_DECLARE("assert-types-compute",
+ "check for type violations, allowing assertions",
+ types_compute,
+ "assert-bindings-compute");
+
+ // Perform a renaming, before desugaring assertions.
+ TASK_DECLARE("assert-rename",
+ "rename identifiers to unique names, allowing assertions",
+ rename,
+ "assert-bindings-compute");
+
+ // Remove syntactic sugar from the Ast.
+ TASK_DECLARE("assert-desugar",
+ "remove assertions constructs from the program",
+ desugar,
+ "assert-rename assert-types-compute");
+
+ // Remove syntactic sugar from the Ast without recomputing
+ // bindings nor types.
+ TASK_DECLARE("raw-assert-desugar",
+ "remove assertions constructs from the program "
+ "without recomputing bindings nor types",
+ raw_desugar,
+ "assert-rename assert-types-compute");
+
+} // namespace assert::tasks
diff --git a/tiger-compiler/src/assert/type-checker.cc b/tiger-compiler/src/assert/type-checker.cc
new file mode 100644
index 0000000..894ff6f
--- /dev/null
+++ b/tiger-compiler/src/assert/type-checker.cc
@@ -0,0 +1,21 @@
+/**
+ ** \file assert/type-checker.cc
+ ** \brief Implementation of assert::TypeChecker.
+ */
+
+#include <assert/type-checker.hh>
+
+namespace assert
+{
+
+ TypeChecker::TypeChecker() = default;
+
+ void TypeChecker::operator()(ast::AssertExp& e)
+ {
+ // FIXME DONE: Some code was deleted here. (implement method documentation)
+ check_type(e.cond_get(), "assertion", type::Int::instance());
+
+ type_default(e, &type::Void::instance());
+ }
+
+} // namespace assert
diff --git a/tiger-compiler/src/assert/type-checker.hh b/tiger-compiler/src/assert/type-checker.hh
new file mode 100644
index 0000000..e15e393
--- /dev/null
+++ b/tiger-compiler/src/assert/type-checker.hh
@@ -0,0 +1,30 @@
+/**
+ ** \file assert/type-checker.hh
+ ** \brief Declaration of assert::TypeChecker.
+ */
+
+#pragma once
+
+#include <ast/assert-visitor.hh>
+#include <type/type-checker.hh>
+
+namespace assert {
+
+ class TypeChecker
+ : public type::TypeChecker
+ , public ast::AssertVisitor
+ {
+ public:
+ using super_type = type::TypeChecker;
+ using super_type::operator();
+
+ // Build a TypeChecker
+ TypeChecker();
+
+ // Type an AssertExp node. All AssertExp must follow the typing table :
+ // cond_ : int | assert cond_ : void
+ // \param e Node to visit
+ void operator()(ast::AssertExp& e) override;
+ };
+
+} // assert