summaryrefslogtreecommitdiff
path: root/tiger-compiler/src/overload
diff options
context:
space:
mode:
authorMartial Simon <msimon_fr@hotmail.com>2025-09-15 01:07:58 +0200
committerMartial Simon <msimon_fr@hotmail.com>2025-09-15 01:07:58 +0200
commit967be9e750221ab2ab783f95df79bb26d290a45e (patch)
tree6802900a5e975f9f68b169f0f503f040056d6952 /tiger-compiler/src/overload
add: added projectsHEADmain
Diffstat (limited to 'tiger-compiler/src/overload')
-rw-r--r--tiger-compiler/src/overload/binder.cc45
-rw-r--r--tiger-compiler/src/overload/binder.hh65
-rw-r--r--tiger-compiler/src/overload/liboverload.cc28
-rw-r--r--tiger-compiler/src/overload/liboverload.hh36
-rw-r--r--tiger-compiler/src/overload/local.am9
-rw-r--r--tiger-compiler/src/overload/over-table.hh63
-rw-r--r--tiger-compiler/src/overload/over-table.hxx64
-rw-r--r--tiger-compiler/src/overload/tasks.cc38
-rw-r--r--tiger-compiler/src/overload/tasks.hh29
-rw-r--r--tiger-compiler/src/overload/type-checker.cc21
-rw-r--r--tiger-compiler/src/overload/type-checker.hh37
11 files changed, 435 insertions, 0 deletions
diff --git a/tiger-compiler/src/overload/binder.cc b/tiger-compiler/src/overload/binder.cc
new file mode 100644
index 0000000..14610fe
--- /dev/null
+++ b/tiger-compiler/src/overload/binder.cc
@@ -0,0 +1,45 @@
+/**
+ ** \file overload/binder.cc
+ ** \brief Implementation of overload::Binder.
+ */
+
+#include <ast/all.hh>
+#include <overload/binder.hh>
+
+namespace overload
+{
+ overfun_bindings_type& Binder::overfun_bindings_get()
+ {
+ return overfun_bindings_;
+ }
+
+ /*---------.
+ | Scopes. |
+ `---------*/
+
+ // FIXME: Some code was deleted here.
+
+ /*-------------------.
+ | Visiting methods. |
+ `-------------------*/
+
+ // Same as Binder's, but do not set the definition site of E.
+ void Binder::operator()(ast::CallExp& e)
+ {
+ // FIXME: Some code was deleted here.
+ }
+
+ // Insert the prototype of the function in the environment.
+ void Binder::visit_dec_header(ast::FunctionDec& e)
+ {
+ // FIXME: Some code was deleted here (Checks for the _main case).
+ overfuns_.put(e.name_get(), e);
+ }
+
+ void Binder::operator()(ast::FunctionChunk& e)
+ {
+ // Two passes: once on headers, then on bodies.
+ // FIXME: Some code was deleted here.
+ }
+
+} // namespace overload
diff --git a/tiger-compiler/src/overload/binder.hh b/tiger-compiler/src/overload/binder.hh
new file mode 100644
index 0000000..607debb
--- /dev/null
+++ b/tiger-compiler/src/overload/binder.hh
@@ -0,0 +1,65 @@
+/**
+ ** \file overload/binder.hh
+ ** \brief Declaration of overload::Binder.
+ **/
+
+#pragma once
+
+#include <map>
+
+#include <bind/binder.hh>
+#include <overload/over-table.hh>
+
+namespace overload
+{
+ /// Type of the dictionary of potential function bindings.
+ using overfun_bindings_type = std::multimap<ast::CallExp*, ast::FunctionDec*>;
+
+ /** \brief Computing bindings with support for overloaded functions.
+ **
+ ** This visitor inherits from Binder, but redefines methods
+ ** dealing with function declarations and uses, to allow
+ ** overloading.
+ **
+ ** As overloading requires some knowledge of the type of the
+ ** arguments of a function, no real function binding is done here.
+ ** We store all potential function declarations (``homonyms'') for
+ ** each function call, and we'll let the overload::TypeChecker
+ ** decide later.
+ **
+ ** Inheritance is declared virtual to enable diamond inheritance with
+ ** the combine::Binder (src/combine/binder.hh), inheriting from
+ ** overload::Binder and object::Binder, both inheriting from bind::Binder.
+ **/
+ class Binder : virtual public bind::Binder
+ {
+ public:
+ /// Super class type.
+ using super_type = bind::Binder;
+ /// Import all the overloaded operator() methods.
+ using super_type::operator();
+
+ /* The visiting methods. */
+ /// Visit a function call.
+ void operator()(ast::CallExp& e) override;
+
+ /// Check a function declaration header.
+ void visit_dec_header(ast::FunctionDec& e);
+ /// Visit a chunk of function declarations.
+ void operator()(ast::FunctionChunk& e) override;
+
+ /// Return the function bindings.
+ overfun_bindings_type& overfun_bindings_get();
+
+ // FIXME: Some code was deleted here (Overload scope handling).
+ /** \} */
+
+ private:
+ using overtable_type = OverTable<ast::FunctionDec>;
+ /// The environment of (overloaded) functions.
+ overtable_type overfuns_;
+ /// The potential function bindings.
+ overfun_bindings_type overfun_bindings_;
+ };
+
+} // namespace overload
diff --git a/tiger-compiler/src/overload/liboverload.cc b/tiger-compiler/src/overload/liboverload.cc
new file mode 100644
index 0000000..7662300
--- /dev/null
+++ b/tiger-compiler/src/overload/liboverload.cc
@@ -0,0 +1,28 @@
+/**
+ ** \file overload/liboverload.cc
+ ** \brief Define exported type functions.
+ */
+
+#include <overload/binder.hh>
+#include <overload/liboverload.hh>
+#include <overload/type-checker.hh>
+
+namespace overload
+{
+ std::pair<overfun_bindings_type, misc::error> bind(ast::Ast& tree)
+ {
+ Binder bind;
+ bind(tree);
+ return std::pair(std::move(bind.overfun_bindings_get()),
+ std::move(bind.error_get()));
+ }
+
+ misc::error types_check(ast::Ast& tree,
+ const overfun_bindings_type& overfun_bindings)
+ {
+ TypeChecker type{overfun_bindings};
+ type(tree);
+ return type.error_get();
+ }
+
+} // namespace overload
diff --git a/tiger-compiler/src/overload/liboverload.hh b/tiger-compiler/src/overload/liboverload.hh
new file mode 100644
index 0000000..6c89862
--- /dev/null
+++ b/tiger-compiler/src/overload/liboverload.hh
@@ -0,0 +1,36 @@
+/**
+ ** \file overload/liboverload.hh
+ ** \brief Declare functions and variables exported by overload module.
+ */
+
+#pragma once
+
+#include <ast/fwd.hh>
+#include <misc/error.hh>
+#include <overload/binder.hh>
+
+/**
+ ** \brief Perform type checking, allowing function overloading.
+ */
+namespace overload
+{
+ /** \brief Bind identifier uses to their definition, allowing
+ function overloading, and return a list of potential definition
+ sites for each function call.
+
+ \param tree AST to bind.
+
+ \return a pair whose first element is the potential function
+ bindings, and the second element the error status. */
+ std::pair<overfun_bindings_type, misc::error> bind(ast::Ast& tree);
+
+ /** \brief Check types allowing function overloading.
+
+ \param tree abstract syntax tree's root.
+ \param overfun_bindings potential function bindings.
+
+ \return success of the type-checking. */
+ misc::error types_check(ast::Ast& tree,
+ const overfun_bindings_type& overfun_bindings);
+
+} // namespace overload
diff --git a/tiger-compiler/src/overload/local.am b/tiger-compiler/src/overload/local.am
new file mode 100644
index 0000000..022ce5f
--- /dev/null
+++ b/tiger-compiler/src/overload/local.am
@@ -0,0 +1,9 @@
+## overload module.
+
+src_libtc_la_SOURCES += \
+ %D%/over-table.hh %D%/over-table.hxx \
+ %D%/binder.hh %D%/binder.cc \
+ %D%/type-checker.hh %D%/type-checker.cc \
+ %D%/liboverload.hh %D%/liboverload.cc
+
+TASKS += %D%/tasks.hh %D%/tasks.cc
diff --git a/tiger-compiler/src/overload/over-table.hh b/tiger-compiler/src/overload/over-table.hh
new file mode 100644
index 0000000..04ddb34
--- /dev/null
+++ b/tiger-compiler/src/overload/over-table.hh
@@ -0,0 +1,63 @@
+/**
+ ** \file overload/over-table.hh
+ ** \brief Checking/translating an OverTiger program in a Tiger program.
+ */
+
+#pragma once
+
+#include <map>
+#include <vector>
+
+namespace overload
+{
+ template <typename T> class OverTable
+ {
+ public:
+ using map_type = std::multimap<const misc::symbol, T*>;
+ using iterator = typename map_type::iterator;
+ using const_iterator = typename map_type::const_iterator;
+ using oversymtab_type = std::vector<map_type>;
+ using range_type = std::pair<const_iterator, const_iterator>;
+
+ /// Create a new over table.
+ OverTable();
+
+ /// \name Symbol handling
+ /// \{
+ /// Put \a key in the map and add the value to the associated container.
+ void put(misc::symbol key, T& value);
+
+ /// Return the range associated to the key.
+ ///
+ /// If the key is not found, the beginning and the end of the range are
+ /// equal.
+ range_type get(misc::symbol key);
+ /// \}
+
+ /// \name Scopes.
+ /// \{
+ /// \brief Open a new scope.
+ ///
+ /// All further type related declarations will be limited to this scope.
+ void scope_begin();
+
+ /// \brief Close the last scope.
+ ///
+ /// Forget everything (i.e. every type related informations) since the
+ /// latest scope_begin().
+ void scope_end();
+ /// \}
+
+ /// Print the table
+ std::ostream& dump(std::ostream& ostr) const;
+
+ protected:
+ oversymtab_type oversymtab_;
+ };
+
+ template <typename T>
+ std::ostream& operator<<(std::ostream& ostr, const OverTable<T>& tbl);
+
+} // namespace overload
+
+#include <overload/over-table.hxx>
diff --git a/tiger-compiler/src/overload/over-table.hxx b/tiger-compiler/src/overload/over-table.hxx
new file mode 100644
index 0000000..de8f98b
--- /dev/null
+++ b/tiger-compiler/src/overload/over-table.hxx
@@ -0,0 +1,64 @@
+/**
+ ** \file overload/over-table.hxx
+ ** \brief Inline methods and template implementations for overload/over-table.hh.
+ */
+
+#pragma once
+
+#include <ostream>
+#include <ranges>
+
+#include <overload/over-table.hh>
+
+namespace overload
+{
+ template <typename T> OverTable<T>::OverTable()
+ {
+ oversymtab_.emplace_back();
+ }
+
+ template <typename T> void OverTable<T>::put(misc::symbol key, T& value)
+ {
+ oversymtab_.back().emplace(key, &value);
+ }
+
+ template <typename T>
+ typename OverTable<T>::range_type OverTable<T>::get(misc::symbol key)
+ {
+ precondition(!oversymtab_.empty());
+ auto& map = oversymtab_.back();
+ return map.equal_range(key);
+ }
+
+ template <typename T> void OverTable<T>::scope_begin()
+ {
+ oversymtab_.emplace_back(oversymtab_.back());
+ }
+
+ template <typename T> void OverTable<T>::scope_end()
+ {
+ precondition(!oversymtab_.empty());
+ oversymtab_.pop_back();
+ }
+
+ template <typename T>
+ std::ostream& OverTable<T>::dump(std::ostream& ostr) const
+ {
+ ostr << "<overTable>\n";
+ for (const auto& m : oversymtab_ | std::views::reverse)
+ {
+ ostr << "<scope>\n";
+ for (const auto& im : m)
+ ostr << im.first << " : " << im->second.size() << '\n';
+ ostr << "</scope>\n";
+ }
+ return ostr << "</overTable>\n";
+ }
+
+ template <typename T>
+ std::ostream& operator<<(std::ostream& ostr, const OverTable<T>& tbl)
+ {
+ return tbl.dump(ostr);
+ }
+
+} // namespace overload
diff --git a/tiger-compiler/src/overload/tasks.cc b/tiger-compiler/src/overload/tasks.cc
new file mode 100644
index 0000000..9cfde5a
--- /dev/null
+++ b/tiger-compiler/src/overload/tasks.cc
@@ -0,0 +1,38 @@
+/**
+ ** \file overload/tasks.cc
+ ** \brief Overload module related tasks' implementation.
+ */
+
+#include <memory>
+
+#include <ast/tasks.hh>
+#include <common.hh>
+#include <overload/liboverload.hh>
+#define DEFINE_TASKS 1
+#include <overload/tasks.hh>
+#undef DEFINE_TASKS
+
+namespace overload::tasks
+{
+ std::unique_ptr<overfun_bindings_type> the_overfun_bindings = nullptr;
+
+ void overfun_bindings_compute()
+ {
+ auto result = ::overload::bind(*ast::tasks::the_program);
+ ::overload::tasks::the_overfun_bindings =
+ std::make_unique<overfun_bindings_type>(std::move(result.first));
+
+ task_error() << result.second << &misc::error::exit_on_error;
+ }
+
+ void overfun_types_compute()
+ {
+ task_error() << ::overload::types_check(
+ *ast::tasks::the_program, *::overload::tasks::the_overfun_bindings);
+
+ // Force the unique_ptr to be freed.
+ the_overfun_bindings.reset();
+ task_error().exit_on_error();
+ }
+
+} // namespace overload::tasks
diff --git a/tiger-compiler/src/overload/tasks.hh b/tiger-compiler/src/overload/tasks.hh
new file mode 100644
index 0000000..31edad1
--- /dev/null
+++ b/tiger-compiler/src/overload/tasks.hh
@@ -0,0 +1,29 @@
+/**
+ ** \file overload/tasks.hh
+ ** \brief Overload module tasks.
+ */
+
+#pragma once
+
+#include <overload/binder.hh>
+#include <task/libtask.hh>
+
+namespace overload::tasks
+{
+ TASK_GROUP("4.5 Type checking with overloading");
+
+ /// Compute bindings, allowing function overloading.
+ TASK_DECLARE("overfun-bindings-compute",
+ "bind the identifiers, "
+ "allowing function overloading",
+ overfun_bindings_compute,
+ "parse");
+
+ /// Check for type violation, allowing function overloading.
+ TASK_DECLARE("O|overfun-types-compute",
+ "check for type violations, "
+ "allowing function overloading",
+ overfun_types_compute,
+ "overfun-bindings-compute");
+
+} // namespace overload::tasks
diff --git a/tiger-compiler/src/overload/type-checker.cc b/tiger-compiler/src/overload/type-checker.cc
new file mode 100644
index 0000000..1f32113
--- /dev/null
+++ b/tiger-compiler/src/overload/type-checker.cc
@@ -0,0 +1,21 @@
+/**
+ ** \file overload/type-checker.cc
+ ** \brief Implementation for overload/type-checker.hh.
+ */
+
+#include <algorithm>
+#include <sstream>
+
+#include <misc/indent.hh>
+#include <overload/type-checker.hh>
+#include <type/types.hh>
+
+namespace overload
+{
+ TypeChecker::TypeChecker(const overfun_bindings_type& overfun_bindings)
+ : overfun_bindings_{overfun_bindings}
+ {}
+
+ // FIXME: Some code was deleted here.
+
+} // namespace overload
diff --git a/tiger-compiler/src/overload/type-checker.hh b/tiger-compiler/src/overload/type-checker.hh
new file mode 100644
index 0000000..719db72
--- /dev/null
+++ b/tiger-compiler/src/overload/type-checker.hh
@@ -0,0 +1,37 @@
+/**
+ ** \file overload/type-checker.hh
+ ** \brief Checking/translating an OverTiger program in a Tiger program.
+ */
+
+#pragma once
+
+#include <overload/binder.hh>
+#include <type/type-checker.hh>
+#include <type/types.hh>
+
+namespace overload
+{
+ /** \brief Perform type checking, allowing function overload, and compute
+ ** the bindings of the functions.
+ **
+ ** Inheritance is declared virtual to enable diamond inheritance with
+ ** the combine::TypeChecker (src/combine/type-checker.hh), inheriting
+ ** from overload::TypeChecker and object::TypeChecker, both inheriting from
+ ** type::TypeChecker.
+ **/
+ class TypeChecker : virtual public type::TypeChecker
+ {
+ public:
+ /// Superclass.
+ using super_type = type::TypeChecker;
+ using super_type::operator();
+
+ TypeChecker(const overfun_bindings_type& overfun_bindings);
+ virtual ~TypeChecker() = default;
+
+ // FIXME: Some code was deleted here.
+ private:
+ const overfun_bindings_type& overfun_bindings_;
+ };
+
+} // namespace overload