Separate definitions in compiler series
This commit is contained in:
81
10/main.cpp
81
10/main.cpp
@@ -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";
|
||||
|
||||
Reference in New Issue
Block a user