Separate definitions in compiler series

This commit is contained in:
2020-03-24 21:08:02 -07:00
parent 2e74291ac9
commit c286c9edcc
6 changed files with 194 additions and 134 deletions

View File

@@ -20,43 +20,52 @@ void yy::parser::error(const std::string& msg) {
std::cout << "An error occured: " << msg << std::endl;
}
extern std::vector<definition_ptr> program;
extern std::vector<definition_data_ptr> defs_data;
extern std::vector<definition_defn_ptr> defs_defn;
void typecheck_program(
const std::vector<definition_ptr>& prog,
type_mgr& mgr, type_env& env) {
const std::vector<definition_data_ptr>& defs_data,
const std::vector<definition_defn_ptr>& defs_defn,
type_mgr& mgr, type_env_ptr& env) {
type_ptr int_type = type_ptr(new type_base("Int"));
type_ptr binop_type = type_ptr(new type_arr(
int_type,
type_ptr(new type_arr(int_type, int_type))));
env.bind("+", binop_type);
env.bind("-", binop_type);
env.bind("*", binop_type);
env.bind("/", binop_type);
env->bind("+", binop_type);
env->bind("-", binop_type);
env->bind("*", binop_type);
env->bind("/", binop_type);
for(auto& def : prog) {
def->typecheck_first(mgr, env);
for(auto& def_data : defs_data) {
def_data->insert_types(mgr, env);
}
for(auto& def_data : defs_data) {
def_data->insert_constructors();
}
for(auto& def : prog) {
def->typecheck_second(mgr, env);
for(auto& def_defn : defs_defn) {
def_defn->find_free(mgr, env);
}
for(auto& def_defn : defs_defn) {
def_defn->insert_types(mgr);
}
for(auto& def_defn : defs_defn) {
def_defn->typecheck(mgr);
}
for(auto& pair : env.names) {
for(auto& pair : env->names) {
std::cout << pair.first << ": ";
pair.second->print(mgr, std::cout);
std::cout << std::endl;
}
}
void compile_program(const std::vector<definition_ptr>& prog) {
for(auto& def : prog) {
def->compile();
void compile_program(const std::vector<definition_defn_ptr>& defs_defn) {
for(auto& def_defn : defs_defn) {
def_defn->compile();
definition_defn* defn = dynamic_cast<definition_defn*>(def.get());
if(!defn) continue;
for(auto& instruction : defn->instructions) {
for(auto& instruction : def_defn->instructions) {
instruction->print(0, std::cout);
}
std::cout << std::endl;
@@ -120,20 +129,25 @@ void output_llvm(llvm_context& ctx, const std::string& filename) {
}
}
void gen_llvm(const std::vector<definition_ptr>& prog) {
void gen_llvm(
const std::vector<definition_data_ptr>& defs_data,
const std::vector<definition_defn_ptr>& defs_defn) {
llvm_context ctx;
gen_llvm_internal_op(ctx, PLUS);
gen_llvm_internal_op(ctx, MINUS);
gen_llvm_internal_op(ctx, TIMES);
gen_llvm_internal_op(ctx, DIVIDE);
for(auto& definition : prog) {
definition->gen_llvm_first(ctx);
for(auto& def_data : defs_data) {
def_data->generate_llvm(ctx);
}
for(auto& def_defn : defs_defn) {
def_defn->declare_llvm(ctx);
}
for(auto& def_defn : defs_defn) {
def_defn->generate_llvm(ctx);
}
for(auto& definition : prog) {
definition->gen_llvm_second(ctx);
}
ctx.module.print(llvm::outs(), nullptr);
output_llvm(ctx, "program.o");
}
@@ -141,23 +155,20 @@ void gen_llvm(const std::vector<definition_ptr>& prog) {
int main() {
yy::parser parser;
type_mgr mgr;
type_env env;
type_env_ptr env(new type_env);
parser.parse();
for(auto& definition : program) {
definition_defn* def = dynamic_cast<definition_defn*>(definition.get());
if(!def) continue;
std::cout << def->name;
for(auto& param : def->params) std::cout << " " << param;
for(auto& def_defn : defs_defn) {
std::cout << def_defn->name;
for(auto& param : def_defn->params) std::cout << " " << param;
std::cout << ":" << std::endl;
def->body->print(1, std::cout);
def_defn->body->print(1, std::cout);
}
try {
typecheck_program(program, mgr, env);
compile_program(program);
gen_llvm(program);
typecheck_program(defs_data, defs_defn, mgr, env);
compile_program(defs_defn);
gen_llvm(defs_data, defs_defn);
} catch(unification_error& err) {
std::cout << "failed to unify types: " << std::endl;
std::cout << " (1) \033[34m";