/** ** \file type/type-checker.hxx ** \brief Inline methods of type::TypeChecker. */ #pragma once #include #include #include #include namespace type { namespace { const Nil nil_error_instance{}; } /*----------------. | Setting types. | `----------------*/ template 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(&e); assertion(casted != nullptr); if (casted->type_get() != nullptr) { return; } type_set(e, type); } template void TypeChecker::created_type_default(NodeType& e, const type::Type* type) { // FIXME DONE: Some code was deleted here. const auto casted = dynamic_cast(&e); assertion(casted != nullptr); if (casted->created_type_get() != nullptr) { return; } casted->created_type_set(type); } template 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(&e); assertion(casted != nullptr); casted->type_set(type); } /*-----------------. | Error handling. | `-----------------*/ template 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 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 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(&e); assertion(casted != nullptr); if (type(*casted)->actual() == t) return; type_mismatch(e, s, *casted->type_get(), "expected", t); } /*------------. | Functions. | `------------*/ template 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(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