Separate definitions in compiler series

This commit is contained in:
Danila Fedorin 2020-03-24 21:08:02 -07:00
parent 6714e18e7c
commit 0efa05142f
6 changed files with 194 additions and 134 deletions

View File

@ -2,6 +2,7 @@
#include <ostream> #include <ostream>
#include "binop.hpp" #include "binop.hpp"
#include "error.hpp" #include "error.hpp"
#include "type_env.hpp"
static void print_indent(int n, std::ostream& to) { static void print_indent(int n, std::ostream& to) {
while(n--) to << " "; while(n--) to << " ";
@ -12,7 +13,11 @@ void ast_int::print(int indent, std::ostream& to) const {
to << "INT: " << value << std::endl; to << "INT: " << value << std::endl;
} }
type_ptr ast_int::typecheck(type_mgr& mgr, const type_env& env) { void ast_int::find_free(type_mgr& mgr, type_env_ptr& env, std::set<std::string>& into) {
this->env = env;
}
type_ptr ast_int::typecheck(type_mgr& mgr) {
return type_ptr(new type_base("Int")); return type_ptr(new type_base("Int"));
} }
@ -25,8 +30,13 @@ void ast_lid::print(int indent, std::ostream& to) const {
to << "LID: " << id << std::endl; to << "LID: " << id << std::endl;
} }
type_ptr ast_lid::typecheck(type_mgr& mgr, const type_env& env) { void ast_lid::find_free(type_mgr& mgr, type_env_ptr& env, std::set<std::string>& into) {
return env.lookup(id); this->env = env;
if(env->lookup(id) == nullptr) into.insert(id);
}
type_ptr ast_lid::typecheck(type_mgr& mgr) {
return env->lookup(id);
} }
void ast_lid::compile(const env_ptr& env, std::vector<instruction_ptr>& into) const { void ast_lid::compile(const env_ptr& env, std::vector<instruction_ptr>& into) const {
@ -41,8 +51,12 @@ void ast_uid::print(int indent, std::ostream& to) const {
to << "UID: " << id << std::endl; to << "UID: " << id << std::endl;
} }
type_ptr ast_uid::typecheck(type_mgr& mgr, const type_env& env) { void ast_uid::find_free(type_mgr& mgr, type_env_ptr& env, std::set<std::string>& into) {
return env.lookup(id); this->env = env;
}
type_ptr ast_uid::typecheck(type_mgr& mgr) {
return env->lookup(id);
} }
void ast_uid::compile(const env_ptr& env, std::vector<instruction_ptr>& into) const { void ast_uid::compile(const env_ptr& env, std::vector<instruction_ptr>& into) const {
@ -56,10 +70,16 @@ void ast_binop::print(int indent, std::ostream& to) const {
right->print(indent + 1, to); right->print(indent + 1, to);
} }
type_ptr ast_binop::typecheck(type_mgr& mgr, const type_env& env) { void ast_binop::find_free(type_mgr& mgr, type_env_ptr& env, std::set<std::string>& into) {
type_ptr ltype = left->typecheck(mgr, env); this->env = env;
type_ptr rtype = right->typecheck(mgr, env); left->find_free(mgr, env, into);
type_ptr ftype = env.lookup(op_name(op)); right->find_free(mgr, env, into);
}
type_ptr ast_binop::typecheck(type_mgr& mgr) {
type_ptr ltype = left->typecheck(mgr);
type_ptr rtype = right->typecheck(mgr);
type_ptr ftype = env->lookup(op_name(op));
if(!ftype) throw type_error(std::string("unknown binary operator ") + op_name(op)); if(!ftype) throw type_error(std::string("unknown binary operator ") + op_name(op));
type_ptr return_type = mgr.new_type(); type_ptr return_type = mgr.new_type();
@ -86,9 +106,15 @@ void ast_app::print(int indent, std::ostream& to) const {
right->print(indent + 1, to); right->print(indent + 1, to);
} }
type_ptr ast_app::typecheck(type_mgr& mgr, const type_env& env) { void ast_app::find_free(type_mgr& mgr, type_env_ptr& env, std::set<std::string>& into) {
type_ptr ltype = left->typecheck(mgr, env); this->env = env;
type_ptr rtype = right->typecheck(mgr, env); left->find_free(mgr, env, into);
right->find_free(mgr, env, into);
}
type_ptr ast_app::typecheck(type_mgr& mgr) {
type_ptr ltype = left->typecheck(mgr);
type_ptr rtype = right->typecheck(mgr);
type_ptr return_type = mgr.new_type(); type_ptr return_type = mgr.new_type();
type_ptr arrow = type_ptr(new type_arr(rtype, return_type)); type_ptr arrow = type_ptr(new type_arr(rtype, return_type));
@ -113,15 +139,24 @@ void ast_case::print(int indent, std::ostream& to) const {
} }
} }
type_ptr ast_case::typecheck(type_mgr& mgr, const type_env& env) { void ast_case::find_free(type_mgr& mgr, type_env_ptr& env, std::set<std::string>& into) {
this->env = env;
of->find_free(mgr, env, into);
for(auto& branch : branches) {
type_env_ptr new_env = type_scope(env);
branch->pat->insert_bindings(mgr, new_env);
branch->expr->find_free(mgr, new_env, into);
}
}
type_ptr ast_case::typecheck(type_mgr& mgr) {
type_var* var; type_var* var;
type_ptr case_type = mgr.resolve(of->typecheck(mgr, env), var); type_ptr case_type = mgr.resolve(of->typecheck(mgr), var);
type_ptr branch_type = mgr.new_type(); type_ptr branch_type = mgr.new_type();
for(auto& branch : branches) { for(auto& branch : branches) {
type_env new_env = env.scope(); branch->pat->typecheck(case_type, mgr, branch->expr->env);
branch->pat->match(case_type, mgr, new_env); type_ptr curr_branch_type = branch->expr->typecheck(mgr);
type_ptr curr_branch_type = branch->expr->typecheck(mgr, new_env);
mgr.unify(branch_type, curr_branch_type); mgr.unify(branch_type, curr_branch_type);
} }
@ -192,8 +227,12 @@ void pattern_var::print(std::ostream& to) const {
to << var; to << var;
} }
void pattern_var::match(type_ptr t, type_mgr& mgr, type_env& env) const { void pattern_var::insert_bindings(type_mgr& mgr, type_env_ptr& env) const {
env.bind(var, t); env->bind(var, mgr.new_type());
}
void pattern_var::typecheck(type_ptr t, type_mgr& mgr, type_env_ptr& env) const {
mgr.unify(env->lookup(var), t);
} }
void pattern_constr::print(std::ostream& to) const { void pattern_constr::print(std::ostream& to) const {
@ -203,17 +242,23 @@ void pattern_constr::print(std::ostream& to) const {
} }
} }
void pattern_constr::match(type_ptr t, type_mgr& mgr, type_env& env) const { void pattern_constr::insert_bindings(type_mgr& mgr, type_env_ptr& env) const {
type_ptr constructor_type = env.lookup(constr); for(auto& param : params) {
env->bind(param, mgr.new_type());
}
}
void pattern_constr::typecheck(type_ptr t, type_mgr& mgr, type_env_ptr& env) const {
type_ptr constructor_type = env->lookup(constr);
if(!constructor_type) { if(!constructor_type) {
throw type_error(std::string("pattern using unknown constructor ") + constr); throw type_error(std::string("pattern using unknown constructor ") + constr);
} }
for(int i = 0; i < params.size(); i++) { for(auto& param : params) {
type_arr* arr = dynamic_cast<type_arr*>(constructor_type.get()); type_arr* arr = dynamic_cast<type_arr*>(constructor_type.get());
if(!arr) throw type_error("too many parameters in constructor pattern"); if(!arr) throw type_error("too many parameters in constructor pattern");
env.bind(params[i], arr->left); mgr.unify(env->lookup(param), arr->left);
constructor_type = arr->right; constructor_type = arr->right;
} }

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <set>
#include "type.hpp" #include "type.hpp"
#include "type_env.hpp" #include "type_env.hpp"
#include "binop.hpp" #include "binop.hpp"
@ -8,10 +9,14 @@
#include "env.hpp" #include "env.hpp"
struct ast { struct ast {
type_env_ptr env;
virtual ~ast() = default; virtual ~ast() = default;
virtual void print(int indent, std::ostream& to) const = 0; virtual void print(int indent, std::ostream& to) const = 0;
virtual type_ptr typecheck(type_mgr& mgr, const type_env& env) = 0; virtual void find_free(type_mgr& mgr,
type_env_ptr& env, std::set<std::string>& into) = 0;
virtual type_ptr typecheck(type_mgr& mgr) = 0;
virtual void compile(const env_ptr& env, virtual void compile(const env_ptr& env,
std::vector<instruction_ptr>& into) const = 0; std::vector<instruction_ptr>& into) const = 0;
}; };
@ -22,7 +27,8 @@ struct pattern {
virtual ~pattern() = default; virtual ~pattern() = default;
virtual void print(std::ostream& to) const = 0; virtual void print(std::ostream& to) const = 0;
virtual void match(type_ptr t, type_mgr& mgr, type_env& env) const = 0; virtual void insert_bindings(type_mgr& mgr, type_env_ptr& env) const = 0;
virtual void typecheck(type_ptr t, type_mgr& mgr, type_env_ptr& env) const = 0;
}; };
using pattern_ptr = std::unique_ptr<pattern>; using pattern_ptr = std::unique_ptr<pattern>;
@ -44,7 +50,8 @@ struct ast_int : public ast {
: value(v) {} : value(v) {}
void print(int indent, std::ostream& to) const; void print(int indent, std::ostream& to) const;
type_ptr typecheck(type_mgr& mgr, const type_env& env); void find_free(type_mgr& mgr, type_env_ptr& env, std::set<std::string>& into);
type_ptr typecheck(type_mgr& mgr);
void compile(const env_ptr& env, std::vector<instruction_ptr>& into) const; void compile(const env_ptr& env, std::vector<instruction_ptr>& into) const;
}; };
@ -55,7 +62,8 @@ struct ast_lid : public ast {
: id(std::move(i)) {} : id(std::move(i)) {}
void print(int indent, std::ostream& to) const; void print(int indent, std::ostream& to) const;
type_ptr typecheck(type_mgr& mgr, const type_env& env); void find_free(type_mgr& mgr, type_env_ptr& env, std::set<std::string>& into);
type_ptr typecheck(type_mgr& mgr);
void compile(const env_ptr& env, std::vector<instruction_ptr>& into) const; void compile(const env_ptr& env, std::vector<instruction_ptr>& into) const;
}; };
@ -66,7 +74,8 @@ struct ast_uid : public ast {
: id(std::move(i)) {} : id(std::move(i)) {}
void print(int indent, std::ostream& to) const; void print(int indent, std::ostream& to) const;
type_ptr typecheck(type_mgr& mgr, const type_env& env); void find_free(type_mgr& mgr, type_env_ptr& env, std::set<std::string>& into);
type_ptr typecheck(type_mgr& mgr);
void compile(const env_ptr& env, std::vector<instruction_ptr>& into) const; void compile(const env_ptr& env, std::vector<instruction_ptr>& into) const;
}; };
@ -79,7 +88,8 @@ struct ast_binop : public ast {
: op(o), left(std::move(l)), right(std::move(r)) {} : op(o), left(std::move(l)), right(std::move(r)) {}
void print(int indent, std::ostream& to) const; void print(int indent, std::ostream& to) const;
type_ptr typecheck(type_mgr& mgr, const type_env& env); void find_free(type_mgr& mgr, type_env_ptr& env, std::set<std::string>& into);
type_ptr typecheck(type_mgr& mgr);
void compile(const env_ptr& env, std::vector<instruction_ptr>& into) const; void compile(const env_ptr& env, std::vector<instruction_ptr>& into) const;
}; };
@ -91,7 +101,8 @@ struct ast_app : public ast {
: left(std::move(l)), right(std::move(r)) {} : left(std::move(l)), right(std::move(r)) {}
void print(int indent, std::ostream& to) const; void print(int indent, std::ostream& to) const;
type_ptr typecheck(type_mgr& mgr, const type_env& env); void find_free(type_mgr& mgr, type_env_ptr& env, std::set<std::string>& into);
type_ptr typecheck(type_mgr& mgr);
void compile(const env_ptr& env, std::vector<instruction_ptr>& into) const; void compile(const env_ptr& env, std::vector<instruction_ptr>& into) const;
}; };
@ -104,7 +115,8 @@ struct ast_case : public ast {
: of(std::move(o)), branches(std::move(b)) {} : of(std::move(o)), branches(std::move(b)) {}
void print(int indent, std::ostream& to) const; void print(int indent, std::ostream& to) const;
type_ptr typecheck(type_mgr& mgr, const type_env& env); void find_free(type_mgr& mgr, type_env_ptr& env, std::set<std::string>& into);
type_ptr typecheck(type_mgr& mgr);
void compile(const env_ptr& env, std::vector<instruction_ptr>& into) const; void compile(const env_ptr& env, std::vector<instruction_ptr>& into) const;
}; };
@ -115,7 +127,8 @@ struct pattern_var : public pattern {
: var(std::move(v)) {} : var(std::move(v)) {}
void print(std::ostream &to) const; void print(std::ostream &to) const;
void match(type_ptr t, type_mgr& mgr, type_env& env) const; void insert_bindings(type_mgr& mgr, type_env_ptr& env) const;
void typecheck(type_ptr t, type_mgr& mgr, type_env_ptr& env) const;
}; };
struct pattern_constr : public pattern { struct pattern_constr : public pattern {
@ -126,5 +139,6 @@ struct pattern_constr : public pattern {
: constr(std::move(c)), params(std::move(p)) {} : constr(std::move(c)), params(std::move(p)) {}
void print(std::ostream &to) const; void print(std::ostream &to) const;
void match(type_ptr t, type_mgr&, type_env& env) const; virtual void insert_bindings(type_mgr& mgr, type_env_ptr& env) const;
virtual void typecheck(type_ptr t, type_mgr& mgr, type_env_ptr& env) const;
}; };

View File

@ -3,35 +3,33 @@
#include "ast.hpp" #include "ast.hpp"
#include "instruction.hpp" #include "instruction.hpp"
#include "llvm_context.hpp" #include "llvm_context.hpp"
#include "type_env.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>
void definition_defn::typecheck_first(type_mgr& mgr, type_env& env) { void definition_defn::find_free(type_mgr& mgr, type_env_ptr& env) {
this->env = env;
var_env = type_scope(env);
return_type = mgr.new_type(); return_type = mgr.new_type();
type_ptr full_type = return_type; full_type = return_type;
for(auto it = params.rbegin(); it != params.rend(); it++) { for(auto it = params.rbegin(); it != params.rend(); it++) {
type_ptr param_type = mgr.new_type(); type_ptr param_type = mgr.new_type();
full_type = type_ptr(new type_arr(param_type, full_type)); full_type = type_ptr(new type_arr(param_type, full_type));
param_types.push_back(param_type); var_env->bind(*it, param_type);
} }
env.bind(name, full_type); body->find_free(mgr, var_env, free_variables);
} }
void definition_defn::typecheck_second(type_mgr& mgr, const type_env& env) const { void definition_defn::insert_types(type_mgr& mgr) {
type_env new_env = env.scope(); env->bind(name, full_type);
auto param_it = params.begin();
auto type_it = param_types.rbegin();
while(param_it != params.end() && type_it != param_types.rend()) {
new_env.bind(*param_it, *type_it);
param_it++;
type_it++;
} }
type_ptr body_type = body->typecheck(mgr, new_env); void definition_defn::typecheck(type_mgr& mgr) {
type_ptr body_type = body->typecheck(mgr);
mgr.unify(return_type, body_type); mgr.unify(return_type, body_type);
} }
@ -44,11 +42,12 @@ void definition_defn::compile() {
instructions.push_back(instruction_ptr(new instruction_update(params.size()))); instructions.push_back(instruction_ptr(new instruction_update(params.size())));
instructions.push_back(instruction_ptr(new instruction_pop(params.size()))); instructions.push_back(instruction_ptr(new instruction_pop(params.size())));
} }
void definition_defn::gen_llvm_first(llvm_context& ctx) {
void definition_defn::declare_llvm(llvm_context& ctx) {
generated_function = ctx.create_custom_function(name, params.size()); generated_function = ctx.create_custom_function(name, params.size());
} }
void definition_defn::gen_llvm_second(llvm_context& ctx) { void definition_defn::generate_llvm(llvm_context& ctx) {
ctx.builder.SetInsertPoint(&generated_function->getEntryBlock()); ctx.builder.SetInsertPoint(&generated_function->getEntryBlock());
for(auto& instruction : instructions) { for(auto& instruction : instructions) {
instruction->gen_llvm(ctx, generated_function); instruction->gen_llvm(ctx, generated_function);
@ -56,7 +55,11 @@ void definition_defn::gen_llvm_second(llvm_context& ctx) {
ctx.builder.CreateRetVoid(); ctx.builder.CreateRetVoid();
} }
void definition_data::typecheck_first(type_mgr& mgr, type_env& env) { void definition_data::insert_types(type_mgr& mgr, type_env_ptr& env) {
this->env = env;
}
void definition_data::insert_constructors() const {
type_data* this_type = new type_data(name); type_data* this_type = new type_data(name);
type_ptr return_type = type_ptr(this_type); type_ptr return_type = type_ptr(this_type);
int next_tag = 0; int next_tag = 0;
@ -71,19 +74,11 @@ void definition_data::typecheck_first(type_mgr& mgr, type_env& env) {
full_type = type_ptr(new type_arr(type, full_type)); full_type = type_ptr(new type_arr(type, full_type));
} }
env.bind(constructor->name, full_type); env->bind(constructor->name, full_type);
} }
} }
void definition_data::typecheck_second(type_mgr& mgr, const type_env& env) const { void definition_data::generate_llvm(llvm_context& ctx) {
// Nothing
}
void definition_data::compile() {
}
void definition_data::gen_llvm_first(llvm_context& ctx) {
for(auto& constructor : constructors) { for(auto& constructor : constructors) {
auto new_function = auto new_function =
ctx.create_custom_function(constructor->name, constructor->types.size()); ctx.create_custom_function(constructor->name, constructor->types.size());
@ -99,7 +94,3 @@ void definition_data::gen_llvm_first(llvm_context& ctx) {
ctx.builder.CreateRetVoid(); ctx.builder.CreateRetVoid();
} }
} }
void definition_data::gen_llvm_second(llvm_context& ctx) {
// Nothing
}

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <set>
#include "instruction.hpp" #include "instruction.hpp"
#include "llvm_context.hpp" #include "llvm_context.hpp"
#include "type_env.hpp" #include "type_env.hpp"
@ -8,18 +9,6 @@
struct ast; struct ast;
using ast_ptr = std::unique_ptr<ast>; using ast_ptr = std::unique_ptr<ast>;
struct definition {
virtual ~definition() = default;
virtual void typecheck_first(type_mgr& mgr, type_env& env) = 0;
virtual void typecheck_second(type_mgr& mgr, const type_env& env) const = 0;
virtual void compile() = 0;
virtual void gen_llvm_first(llvm_context& ctx) = 0;
virtual void gen_llvm_second(llvm_context& ctx) = 0;
};
using definition_ptr = std::unique_ptr<definition>;
struct constructor { struct constructor {
std::string name; std::string name;
std::vector<std::string> types; std::vector<std::string> types;
@ -31,13 +20,16 @@ struct constructor {
using constructor_ptr = std::unique_ptr<constructor>; using constructor_ptr = std::unique_ptr<constructor>;
struct definition_defn : public definition { struct definition_defn {
std::string name; std::string name;
std::vector<std::string> params; std::vector<std::string> params;
ast_ptr body; ast_ptr body;
type_env_ptr env;
type_env_ptr var_env;
std::set<std::string> free_variables;
type_ptr full_type;
type_ptr return_type; type_ptr return_type;
std::vector<type_ptr> param_types;
std::vector<instruction_ptr> instructions; std::vector<instruction_ptr> instructions;
@ -48,23 +40,28 @@ struct definition_defn : public definition {
} }
void typecheck_first(type_mgr& mgr, type_env& env); void find_free(type_mgr& mgr, type_env_ptr& env);
void typecheck_second(type_mgr& mgr, const type_env& env) const; void insert_types(type_mgr& mgr);
void typecheck(type_mgr& mgr);
void compile(); void compile();
void gen_llvm_first(llvm_context& ctx); void declare_llvm(llvm_context& ctx);
void gen_llvm_second(llvm_context& ctx); void generate_llvm(llvm_context& ctx);
}; };
struct definition_data : public definition { using definition_defn_ptr = std::unique_ptr<definition_defn>;
struct definition_data {
std::string name; std::string name;
std::vector<constructor_ptr> constructors; std::vector<constructor_ptr> constructors;
type_env_ptr env;
definition_data(std::string n, std::vector<constructor_ptr> cs) definition_data(std::string n, std::vector<constructor_ptr> cs)
: name(std::move(n)), constructors(std::move(cs)) {} : name(std::move(n)), constructors(std::move(cs)) {}
void typecheck_first(type_mgr& mgr, type_env& env); void insert_types(type_mgr& mgr, type_env_ptr& env);
void typecheck_second(type_mgr& mgr, const type_env& env) const; void insert_constructors() const;
void compile(); void generate_llvm(llvm_context& ctx);
void gen_llvm_first(llvm_context& ctx);
void gen_llvm_second(llvm_context& ctx);
}; };
using definition_data_ptr = std::unique_ptr<definition_data>;

View File

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

View File

@ -5,7 +5,9 @@
#include "definition.hpp" #include "definition.hpp"
#include "parser.hpp" #include "parser.hpp"
std::vector<definition_ptr> program; std::vector<definition_data_ptr> defs_data;
std::vector<definition_defn_ptr> defs_defn;
extern yy::parser::symbol_type yylex(); extern yy::parser::symbol_type yylex();
%} %}
@ -34,11 +36,11 @@ extern yy::parser::symbol_type yylex();
%define api.token.constructor %define api.token.constructor
%type <std::vector<std::string>> lowercaseParams uppercaseParams %type <std::vector<std::string>> lowercaseParams uppercaseParams
%type <std::vector<definition_ptr>> program definitions
%type <std::vector<branch_ptr>> branches %type <std::vector<branch_ptr>> branches
%type <std::vector<constructor_ptr>> constructors %type <std::vector<constructor_ptr>> constructors
%type <ast_ptr> aAdd aMul case app appBase %type <ast_ptr> aAdd aMul case app appBase
%type <definition_ptr> definition defn data %type <definition_data_ptr> data
%type <definition_defn_ptr> defn
%type <branch_ptr> branch %type <branch_ptr> branch
%type <pattern_ptr> pattern %type <pattern_ptr> pattern
%type <constructor_ptr> constructor %type <constructor_ptr> constructor
@ -48,22 +50,22 @@ extern yy::parser::symbol_type yylex();
%% %%
program program
: definitions { program = std::move($1); } : definitions { }
; ;
definitions definitions
: definitions definition { $$ = std::move($1); $$.push_back(std::move($2)); } : definitions definition { }
| definition { $$ = std::vector<definition_ptr>(); $$.push_back(std::move($1)); } | definition { }
; ;
definition definition
: defn { $$ = std::move($1); } : defn { defs_defn.push_back(std::move($1)); }
| data { $$ = std::move($1); } | data { defs_data.push_back(std::move($1)); }
; ;
defn defn
: DEFN LID lowercaseParams EQUAL OCURLY aAdd CCURLY : DEFN LID lowercaseParams EQUAL OCURLY aAdd CCURLY
{ $$ = definition_ptr( { $$ = definition_defn_ptr(
new definition_defn(std::move($2), std::move($3), std::move($6))); } new definition_defn(std::move($2), std::move($3), std::move($6))); }
; ;
@ -125,7 +127,7 @@ pattern
data data
: DATA UID EQUAL OCURLY constructors CCURLY : DATA UID EQUAL OCURLY constructors CCURLY
{ $$ = definition_ptr(new definition_data(std::move($2), std::move($5))); } { $$ = definition_data_ptr(new definition_data(std::move($2), std::move($5))); }
; ;
constructors constructors