Add the push operation in code in compiler series
This commit is contained in:
parent
9ca1b177ef
commit
f7b5bb48d1
|
@ -104,7 +104,7 @@ void ast_binop::compile(const env_ptr& env, std::vector<instruction_ptr>& into)
|
|||
right->compile(env, into);
|
||||
left->compile(env_ptr(new env_offset(1, env)), into);
|
||||
|
||||
into.push_back(instruction_ptr(new instruction_pushglobal(op_name(op))));
|
||||
into.push_back(instruction_ptr(new instruction_pushglobal(op_action(op))));
|
||||
into.push_back(instruction_ptr(new instruction_mkapp()));
|
||||
into.push_back(instruction_ptr(new instruction_mkapp()));
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ using branch_ptr = std::unique_ptr<branch>;
|
|||
struct constructor {
|
||||
std::string name;
|
||||
std::vector<std::string> types;
|
||||
int8_t tag;
|
||||
|
||||
constructor(std::string n, std::vector<std::string> ts)
|
||||
: name(std::move(n)), types(std::move(ts)) {}
|
||||
|
|
|
@ -48,6 +48,7 @@ void definition_defn::compile() {
|
|||
}
|
||||
body->compile(new_env, instructions);
|
||||
instructions.push_back(instruction_ptr(new instruction_update(params.size())));
|
||||
instructions.push_back(instruction_ptr(new instruction_pop(params.size())));
|
||||
}
|
||||
|
||||
void definition_data::typecheck_first(type_mgr& mgr, type_env& env) {
|
||||
|
@ -56,6 +57,7 @@ void definition_data::typecheck_first(type_mgr& mgr, type_env& env) {
|
|||
int next_tag = 0;
|
||||
|
||||
for(auto& constructor : constructors) {
|
||||
constructor->tag = next_tag;
|
||||
this_type->constructors[constructor->name] = { next_tag++ };
|
||||
|
||||
type_ptr full_type = return_type;
|
||||
|
|
|
@ -19,6 +19,11 @@ void instruction_push::print(int indent, std::ostream& to) const {
|
|||
to << "Push(" << offset << ")" << std::endl;
|
||||
}
|
||||
|
||||
void instruction_pop::print(int indent, std::ostream& to) const {
|
||||
print_indent(indent, to);
|
||||
to << "Pop(" << count << ")" << std::endl;
|
||||
}
|
||||
|
||||
void instruction_mkapp::print(int indent, std::ostream& to) const {
|
||||
print_indent(indent, to);
|
||||
to << "MkApp()" << std::endl;
|
||||
|
|
|
@ -41,6 +41,15 @@ struct instruction_push : public instruction {
|
|||
void print(int indent, std::ostream& to) const;
|
||||
};
|
||||
|
||||
struct instruction_pop : public instruction {
|
||||
int count;
|
||||
|
||||
instruction_pop(int c)
|
||||
: count(c) {}
|
||||
|
||||
void print(int indent, std::ostream& to) const;
|
||||
};
|
||||
|
||||
struct instruction_mkapp : public instruction {
|
||||
void print(int indent, std::ostream& to) const;
|
||||
};
|
||||
|
|
|
@ -104,7 +104,7 @@ void ast_binop::compile(const env_ptr& env, std::vector<instruction_ptr>& into)
|
|||
right->compile(env, into);
|
||||
left->compile(env_ptr(new env_offset(1, env)), into);
|
||||
|
||||
into.push_back(instruction_ptr(new instruction_pushglobal(op_name(op))));
|
||||
into.push_back(instruction_ptr(new instruction_pushglobal(op_action(op))));
|
||||
into.push_back(instruction_ptr(new instruction_mkapp()));
|
||||
into.push_back(instruction_ptr(new instruction_mkapp()));
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ using branch_ptr = std::unique_ptr<branch>;
|
|||
struct constructor {
|
||||
std::string name;
|
||||
std::vector<std::string> types;
|
||||
int8_t tag;
|
||||
|
||||
constructor(std::string n, std::vector<std::string> ts)
|
||||
: name(std::move(n)), types(std::move(ts)) {}
|
||||
|
|
|
@ -48,6 +48,7 @@ void definition_defn::compile() {
|
|||
}
|
||||
body->compile(new_env, instructions);
|
||||
instructions.push_back(instruction_ptr(new instruction_update(params.size())));
|
||||
instructions.push_back(instruction_ptr(new instruction_pop(params.size())));
|
||||
}
|
||||
|
||||
void definition_data::typecheck_first(type_mgr& mgr, type_env& env) {
|
||||
|
@ -56,6 +57,7 @@ void definition_data::typecheck_first(type_mgr& mgr, type_env& env) {
|
|||
int next_tag = 0;
|
||||
|
||||
for(auto& constructor : constructors) {
|
||||
constructor->tag = next_tag;
|
||||
this_type->constructors[constructor->name] = { next_tag++ };
|
||||
|
||||
type_ptr full_type = return_type;
|
||||
|
|
|
@ -19,6 +19,11 @@ void instruction_push::print(int indent, std::ostream& to) const {
|
|||
to << "Push(" << offset << ")" << std::endl;
|
||||
}
|
||||
|
||||
void instruction_pop::print(int indent, std::ostream& to) const {
|
||||
print_indent(indent, to);
|
||||
to << "Pop(" << count << ")" << std::endl;
|
||||
}
|
||||
|
||||
void instruction_mkapp::print(int indent, std::ostream& to) const {
|
||||
print_indent(indent, to);
|
||||
to << "MkApp()" << std::endl;
|
||||
|
|
|
@ -41,6 +41,15 @@ struct instruction_push : public instruction {
|
|||
void print(int indent, std::ostream& to) const;
|
||||
};
|
||||
|
||||
struct instruction_pop : public instruction {
|
||||
int count;
|
||||
|
||||
instruction_pop(int c)
|
||||
: count(c) {}
|
||||
|
||||
void print(int indent, std::ostream& to) const;
|
||||
};
|
||||
|
||||
struct instruction_mkapp : public instruction {
|
||||
void print(int indent, std::ostream& to) const;
|
||||
};
|
||||
|
|
|
@ -53,6 +53,7 @@ void definition_defn::compile() {
|
|||
}
|
||||
body->compile(new_env, instructions);
|
||||
instructions.push_back(instruction_ptr(new instruction_update(params.size())));
|
||||
instructions.push_back(instruction_ptr(new instruction_pop(params.size())));
|
||||
}
|
||||
void definition_defn::gen_llvm_first(llvm_context& ctx) {
|
||||
generated_function = ctx.create_custom_function(name, params.size());
|
||||
|
@ -63,7 +64,6 @@ void definition_defn::gen_llvm_second(llvm_context& ctx) {
|
|||
for(auto& instruction : instructions) {
|
||||
instruction->gen_llvm(ctx, generated_function);
|
||||
}
|
||||
ctx.create_popn(generated_function, ctx.create_size(params.size()));
|
||||
ctx.builder.CreateRetVoid();
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,15 @@ void instruction_push::gen_llvm(llvm_context& ctx, Function* f) const {
|
|||
ctx.create_push(f, ctx.create_peek(f, ctx.create_size(offset)));
|
||||
}
|
||||
|
||||
void instruction_pop::print(int indent, std::ostream& to) const {
|
||||
print_indent(indent, to);
|
||||
to << "Pop(" << count << ")" << std::endl;
|
||||
}
|
||||
|
||||
void instruction_pop::gen_llvm(llvm_context& ctx, Function* f) const {
|
||||
ctx.create_popn(f, ctx.create_size(count));
|
||||
}
|
||||
|
||||
void instruction_mkapp::print(int indent, std::ostream& to) const {
|
||||
print_indent(indent, to);
|
||||
to << "MkApp()" << std::endl;
|
||||
|
@ -128,8 +137,8 @@ void instruction_binop::print(int indent, std::ostream& to) const {
|
|||
}
|
||||
|
||||
void instruction_binop::gen_llvm(llvm_context& ctx, Function* f) const {
|
||||
auto left_int = ctx.unwrap_num(ctx.create_eval(ctx.create_pop(f)));
|
||||
auto right_int = ctx.unwrap_num(ctx.create_eval(ctx.create_pop(f)));
|
||||
auto left_int = ctx.unwrap_num(ctx.create_pop(f));
|
||||
auto right_int = ctx.unwrap_num(ctx.create_pop(f));
|
||||
llvm::Value* result;
|
||||
switch(op) {
|
||||
case PLUS: result = ctx.builder.CreateAdd(left_int, right_int); break;
|
||||
|
|
|
@ -47,6 +47,16 @@ struct instruction_push : public instruction {
|
|||
void gen_llvm(llvm_context& ctx, llvm::Function* f) const;
|
||||
};
|
||||
|
||||
struct instruction_pop : public instruction {
|
||||
int count;
|
||||
|
||||
instruction_pop(int c)
|
||||
: count(c) {}
|
||||
|
||||
void print(int indent, std::ostream& to) const;
|
||||
void gen_llvm(llvm_context& ctx, llvm::Function* f) const;
|
||||
};
|
||||
|
||||
struct instruction_mkapp : public instruction {
|
||||
void print(int indent, std::ostream& to) const;
|
||||
void gen_llvm(llvm_context& ctx, llvm::Function* f) const;
|
||||
|
|
11
08/main.cpp
11
08/main.cpp
|
@ -69,9 +69,16 @@ void compile_program(const std::vector<definition_ptr>& prog) {
|
|||
|
||||
void gen_llvm_internal_op(llvm_context& ctx, binop op) {
|
||||
auto new_function = ctx.create_custom_function(op_action(op), 2);
|
||||
auto new_instruction = instruction_ptr(new instruction_binop(op));
|
||||
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)));
|
||||
ctx.builder.SetInsertPoint(&new_function->getEntryBlock());
|
||||
new_instruction->gen_llvm(ctx, new_function);
|
||||
for(auto& instruction : instructions) {
|
||||
instruction->gen_llvm(ctx, new_function);
|
||||
}
|
||||
ctx.builder.CreateRetVoid();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user