Extract ordering functionality into definition group.
This commit is contained in:
parent
3865abfb4d
commit
e966e74487
|
@ -5,6 +5,7 @@
|
||||||
#include "llvm_context.hpp"
|
#include "llvm_context.hpp"
|
||||||
#include "type.hpp"
|
#include "type.hpp"
|
||||||
#include "type_env.hpp"
|
#include "type_env.hpp"
|
||||||
|
#include "graph.hpp"
|
||||||
#include <llvm/IR/DerivedTypes.h>
|
#include <llvm/IR/DerivedTypes.h>
|
||||||
#include <llvm/IR/Function.h>
|
#include <llvm/IR/Function.h>
|
||||||
#include <llvm/IR/Type.h>
|
#include <llvm/IR/Type.h>
|
||||||
|
@ -107,3 +108,58 @@ void definition_data::generate_llvm(llvm_context& ctx) {
|
||||||
ctx.builder.CreateRetVoid();
|
ctx.builder.CreateRetVoid();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void definition_group::find_free(type_mgr& mgr, type_env_ptr& env, std::set<std::string>& into) {
|
||||||
|
this->env = type_scope(env);
|
||||||
|
|
||||||
|
for(auto& def_pair : defs_defn) {
|
||||||
|
def_pair.second->find_free(mgr, env);
|
||||||
|
std::set<std::string> local_dependencies;
|
||||||
|
for(auto& free_var : def_pair.second->free_variables) {
|
||||||
|
if(defs_defn.find(free_var) == defs_defn.end()) {
|
||||||
|
into.insert(free_var);
|
||||||
|
} else {
|
||||||
|
local_dependencies.insert(free_var);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::swap(def_pair.second->free_variables, local_dependencies);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void definition_group::typecheck(type_mgr& mgr) {
|
||||||
|
for(auto& def_data : defs_data) {
|
||||||
|
def_data.second->insert_types(env);
|
||||||
|
}
|
||||||
|
for(auto& def_data : defs_data) {
|
||||||
|
def_data.second->insert_constructors();
|
||||||
|
}
|
||||||
|
|
||||||
|
function_graph dependency_graph;
|
||||||
|
|
||||||
|
for(auto& def_defn : defs_defn) {
|
||||||
|
def_defn.second->find_free(mgr, env);
|
||||||
|
dependency_graph.add_function(def_defn.second->name);
|
||||||
|
|
||||||
|
for(auto& dependency : def_defn.second->free_variables) {
|
||||||
|
if(defs_defn.find(dependency) == defs_defn.end())
|
||||||
|
throw 0;
|
||||||
|
dependency_graph.add_edge(def_defn.second->name, dependency);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<group_ptr> groups = dependency_graph.compute_order();
|
||||||
|
for(auto it = groups.rbegin(); it != groups.rend(); it++) {
|
||||||
|
auto& group = *it;
|
||||||
|
for(auto& def_defnn_name : group->members) {
|
||||||
|
auto& def_defn = defs_defn.find(def_defnn_name)->second;
|
||||||
|
def_defn->insert_types(mgr);
|
||||||
|
}
|
||||||
|
for(auto& def_defnn_name : group->members) {
|
||||||
|
auto& def_defn = defs_defn.find(def_defnn_name)->second;
|
||||||
|
def_defn->typecheck(mgr);
|
||||||
|
}
|
||||||
|
for(auto& def_defnn_name : group->members) {
|
||||||
|
env->generalize(def_defnn_name, mgr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -75,4 +75,9 @@ 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;
|
||||||
|
|
||||||
|
type_env_ptr env;
|
||||||
|
|
||||||
|
void find_free(type_mgr& mgr, type_env_ptr& env, std::set<std::string>& into);
|
||||||
|
void typecheck(type_mgr& mgr);
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
using function = std::string;
|
using function = std::string;
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,7 @@ void yy::parser::error(const std::string& msg) {
|
||||||
extern definition_group global_defs;
|
extern definition_group global_defs;
|
||||||
|
|
||||||
void typecheck_program(
|
void typecheck_program(
|
||||||
const std::map<std::string, definition_data_ptr>& defs_data,
|
definition_group& defs,
|
||||||
const std::map<std::string, definition_defn_ptr>& defs_defn,
|
|
||||||
type_mgr& mgr, type_env_ptr& env) {
|
type_mgr& mgr, type_env_ptr& env) {
|
||||||
type_ptr int_type = type_ptr(new type_base("Int"));
|
type_ptr int_type = type_ptr(new type_base("Int"));
|
||||||
env->bind_type("Int", int_type);
|
env->bind_type("Int", int_type);
|
||||||
|
@ -39,43 +38,11 @@ void typecheck_program(
|
||||||
env->bind("*", binop_type);
|
env->bind("*", binop_type);
|
||||||
env->bind("/", binop_type);
|
env->bind("/", binop_type);
|
||||||
|
|
||||||
for(auto& def_data : defs_data) {
|
std::set<std::string> free;
|
||||||
def_data.second->insert_types(env);
|
defs.find_free(mgr, env, free);
|
||||||
}
|
defs.typecheck(mgr);
|
||||||
for(auto& def_data : defs_data) {
|
|
||||||
def_data.second->insert_constructors();
|
|
||||||
}
|
|
||||||
|
|
||||||
function_graph dependency_graph;
|
for(auto& pair : defs.env->names) {
|
||||||
|
|
||||||
for(auto& def_defn : defs_defn) {
|
|
||||||
def_defn.second->find_free(mgr, env);
|
|
||||||
dependency_graph.add_function(def_defn.second->name);
|
|
||||||
|
|
||||||
for(auto& dependency : def_defn.second->free_variables) {
|
|
||||||
if(defs_defn.find(dependency) == defs_defn.end())
|
|
||||||
throw 0;
|
|
||||||
dependency_graph.add_edge(def_defn.second->name, dependency);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<group_ptr> groups = dependency_graph.compute_order();
|
|
||||||
for(auto it = groups.rbegin(); it != groups.rend(); it++) {
|
|
||||||
auto& group = *it;
|
|
||||||
for(auto& def_defnn_name : group->members) {
|
|
||||||
auto& def_defn = defs_defn.find(def_defnn_name)->second;
|
|
||||||
def_defn->insert_types(mgr);
|
|
||||||
}
|
|
||||||
for(auto& def_defnn_name : group->members) {
|
|
||||||
auto& def_defn = defs_defn.find(def_defnn_name)->second;
|
|
||||||
def_defn->typecheck(mgr);
|
|
||||||
}
|
|
||||||
for(auto& def_defnn_name : group->members) {
|
|
||||||
env->generalize(def_defnn_name, mgr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(auto& pair : env->names) {
|
|
||||||
std::cout << pair.first << ": ";
|
std::cout << pair.first << ": ";
|
||||||
pair.second->print(mgr, std::cout);
|
pair.second->print(mgr, std::cout);
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
@ -187,7 +154,7 @@ int main() {
|
||||||
def_defn.second->body->print(1, std::cout);
|
def_defn.second->body->print(1, std::cout);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
typecheck_program(global_defs.defs_data, global_defs.defs_defn, mgr, env);
|
typecheck_program(global_defs, mgr, env);
|
||||||
compile_program(global_defs.defs_defn);
|
compile_program(global_defs.defs_defn);
|
||||||
gen_llvm(global_defs.defs_data, global_defs.defs_defn);
|
gen_llvm(global_defs.defs_data, global_defs.defs_defn);
|
||||||
} catch(unification_error& err) {
|
} catch(unification_error& err) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user