diff options
| author | Martial Simon <msimon_fr@hotmail.com> | 2025-09-15 01:07:58 +0200 |
|---|---|---|
| committer | Martial Simon <msimon_fr@hotmail.com> | 2025-09-15 01:07:58 +0200 |
| commit | 967be9e750221ab2ab783f95df79bb26d290a45e (patch) | |
| tree | 6802900a5e975f9f68b169f0f503f040056d6952 /tiger-compiler/src/type/type-checker.hxx | |
Diffstat (limited to 'tiger-compiler/src/type/type-checker.hxx')
| -rw-r--r-- | tiger-compiler/src/type/type-checker.hxx | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/tiger-compiler/src/type/type-checker.hxx b/tiger-compiler/src/type/type-checker.hxx new file mode 100644 index 0000000..bcdf348 --- /dev/null +++ b/tiger-compiler/src/type/type-checker.hxx @@ -0,0 +1,127 @@ +/** + ** \file type/type-checker.hxx + ** \brief Inline methods of type::TypeChecker. + */ + +#pragma once + +#include <ast/all.hh> +#include <type/pretty-printer.hh> +#include <type/type-checker.hh> +#include <type/types.hh> + +namespace type +{ + namespace + { + const Nil nil_error_instance{}; + + } + + /*----------------. + | Setting types. | + `----------------*/ + + template <typename NodeType> + void TypeChecker::type_default(NodeType& e, const type::Type* type) + { + // FIXME DONE: Some code was deleted here. + // We can check here to be sure that the type we use really is a native Tiger type + const auto casted = dynamic_cast<ast::Typable*>(&e); + + assertion(casted != nullptr); + + if (casted->type_get() != nullptr) + { + return; + } + + type_set(e, type); + } + + template <typename NodeType> + void TypeChecker::created_type_default(NodeType& e, const type::Type* type) + { + // FIXME DONE: Some code was deleted here. + const auto casted = dynamic_cast<ast::TypeConstructor*>(&e); + + assertion(casted != nullptr); + + if (casted->created_type_get() != nullptr) + { + return; + } + + casted->created_type_set(type); + } + + template <typename NodeType> + void TypeChecker::type_set(NodeType& e, const type::Type* type) + { + // FIXME DONE: Some code was deleted here (Basically e.type_set(type)). + const auto casted = dynamic_cast<ast::Typable*>(&e); + + assertion(casted != nullptr); + + casted->type_set(type); + } + + /*-----------------. + | Error handling. | + `-----------------*/ + + template <typename T> + void + TypeChecker::error(const ast::Ast& ast, const std::string& msg, const T& exp) + { + error_ << misc::error::error_type::type << ast.location_get() << ": " << msg + << ": " << exp << std::endl; + } + + template <typename T, typename U> + void + TypeChecker::error_and_recover(T& loc, const std::string& msg, const U& exp) + { + error(loc, msg, exp); + loc.type_set(&nil_error_instance); + } + + template <typename NodeType> + void TypeChecker::check_type(NodeType& e, + const std::string& s, + const Type& t) + { + // FIXME DONE: Some code was deleted here. + const auto casted = dynamic_cast<ast::Typable*>(&e); + + assertion(casted != nullptr); + + if (type(*casted)->actual() == t) + return; + + type_mismatch(e, s, *casted->type_get(), "expected", t); + } + + /*------------. + | Functions. | + `------------*/ + + template <typename Routine_Type, typename Routine_Node> + void TypeChecker::visit_routine_body(Routine_Node& e) + { + // FIXME DONE: Some code was deleted here. + if (e.body_get() == nullptr) + return; + type(*e.body_get()); + if (e.type_get()) + { + auto rt = dynamic_cast<const Routine_Type*>(e.type_get()); + check_types(e, "routine", rt->result_get(), "body", *e.body_get()->type_get()); + } + else + { + created_type_default(e, e.body_get()->type_get()); + } + } + +} // namespace type |
