Compare commits

..

No commits in common. "7f8dae74ac6f5580aa9e3243fe85a8dd0a43014a" and "4586bd01884aa26375d353814f7828ab5af64c6d" have entirely different histories.

8 changed files with 31 additions and 67 deletions

View File

@ -26,8 +26,8 @@ void definition_defn::find_free(type_mgr& mgr, type_env_ptr& env) {
body->find_free(mgr, var_env, free_variables); body->find_free(mgr, var_env, free_variables);
} }
void definition_defn::insert_types(type_mgr& mgr, visibility v) { void definition_defn::insert_types(type_mgr& mgr) {
env->bind(name, full_type, v); env->bind(name, full_type);
} }
void definition_defn::typecheck(type_mgr& mgr) { void definition_defn::typecheck(type_mgr& mgr) {
@ -114,13 +114,15 @@ void definition_group::find_free(type_mgr& mgr, type_env_ptr& env, std::set<std:
for(auto& def_pair : defs_defn) { for(auto& def_pair : defs_defn) {
def_pair.second->find_free(mgr, env); def_pair.second->find_free(mgr, env);
std::set<std::string> local_dependencies;
for(auto& free_var : def_pair.second->free_variables) { for(auto& free_var : def_pair.second->free_variables) {
if(defs_defn.find(free_var) == defs_defn.end()) { if(defs_defn.find(free_var) == defs_defn.end()) {
into.insert(free_var); into.insert(free_var);
} else { } else {
def_pair.second->nearby_variables.insert(free_var); local_dependencies.insert(free_var);
} }
} }
std::swap(def_pair.second->free_variables, local_dependencies);
} }
} }
@ -138,7 +140,7 @@ void definition_group::typecheck(type_mgr& mgr) {
def_defn.second->find_free(mgr, env); def_defn.second->find_free(mgr, env);
dependency_graph.add_function(def_defn.second->name); dependency_graph.add_function(def_defn.second->name);
for(auto& dependency : def_defn.second->nearby_variables) { for(auto& dependency : def_defn.second->free_variables) {
if(defs_defn.find(dependency) == defs_defn.end()) if(defs_defn.find(dependency) == defs_defn.end())
throw 0; throw 0;
dependency_graph.add_edge(def_defn.second->name, dependency); dependency_graph.add_edge(def_defn.second->name, dependency);
@ -150,7 +152,7 @@ void definition_group::typecheck(type_mgr& mgr) {
auto& group = *it; auto& group = *it;
for(auto& def_defnn_name : group->members) { for(auto& def_defnn_name : group->members) {
auto& def_defn = defs_defn.find(def_defnn_name)->second; auto& def_defn = defs_defn.find(def_defnn_name)->second;
def_defn->insert_types(mgr, vis); def_defn->insert_types(mgr);
} }
for(auto& def_defnn_name : group->members) { for(auto& def_defnn_name : group->members) {
auto& def_defn = defs_defn.find(def_defnn_name)->second; auto& def_defn = defs_defn.find(def_defnn_name)->second;

View File

@ -30,7 +30,6 @@ struct definition_defn {
type_env_ptr env; type_env_ptr env;
type_env_ptr var_env; type_env_ptr var_env;
std::set<std::string> free_variables; std::set<std::string> free_variables;
std::set<std::string> nearby_variables;
type_ptr full_type; type_ptr full_type;
type_ptr return_type; type_ptr return_type;
@ -44,7 +43,7 @@ struct definition_defn {
} }
void find_free(type_mgr& mgr, type_env_ptr& env); void find_free(type_mgr& mgr, type_env_ptr& env);
void insert_types(type_mgr& mgr, visibility v); void insert_types(type_mgr& mgr);
void typecheck(type_mgr& mgr); void typecheck(type_mgr& mgr);
void compile(); void compile();
void declare_llvm(llvm_context& ctx); void declare_llvm(llvm_context& ctx);
@ -76,10 +75,8 @@ using definition_data_ptr = std::unique_ptr<definition_data>;
struct definition_group { struct definition_group {
std::map<std::string, definition_data_ptr> defs_data; std::map<std::string, definition_data_ptr> defs_data;
std::map<std::string, definition_defn_ptr> defs_defn; std::map<std::string, definition_defn_ptr> defs_defn;
visibility vis;
type_env_ptr env;
definition_group(visibility v = visibility::local) : vis(v) {} type_env_ptr env;
void find_free(type_mgr& mgr, type_env_ptr& env, std::set<std::string>& into); void find_free(type_mgr& mgr, type_env_ptr& env, std::set<std::string>& into);
void typecheck(type_mgr& mgr); void typecheck(type_mgr& mgr);

View File

@ -33,10 +33,10 @@ void typecheck_program(
type_ptr binop_type = type_ptr(new type_arr( type_ptr binop_type = type_ptr(new type_arr(
int_type_app, int_type_app,
type_ptr(new type_arr(int_type_app, int_type_app)))); type_ptr(new type_arr(int_type_app, int_type_app))));
env->bind("+", binop_type, visibility::global); env->bind("+", binop_type);
env->bind("-", binop_type, visibility::global); env->bind("-", binop_type);
env->bind("*", binop_type, visibility::global); env->bind("*", binop_type);
env->bind("/", binop_type, visibility::global); env->bind("/", binop_type);
std::set<std::string> free; std::set<std::string> free;
defs.find_free(mgr, env, free); defs.find_free(mgr, env, free);
@ -44,7 +44,7 @@ void typecheck_program(
for(auto& pair : defs.env->names) { for(auto& pair : defs.env->names) {
std::cout << pair.first << ": "; std::cout << pair.first << ": ";
pair.second.type->print(mgr, std::cout); pair.second->print(mgr, std::cout);
std::cout << std::endl; std::cout << std::endl;
} }
} }

View File

@ -7,7 +7,7 @@
#include "parser.hpp" #include "parser.hpp"
#include "parsed_type.hpp" #include "parsed_type.hpp"
definition_group global_defs(visibility::global); definition_group global_defs;
extern yy::parser::symbol_type yylex(); extern yy::parser::symbol_type yylex();

View File

@ -5,8 +5,6 @@
#include <vector> #include <vector>
#include "error.hpp" #include "error.hpp"
bool type::is_arrow(const type_mgr& mgr) const { return false; }
void type_scheme::print(const type_mgr& mgr, std::ostream& to) const { void type_scheme::print(const type_mgr& mgr, std::ostream& to) const {
if(forall.size() != 0) { if(forall.size() != 0) {
to << "forall "; to << "forall ";
@ -36,35 +34,20 @@ void type_var::print(const type_mgr& mgr, std::ostream& to) const {
} }
} }
bool type_var::is_arrow(const type_mgr& mgr) const {
auto it = mgr.types.find(name);
if(it != mgr.types.end()) {
return it->second->is_arrow(mgr);
} else {
return false;
}
}
void type_base::print(const type_mgr& mgr, std::ostream& to) const { void type_base::print(const type_mgr& mgr, std::ostream& to) const {
to << name; to << name;
} }
void type_arr::print(const type_mgr& mgr, std::ostream& to) const { void type_arr::print(const type_mgr& mgr, std::ostream& to) const {
bool print_parenths = left->is_arrow(mgr);
if(print_parenths) to << "(";
left->print(mgr, to); left->print(mgr, to);
if(print_parenths) to << ")"; to << " -> (";
to << " -> ";
right->print(mgr, to); right->print(mgr, to);
} to << ")";
bool type_arr::is_arrow(const type_mgr& mgr) const {
return true;
} }
void type_app::print(const type_mgr& mgr, std::ostream& to) const { void type_app::print(const type_mgr& mgr, std::ostream& to) const {
constructor->print(mgr, to); constructor->print(mgr, to);
to << "*"; to << "* ";
for(auto& arg : arguments) { for(auto& arg : arguments) {
to << " "; to << " ";
arg->print(mgr, to); arg->print(mgr, to);

View File

@ -11,7 +11,6 @@ struct type {
virtual ~type() = default; virtual ~type() = default;
virtual void print(const type_mgr& mgr, std::ostream& to) const = 0; virtual void print(const type_mgr& mgr, std::ostream& to) const = 0;
virtual bool is_arrow(const type_mgr& mgr) const;
}; };
using type_ptr = std::shared_ptr<type>; using type_ptr = std::shared_ptr<type>;
@ -35,7 +34,6 @@ struct type_var : public type {
: name(std::move(n)) {} : name(std::move(n)) {}
void print(const type_mgr& mgr, std::ostream& to) const; void print(const type_mgr& mgr, std::ostream& to) const;
bool is_arrow(const type_mgr& mgr) const;
}; };
struct type_base : public type { struct type_base : public type {
@ -67,7 +65,6 @@ struct type_arr : public type {
: left(std::move(l)), right(std::move(r)) {} : left(std::move(l)), right(std::move(r)) {}
void print(const type_mgr& mgr, std::ostream& to) const; void print(const type_mgr& mgr, std::ostream& to) const;
bool is_arrow(const type_mgr& mgr) const;
}; };
struct type_app : public type { struct type_app : public type {

View File

@ -4,7 +4,7 @@
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);
for(auto& binding : names) { for(auto& binding : names) {
mgr.find_free(binding.second.type, into); mgr.find_free(binding.second, into);
} }
} }
@ -13,13 +13,13 @@ void type_env::find_free_except(const type_mgr& mgr, const std::string& avoid,
if(parent != nullptr) parent->find_free(mgr, into); if(parent != nullptr) parent->find_free(mgr, into);
for(auto& binding : names) { for(auto& binding : names) {
if(binding.first == avoid) continue; if(binding.first == avoid) continue;
mgr.find_free(binding.second.type, into); mgr.find_free(binding.second, into);
} }
} }
type_scheme_ptr type_env::lookup(const std::string& name) const { type_scheme_ptr type_env::lookup(const std::string& name) const {
auto it = names.find(name); auto it = names.find(name);
if(it != names.end()) return it->second.type; if(it != names.end()) return it->second;
if(parent) return parent->lookup(name); if(parent) return parent->lookup(name);
return nullptr; return nullptr;
} }
@ -31,13 +31,12 @@ type_ptr type_env::lookup_type(const std::string& name) const {
return nullptr; return nullptr;
} }
void type_env::bind(const std::string& name, type_ptr t, visibility v) { void type_env::bind(const std::string& name, type_ptr t) {
type_scheme_ptr new_scheme(new type_scheme(std::move(t))); names[name] = type_scheme_ptr(new type_scheme(t));
names[name] = variable_data(std::move(new_scheme), v);
} }
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) {
names[name] = variable_data(std::move(t), v); names[name] = t;
} }
void type_env::bind_type(const std::string& type_name, type_ptr t) { void type_env::bind_type(const std::string& type_name, type_ptr t) {
@ -48,15 +47,15 @@ void type_env::bind_type(const std::string& type_name, type_ptr t) {
void type_env::generalize(const std::string& name, type_mgr& mgr) { void type_env::generalize(const std::string& name, type_mgr& mgr) {
auto names_it = names.find(name); auto names_it = names.find(name);
if(names_it == names.end()) throw 0; if(names_it == names.end()) throw 0;
if(names_it->second.type->forall.size() > 0) throw 0; if(names_it->second->forall.size() > 0) throw 0;
std::set<std::string> free_in_type; std::set<std::string> free_in_type;
std::set<std::string> free_in_env; std::set<std::string> free_in_env;
mgr.find_free(names_it->second.type->monotype, free_in_type); mgr.find_free(names_it->second->monotype, free_in_type);
find_free_except(mgr, name, free_in_env); find_free_except(mgr, name, free_in_env);
for(auto& free : free_in_type) { for(auto& free : free_in_type) {
if(free_in_env.find(free) != free_in_env.end()) continue; if(free_in_env.find(free) != free_in_env.end()) continue;
names_it->second.type->forall.push_back(free); names_it->second->forall.push_back(free);
} }
} }

View File

@ -7,21 +7,9 @@
struct type_env; struct type_env;
using type_env_ptr = std::shared_ptr<type_env>; using type_env_ptr = std::shared_ptr<type_env>;
enum class visibility { global,local };
struct type_env { struct type_env {
struct variable_data {
type_scheme_ptr type;
visibility vis;
variable_data()
: variable_data(nullptr, visibility::local) {}
variable_data(type_scheme_ptr t, visibility v)
: type(std::move(t)), vis(v) {}
};
type_env_ptr parent; type_env_ptr parent;
std::map<std::string, variable_data> names; std::map<std::string, type_scheme_ptr> names;
std::map<std::string, type_ptr> type_names; std::map<std::string, type_ptr> type_names;
type_env(type_env_ptr p) : parent(std::move(p)) {} type_env(type_env_ptr p) : parent(std::move(p)) {}
@ -32,10 +20,8 @@ struct type_env {
std::set<std::string>& into) const; std::set<std::string>& into) const;
type_scheme_ptr lookup(const std::string& name) const; type_scheme_ptr lookup(const std::string& name) const;
type_ptr lookup_type(const std::string& name) const; type_ptr lookup_type(const std::string& name) const;
void bind(const std::string& name, type_ptr t, void bind(const std::string& name, type_ptr t);
visibility v = visibility::local); void bind(const std::string& name, type_scheme_ptr t);
void bind(const std::string& name, type_scheme_ptr t,
visibility v = visibility::local);
void bind_type(const std::string& type_name, type_ptr t); void bind_type(const std::string& type_name, type_ptr t);
void generalize(const std::string& name, type_mgr& mgr); void generalize(const std::string& name, type_mgr& mgr);
}; };