diff --git a/code/compiler/13/error.cpp b/code/compiler/13/error.cpp index f5125e3..d3cb850 100644 --- a/code/compiler/13/error.cpp +++ b/code/compiler/13/error.cpp @@ -3,3 +3,26 @@ const char* type_error::what() const noexcept { return "an error occured while checking the types of the program"; } + +void type_error::pretty_print(std::ostream& to, parse_driver& drv) { + to << "encountered error while typechecking program: "; + to << description << std::endl; + + if(loc) { + to << "occuring on line " << loc->begin.line << ":" << std::endl; + to << std::endl << "```" << std::endl; + drv.print_highlighted_location(to, *loc); + to << "```" << std::endl; + } +} + +void unification_error::pretty_print(std::ostream& to, parse_driver& drv, type_mgr& mgr) { + type_error::pretty_print(to, drv); + to << "the expected type was:" << std::endl; + to << " \033[34m"; + left->print(mgr, to); + to << std::endl << "\033[0mwhile the actual type was:" << std::endl; + to << " \033[32m"; + right->print(mgr, to); + to << "\033[0m" << std::endl; +} diff --git a/code/compiler/13/error.hpp b/code/compiler/13/error.hpp index 5bfbc7e..0cf51d5 100644 --- a/code/compiler/13/error.hpp +++ b/code/compiler/13/error.hpp @@ -1,21 +1,30 @@ #pragma once #include +#include #include "type.hpp" +#include "location.hh" +#include "parse_driver.hpp" + +using maybe_location = std::optional; struct type_error : std::exception { std::string description; + std::optional loc; - type_error(std::string d) - : description(std::move(d)) {} + type_error(std::string d, maybe_location l = std::nullopt) + : description(std::move(d)), loc(std::move(l)) {} const char* what() const noexcept override; + void pretty_print(std::ostream& to, parse_driver& drv); }; struct unification_error : public type_error { type_ptr left; type_ptr right; - unification_error(type_ptr l, type_ptr r) + unification_error(type_ptr l, type_ptr r, maybe_location loc = std::nullopt) : left(std::move(l)), right(std::move(r)), - type_error("failed to unify types") {} + type_error("failed to unify types", std::move(loc)) {} + + void pretty_print(std::ostream& to, parse_driver& drv, type_mgr& mgr); }; diff --git a/code/compiler/13/main.cpp b/code/compiler/13/main.cpp index 238caea..6f844ca 100644 --- a/code/compiler/13/main.cpp +++ b/code/compiler/13/main.cpp @@ -144,8 +144,9 @@ int main(int argc, char** argv) { std::cout << def_defn.second->name; for(auto& param : def_defn.second->params) std::cout << " " << param; std::cout << ":" << std::endl; - def_defn.second->body->print(1, std::cout); + + std::cout << std::endl; } try { typecheck_program(driver.global_defs, mgr, env); @@ -153,14 +154,8 @@ int main(int argc, char** argv) { scope.compile(); gen_llvm(scope); } catch(unification_error& err) { - std::cout << "failed to unify types: " << std::endl; - std::cout << " (1) \033[34m"; - err.left->print(mgr, std::cout); - std::cout << "\033[0m" << std::endl; - std::cout << " (2) \033[32m"; - err.right->print(mgr, std::cout); - std::cout << "\033[0m" << std::endl; + err.pretty_print(std::cout, driver, mgr); } catch(type_error& err) { - std::cout << "failed to type check program: " << err.description << std::endl; + err.pretty_print(std::cout, driver); } }