From 2994f8983de76d24ea2398b51b703b41ed5df5ee Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Wed, 6 Nov 2019 13:23:59 -0800 Subject: [PATCH] Add the push operation in code in compiler series --- code/compiler/06/ast.cpp | 2 +- code/compiler/06/ast.hpp | 1 + code/compiler/06/definition.cpp | 2 ++ code/compiler/06/instruction.cpp | 5 +++++ code/compiler/06/instruction.hpp | 9 +++++++++ code/compiler/07/ast.cpp | 2 +- code/compiler/07/ast.hpp | 1 + code/compiler/07/definition.cpp | 2 ++ code/compiler/07/instruction.cpp | 5 +++++ code/compiler/07/instruction.hpp | 9 +++++++++ code/compiler/08/definition.cpp | 2 +- code/compiler/08/instruction.cpp | 13 +++++++++++-- code/compiler/08/instruction.hpp | 10 ++++++++++ code/compiler/08/main.cpp | 11 +++++++++-- 14 files changed, 67 insertions(+), 7 deletions(-) diff --git a/code/compiler/06/ast.cpp b/code/compiler/06/ast.cpp index 00d92a3..486607b 100644 --- a/code/compiler/06/ast.cpp +++ b/code/compiler/06/ast.cpp @@ -104,7 +104,7 @@ void ast_binop::compile(const env_ptr& env, std::vector& 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())); } diff --git a/code/compiler/06/ast.hpp b/code/compiler/06/ast.hpp index c536d17..2cc54bf 100644 --- a/code/compiler/06/ast.hpp +++ b/code/compiler/06/ast.hpp @@ -46,6 +46,7 @@ using branch_ptr = std::unique_ptr; struct constructor { std::string name; std::vector types; + int8_t tag; constructor(std::string n, std::vector ts) : name(std::move(n)), types(std::move(ts)) {} diff --git a/code/compiler/06/definition.cpp b/code/compiler/06/definition.cpp index 34c6f66..29b16cc 100644 --- a/code/compiler/06/definition.cpp +++ b/code/compiler/06/definition.cpp @@ -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; diff --git a/code/compiler/06/instruction.cpp b/code/compiler/06/instruction.cpp index 0272e20..3b421c0 100644 --- a/code/compiler/06/instruction.cpp +++ b/code/compiler/06/instruction.cpp @@ -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; diff --git a/code/compiler/06/instruction.hpp b/code/compiler/06/instruction.hpp index 879cd05..5228209 100644 --- a/code/compiler/06/instruction.hpp +++ b/code/compiler/06/instruction.hpp @@ -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; }; diff --git a/code/compiler/07/ast.cpp b/code/compiler/07/ast.cpp index 00d92a3..486607b 100644 --- a/code/compiler/07/ast.cpp +++ b/code/compiler/07/ast.cpp @@ -104,7 +104,7 @@ void ast_binop::compile(const env_ptr& env, std::vector& 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())); } diff --git a/code/compiler/07/ast.hpp b/code/compiler/07/ast.hpp index c536d17..2cc54bf 100644 --- a/code/compiler/07/ast.hpp +++ b/code/compiler/07/ast.hpp @@ -46,6 +46,7 @@ using branch_ptr = std::unique_ptr; struct constructor { std::string name; std::vector types; + int8_t tag; constructor(std::string n, std::vector ts) : name(std::move(n)), types(std::move(ts)) {} diff --git a/code/compiler/07/definition.cpp b/code/compiler/07/definition.cpp index 34c6f66..29b16cc 100644 --- a/code/compiler/07/definition.cpp +++ b/code/compiler/07/definition.cpp @@ -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; diff --git a/code/compiler/07/instruction.cpp b/code/compiler/07/instruction.cpp index 0272e20..3b421c0 100644 --- a/code/compiler/07/instruction.cpp +++ b/code/compiler/07/instruction.cpp @@ -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; diff --git a/code/compiler/07/instruction.hpp b/code/compiler/07/instruction.hpp index 879cd05..5228209 100644 --- a/code/compiler/07/instruction.hpp +++ b/code/compiler/07/instruction.hpp @@ -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; }; diff --git a/code/compiler/08/definition.cpp b/code/compiler/08/definition.cpp index 25aabee..fe116c8 100644 --- a/code/compiler/08/definition.cpp +++ b/code/compiler/08/definition.cpp @@ -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(); } diff --git a/code/compiler/08/instruction.cpp b/code/compiler/08/instruction.cpp index 2d2854a..23f4258 100644 --- a/code/compiler/08/instruction.cpp +++ b/code/compiler/08/instruction.cpp @@ -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; diff --git a/code/compiler/08/instruction.hpp b/code/compiler/08/instruction.hpp index fa31e18..abe2409 100644 --- a/code/compiler/08/instruction.hpp +++ b/code/compiler/08/instruction.hpp @@ -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; diff --git a/code/compiler/08/main.cpp b/code/compiler/08/main.cpp index c3d6047..47fdec4 100644 --- a/code/compiler/08/main.cpp +++ b/code/compiler/08/main.cpp @@ -69,9 +69,16 @@ void compile_program(const std::vector& 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 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(); }