Add the push operation in code in compiler series
This commit is contained in:
parent
64227f2873
commit
2994f8983d
|
@ -104,7 +104,7 @@ void ast_binop::compile(const env_ptr& env, std::vector<instruction_ptr>& into)
|
||||||
right->compile(env, into);
|
right->compile(env, into);
|
||||||
left->compile(env_ptr(new env_offset(1, 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()));
|
||||||
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 {
|
struct constructor {
|
||||||
std::string name;
|
std::string name;
|
||||||
std::vector<std::string> types;
|
std::vector<std::string> types;
|
||||||
|
int8_t tag;
|
||||||
|
|
||||||
constructor(std::string n, std::vector<std::string> ts)
|
constructor(std::string n, std::vector<std::string> ts)
|
||||||
: name(std::move(n)), types(std::move(ts)) {}
|
: name(std::move(n)), types(std::move(ts)) {}
|
||||||
|
|
|
@ -48,6 +48,7 @@ void definition_defn::compile() {
|
||||||
}
|
}
|
||||||
body->compile(new_env, instructions);
|
body->compile(new_env, instructions);
|
||||||
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())));
|
||||||
}
|
}
|
||||||
|
|
||||||
void definition_data::typecheck_first(type_mgr& mgr, type_env& env) {
|
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;
|
int next_tag = 0;
|
||||||
|
|
||||||
for(auto& constructor : constructors) {
|
for(auto& constructor : constructors) {
|
||||||
|
constructor->tag = next_tag;
|
||||||
this_type->constructors[constructor->name] = { next_tag++ };
|
this_type->constructors[constructor->name] = { next_tag++ };
|
||||||
|
|
||||||
type_ptr full_type = return_type;
|
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;
|
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 {
|
void instruction_mkapp::print(int indent, std::ostream& to) const {
|
||||||
print_indent(indent, to);
|
print_indent(indent, to);
|
||||||
to << "MkApp()" << std::endl;
|
to << "MkApp()" << std::endl;
|
||||||
|
|
|
@ -41,6 +41,15 @@ struct instruction_push : public instruction {
|
||||||
void print(int indent, std::ostream& to) const;
|
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 {
|
struct instruction_mkapp : public instruction {
|
||||||
void print(int indent, std::ostream& to) const;
|
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);
|
right->compile(env, into);
|
||||||
left->compile(env_ptr(new env_offset(1, 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()));
|
||||||
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 {
|
struct constructor {
|
||||||
std::string name;
|
std::string name;
|
||||||
std::vector<std::string> types;
|
std::vector<std::string> types;
|
||||||
|
int8_t tag;
|
||||||
|
|
||||||
constructor(std::string n, std::vector<std::string> ts)
|
constructor(std::string n, std::vector<std::string> ts)
|
||||||
: name(std::move(n)), types(std::move(ts)) {}
|
: name(std::move(n)), types(std::move(ts)) {}
|
||||||
|
|
|
@ -48,6 +48,7 @@ void definition_defn::compile() {
|
||||||
}
|
}
|
||||||
body->compile(new_env, instructions);
|
body->compile(new_env, instructions);
|
||||||
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())));
|
||||||
}
|
}
|
||||||
|
|
||||||
void definition_data::typecheck_first(type_mgr& mgr, type_env& env) {
|
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;
|
int next_tag = 0;
|
||||||
|
|
||||||
for(auto& constructor : constructors) {
|
for(auto& constructor : constructors) {
|
||||||
|
constructor->tag = next_tag;
|
||||||
this_type->constructors[constructor->name] = { next_tag++ };
|
this_type->constructors[constructor->name] = { next_tag++ };
|
||||||
|
|
||||||
type_ptr full_type = return_type;
|
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;
|
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 {
|
void instruction_mkapp::print(int indent, std::ostream& to) const {
|
||||||
print_indent(indent, to);
|
print_indent(indent, to);
|
||||||
to << "MkApp()" << std::endl;
|
to << "MkApp()" << std::endl;
|
||||||
|
|
|
@ -41,6 +41,15 @@ struct instruction_push : public instruction {
|
||||||
void print(int indent, std::ostream& to) const;
|
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 {
|
struct instruction_mkapp : public instruction {
|
||||||
void print(int indent, std::ostream& to) const;
|
void print(int indent, std::ostream& to) const;
|
||||||
};
|
};
|
||||||
|
|
|
@ -53,6 +53,7 @@ void definition_defn::compile() {
|
||||||
}
|
}
|
||||||
body->compile(new_env, instructions);
|
body->compile(new_env, instructions);
|
||||||
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())));
|
||||||
}
|
}
|
||||||
void definition_defn::gen_llvm_first(llvm_context& ctx) {
|
void definition_defn::gen_llvm_first(llvm_context& ctx) {
|
||||||
generated_function = ctx.create_custom_function(name, params.size());
|
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) {
|
for(auto& instruction : instructions) {
|
||||||
instruction->gen_llvm(ctx, generated_function);
|
instruction->gen_llvm(ctx, generated_function);
|
||||||
}
|
}
|
||||||
ctx.create_popn(generated_function, ctx.create_size(params.size()));
|
|
||||||
ctx.builder.CreateRetVoid();
|
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)));
|
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 {
|
void instruction_mkapp::print(int indent, std::ostream& to) const {
|
||||||
print_indent(indent, to);
|
print_indent(indent, to);
|
||||||
to << "MkApp()" << std::endl;
|
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 {
|
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 left_int = ctx.unwrap_num(ctx.create_pop(f));
|
||||||
auto right_int = ctx.unwrap_num(ctx.create_eval(ctx.create_pop(f)));
|
auto right_int = ctx.unwrap_num(ctx.create_pop(f));
|
||||||
llvm::Value* result;
|
llvm::Value* result;
|
||||||
switch(op) {
|
switch(op) {
|
||||||
case PLUS: result = ctx.builder.CreateAdd(left_int, right_int); break;
|
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;
|
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 {
|
struct instruction_mkapp : public instruction {
|
||||||
void print(int indent, std::ostream& to) const;
|
void print(int indent, std::ostream& to) const;
|
||||||
void gen_llvm(llvm_context& ctx, llvm::Function* f) const;
|
void gen_llvm(llvm_context& ctx, llvm::Function* f) const;
|
||||||
|
|
|
@ -69,9 +69,16 @@ void compile_program(const std::vector<definition_ptr>& prog) {
|
||||||
|
|
||||||
void gen_llvm_internal_op(llvm_context& ctx, binop op) {
|
void gen_llvm_internal_op(llvm_context& ctx, binop op) {
|
||||||
auto new_function = ctx.create_custom_function(op_action(op), 2);
|
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());
|
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();
|
ctx.builder.CreateRetVoid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user