Compare commits

..

5 Commits

5 changed files with 24 additions and 23 deletions

View File

@ -47,7 +47,7 @@ type_ptr ast_lid::typecheck(type_mgr& mgr, type_env_ptr& env) {
this->env = env; this->env = env;
type_scheme_ptr lid_type = env->lookup(id); type_scheme_ptr lid_type = env->lookup(id);
if(!lid_type) if(!lid_type)
throw type_error(std::string("unknown identifier ") + id, loc); throw type_error("unknown identifier " + id, loc);
return lid_type->instantiate(mgr); return lid_type->instantiate(mgr);
} }
@ -75,7 +75,7 @@ type_ptr ast_uid::typecheck(type_mgr& mgr, type_env_ptr& env) {
this->env = env; this->env = env;
type_scheme_ptr uid_type = env->lookup(id); type_scheme_ptr uid_type = env->lookup(id);
if(!uid_type) if(!uid_type)
throw type_error(std::string("unknown constructor ") + id, loc); throw type_error("unknown constructor " + id, loc);
return uid_type->instantiate(mgr); return uid_type->instantiate(mgr);
} }
@ -105,7 +105,7 @@ type_ptr ast_binop::typecheck(type_mgr& mgr, type_env_ptr& env) {
type_ptr ltype = left->typecheck(mgr, env); type_ptr ltype = left->typecheck(mgr, env);
type_ptr rtype = right->typecheck(mgr, env); type_ptr rtype = right->typecheck(mgr, env);
type_ptr ftype = env->lookup(op_name(op))->instantiate(mgr); type_ptr ftype = env->lookup(op_name(op))->instantiate(mgr);
if(!ftype) throw type_error(std::string("unknown binary operator ") + op_name(op), loc); if(!ftype) throw type_error("unknown binary operator " + op_name(op), loc);
// For better type errors, we first require binary function, // For better type errors, we first require binary function,
// and only then unify each argument. This way, we can // and only then unify each argument. This way, we can
@ -438,7 +438,7 @@ void pattern_constr::find_variables(std::set<std::string>& into) const {
void pattern_constr::typecheck(type_ptr t, type_mgr& mgr, type_env_ptr& env) const { void pattern_constr::typecheck(type_ptr t, type_mgr& mgr, type_env_ptr& env) const {
type_scheme_ptr constructor_type_scheme = env->lookup(constr); type_scheme_ptr constructor_type_scheme = env->lookup(constr);
if(!constructor_type_scheme) { if(!constructor_type_scheme) {
throw type_error(std::string("pattern using unknown constructor ") + constr, loc); throw type_error("pattern using unknown constructor " + constr, loc);
} }
type_ptr constructor_type = constructor_type_scheme->instantiate(mgr); type_ptr constructor_type = constructor_type_scheme->instantiate(mgr);

View File

@ -54,7 +54,7 @@ void compiler::translate() {
} }
for(auto& defn : global_defs.defs_defn) { for(auto& defn : global_defs.defs_defn) {
auto& function = defn.second->into_global(global_scp); auto& function = defn.second->into_global(global_scp);
function.body->env->get_parent()->set_mangled_name(defn.first, function.name); defn.second->env->set_mangled_name(defn.first, function.name);
} }
} }

View File

@ -9,10 +9,10 @@ type_ptr parsed_type_app::to_type(
const type_env& e) const { const type_env& e) const {
auto parent_type = e.lookup_type(name); auto parent_type = e.lookup_type(name);
if(parent_type == nullptr) if(parent_type == nullptr)
throw type_error(std::string("no such type or type constructor ") + name); throw type_error("no such type or type constructor " + name);
type_base* base_type; type_base* base_type;
if(!(base_type = dynamic_cast<type_base*>(parent_type.get()))) if(!(base_type = dynamic_cast<type_base*>(parent_type.get())))
throw type_error(std::string("invalid type ") + name); throw type_error("invalid type " + name);
if(base_type->arity != arguments.size()) { if(base_type->arity != arguments.size()) {
std::ostringstream error_stream; std::ostringstream error_stream;
error_stream << "invalid application of type "; error_stream << "invalid application of type ";
@ -34,7 +34,7 @@ type_ptr parsed_type_var::to_type(
const std::set<std::string>& vars, const std::set<std::string>& vars,
const type_env& e) const { const type_env& e) const {
if(vars.find(var) == vars.end()) if(vars.find(var) == vars.end())
throw type_error(std::string("the type variable ") + var + std::string(" was not explicitly declared.")); throw type_error("the type variable " + var + " was not explicitly declared.");
return type_ptr(new type_var(var)); return type_ptr(new type_var(var));
} }

View File

@ -1,10 +1,7 @@
#include "type_env.hpp" #include "type_env.hpp"
#include "type.hpp" #include "type.hpp"
#include "error.hpp" #include "error.hpp"
#include <cassert>
type_env_ptr type_env::get_parent() {
return parent;
}
void type_env::find_free(const type_mgr& mgr, std::set<std::string>& into) const { void type_env::find_free(const type_mgr& mgr, std::set<std::string>& into) const {
if(parent != nullptr) parent->find_free(mgr, into); if(parent != nullptr) parent->find_free(mgr, into);
@ -38,17 +35,21 @@ bool type_env::is_global(const std::string& name) const {
void type_env::set_mangled_name(const std::string& name, const std::string& mangled) { void type_env::set_mangled_name(const std::string& name, const std::string& mangled) {
auto it = names.find(name); auto it = names.find(name);
if(it != names.end()) {
// Can't set mangled name for non-existent variable.
assert(it != names.end());
// Local names shouldn't need mangling. // Local names shouldn't need mangling.
assert(it->second.vis == visibility::global); assert(it->second.vis == visibility::global);
it->second.mangled_name = mangled; it->second.mangled_name = mangled;
} }
}
const std::string& type_env::get_mangled_name(const std::string& name) const { const std::string& type_env::get_mangled_name(const std::string& name) const {
auto it = names.find(name); auto it = names.find(name);
if(it != names.end()) return it->second.mangled_name; if(it != names.end()) {
assert(it->second.mangled_name);
return *it->second.mangled_name;
}
assert(parent != nullptr); assert(parent != nullptr);
return parent->get_mangled_name(name); return parent->get_mangled_name(name);
} }
@ -62,7 +63,7 @@ type_ptr type_env::lookup_type(const std::string& name) const {
void type_env::bind(const std::string& name, type_ptr t, visibility v) { void type_env::bind(const std::string& name, type_ptr t, visibility v) {
type_scheme_ptr new_scheme(new type_scheme(std::move(t))); type_scheme_ptr new_scheme(new type_scheme(std::move(t)));
names[name] = variable_data(std::move(new_scheme), v, ""); names[name] = variable_data(std::move(new_scheme), v, std::nullopt);
} }
void type_env::bind(const std::string& name, type_scheme_ptr t, visibility v) { void type_env::bind(const std::string& name, type_scheme_ptr t, visibility v) {

View File

@ -2,6 +2,7 @@
#include <map> #include <map>
#include <string> #include <string>
#include <set> #include <set>
#include <optional>
#include "graph.hpp" #include "graph.hpp"
#include "type.hpp" #include "type.hpp"
@ -15,11 +16,11 @@ class type_env {
struct variable_data { struct variable_data {
type_scheme_ptr type; type_scheme_ptr type;
visibility vis; visibility vis;
std::string mangled_name; std::optional<std::string> mangled_name;
variable_data() variable_data()
: variable_data(nullptr, visibility::local, "") {} : variable_data(nullptr, visibility::local, std::nullopt) {}
variable_data(type_scheme_ptr t, visibility v, std::string n) variable_data(type_scheme_ptr t, visibility v, std::optional<std::string> n)
: type(std::move(t)), vis(v), mangled_name(std::move(n)) {} : type(std::move(t)), vis(v), mangled_name(std::move(n)) {}
}; };
@ -31,7 +32,6 @@ class type_env {
type_env(type_env_ptr p) : parent(std::move(p)) {} type_env(type_env_ptr p) : parent(std::move(p)) {}
type_env() : type_env(nullptr) {} type_env() : type_env(nullptr) {}
type_env_ptr get_parent();
void find_free(const type_mgr& mgr, std::set<std::string>& into) const; void find_free(const type_mgr& mgr, std::set<std::string>& into) const;
void find_free_except(const type_mgr& mgr, const group& avoid, void find_free_except(const type_mgr& mgr, const group& avoid,
std::set<std::string>& into) const; std::set<std::string>& into) const;