Register booleans as internal types.
This commit is contained in:
@@ -22,13 +22,15 @@ void yy::parser::error(const yy::location& loc, const std::string& msg) {
|
||||
std::cout << "An error occured: " << msg << std::endl;
|
||||
}
|
||||
|
||||
void typecheck_program(
|
||||
definition_group& defs,
|
||||
type_mgr& mgr, type_env_ptr& env) {
|
||||
void prelude_types(definition_group& defs, type_env_ptr env) {
|
||||
type_ptr int_type = type_ptr(new type_internal("Int"));
|
||||
env->bind_type("Int", int_type);
|
||||
type_ptr int_type_app = type_ptr(new type_app(int_type));
|
||||
|
||||
type_ptr bool_type = type_ptr(new type_internal("Bool"));
|
||||
env->bind_type("Bool", bool_type);
|
||||
type_ptr bool_type_app = type_ptr(new type_app(bool_type));
|
||||
|
||||
type_ptr binop_type = type_ptr(new type_arr(
|
||||
int_type_app,
|
||||
type_ptr(new type_arr(int_type_app, int_type_app))));
|
||||
@@ -37,6 +39,15 @@ void typecheck_program(
|
||||
env->bind("*", binop_type, visibility::global);
|
||||
env->bind("/", binop_type, visibility::global);
|
||||
|
||||
env->bind("True", bool_type_app, visibility::global);
|
||||
env->bind("False", bool_type_app, visibility::global);
|
||||
}
|
||||
|
||||
void typecheck_program(
|
||||
definition_group& defs,
|
||||
type_mgr& mgr, type_env_ptr& env) {
|
||||
prelude_types(defs, env);
|
||||
|
||||
std::set<std::string> free;
|
||||
defs.find_free(free);
|
||||
defs.typecheck(mgr, env);
|
||||
@@ -60,23 +71,6 @@ global_scope translate_program(definition_group& group) {
|
||||
return scope;
|
||||
}
|
||||
|
||||
void gen_llvm_internal_op(llvm_context& ctx, binop op) {
|
||||
auto new_function = ctx.create_custom_function(op_action(op), 2);
|
||||
std::vector<instruction_ptr> instructions;
|
||||
instructions.push_back(instruction_ptr(new instruction_push(1)));
|
||||
instructions.push_back(instruction_ptr(new instruction_eval()));
|
||||
instructions.push_back(instruction_ptr(new instruction_push(1)));
|
||||
instructions.push_back(instruction_ptr(new instruction_eval()));
|
||||
instructions.push_back(instruction_ptr(new instruction_binop(op)));
|
||||
instructions.push_back(instruction_ptr(new instruction_update(2)));
|
||||
instructions.push_back(instruction_ptr(new instruction_pop(2)));
|
||||
ctx.builder.SetInsertPoint(&new_function->getEntryBlock());
|
||||
for(auto& instruction : instructions) {
|
||||
instruction->gen_llvm(ctx, new_function);
|
||||
}
|
||||
ctx.builder.CreateRetVoid();
|
||||
}
|
||||
|
||||
void output_llvm(llvm_context& ctx, const std::string& filename) {
|
||||
std::string targetTriple = llvm::sys::getDefaultTargetTriple();
|
||||
|
||||
@@ -117,12 +111,43 @@ void output_llvm(llvm_context& ctx, const std::string& filename) {
|
||||
}
|
||||
}
|
||||
|
||||
void gen_llvm_internal_op(llvm_context& ctx, binop op) {
|
||||
auto new_function = ctx.create_custom_function(op_action(op), 2);
|
||||
std::vector<instruction_ptr> instructions;
|
||||
instructions.push_back(instruction_ptr(new instruction_push(1)));
|
||||
instructions.push_back(instruction_ptr(new instruction_eval()));
|
||||
instructions.push_back(instruction_ptr(new instruction_push(1)));
|
||||
instructions.push_back(instruction_ptr(new instruction_eval()));
|
||||
instructions.push_back(instruction_ptr(new instruction_binop(op)));
|
||||
instructions.push_back(instruction_ptr(new instruction_update(2)));
|
||||
instructions.push_back(instruction_ptr(new instruction_pop(2)));
|
||||
ctx.builder.SetInsertPoint(&new_function->getEntryBlock());
|
||||
for(auto& instruction : instructions) {
|
||||
instruction->gen_llvm(ctx, new_function);
|
||||
}
|
||||
ctx.builder.CreateRetVoid();
|
||||
}
|
||||
|
||||
void gen_llvm_boolean_constructor(llvm_context& ctx, const std::string& s, bool b) {
|
||||
auto new_function = ctx.create_custom_function(s, 0);
|
||||
std::vector<instruction_ptr> instructions;
|
||||
instructions.push_back(instruction_ptr(new instruction_pushint(b)));
|
||||
instructions.push_back(instruction_ptr(new instruction_update(0)));
|
||||
ctx.builder.SetInsertPoint(&new_function->getEntryBlock());
|
||||
for(auto& instruction : instructions) {
|
||||
instruction->gen_llvm(ctx, new_function);
|
||||
}
|
||||
ctx.builder.CreateRetVoid();
|
||||
}
|
||||
|
||||
void gen_llvm(global_scope& scope) {
|
||||
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);
|
||||
gen_llvm_boolean_constructor(ctx, "True", true);
|
||||
gen_llvm_boolean_constructor(ctx, "False", false);
|
||||
|
||||
scope.generate_llvm(ctx);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user