Add errors ection to Part 4 of compiler posts

This commit is contained in:
2019-08-28 15:34:13 -07:00
parent 2dd81cf07a
commit b065d95804
6 changed files with 64 additions and 16 deletions

View File

@@ -1,5 +1,6 @@
#include "ast.hpp"
#include <ostream>
#include "error.hpp"
std::string op_name(binop op) {
switch(op) {
@@ -8,7 +9,7 @@ std::string op_name(binop op) {
case TIMES: return "*";
case DIVIDE: return "/";
}
throw 0;
return "??";
}
void print_indent(int n, std::ostream& to) {
@@ -53,7 +54,7 @@ type_ptr ast_binop::typecheck(type_mgr& mgr, const type_env& env) const {
type_ptr ltype = left->typecheck(mgr, env);
type_ptr rtype = right->typecheck(mgr, env);
type_ptr ftype = env.lookup(op_name(op));
if(!ftype) throw 0;
if(!ftype) throw type_error(std::string("unknown binary operator ") + op_name(op));
type_ptr return_type = mgr.new_type();
type_ptr arrow_one = type_ptr(new type_arr(rtype, return_type));
@@ -92,9 +93,14 @@ void ast_case::print(int indent, std::ostream& to) const {
}
type_ptr ast_case::typecheck(type_mgr& mgr, const type_env& env) const {
type_ptr case_type = of->typecheck(mgr, env);
type_var* var;
type_ptr case_type = mgr.resolve(of->typecheck(mgr, env), var);
type_ptr branch_type = mgr.new_type();
if(!dynamic_cast<type_base*>(case_type.get())) {
throw type_error("attempting case analysis of non-data type");
}
for(auto& branch : branches) {
type_env new_env = env.scope();
branch->pat->match(case_type, mgr, new_env);
@@ -122,17 +128,17 @@ void pattern_constr::print(std::ostream& to) const {
void pattern_constr::match(type_ptr t, type_mgr& mgr, type_env& env) const {
type_ptr constructor_type = env.lookup(constr);
if(!constructor_type) throw 0;
if(!constructor_type) {
throw type_error(std::string("pattern using unknown constructor ") + constr);
}
for(int i = 0; i < params.size(); i++) {
type_arr* arr = dynamic_cast<type_arr*>(constructor_type.get());
if(!arr) throw 0;
if(!arr) throw type_error("too many parameters in constructor pattern");
env.bind(params[i], arr->left);
constructor_type = arr->right;
}
mgr.unify(t, constructor_type);
type_base* result_type = dynamic_cast<type_base*>(constructor_type.get());
if(!result_type) throw 0;
}