diff --git a/code/compiler/13/ast.cpp b/code/compiler/13/ast.cpp index 8fc5d78..57293e9 100644 --- a/code/compiler/13/ast.cpp +++ b/code/compiler/13/ast.cpp @@ -3,6 +3,7 @@ #include #include "binop.hpp" #include "error.hpp" +#include "instruction.hpp" #include "type.hpp" #include "type_env.hpp" #include "env.hpp" @@ -308,9 +309,13 @@ struct case_strategy_bool { return; } - into.push_back(instruction_ptr(new instruction_if( - std::move(ms.get_case_for(true)), - std::move(ms.get_case_for(false))))); + instruction_ijump* ijump = new instruction_ijump(); + instruction_ptr inst(ijump); + ijump->branches.push_back(std::move(ms.get_case_for(false))); + ijump->tag_mappings[0] = 0; + ijump->branches.push_back(std::move(ms.get_case_for(true))); + ijump->tag_mappings[1] = 1; + into.push_back(std::move(inst)); } }; diff --git a/code/compiler/13/instruction.cpp b/code/compiler/13/instruction.cpp index 7fd8c0c..4700688 100644 --- a/code/compiler/13/instruction.cpp +++ b/code/compiler/13/instruction.cpp @@ -100,7 +100,7 @@ void instruction_jump::print(int indent, std::ostream& to) const { void instruction_jump::gen_llvm(llvm_context& ctx, Function* f) const { auto top_node = ctx.create_peek(f, ctx.create_size(0)); - auto tag = ctx.unwrap_data_tag(top_node); + auto tag = get_case_value(ctx, top_node); auto safety_block = ctx.create_basic_block("safety", f); auto switch_op = ctx.get_builder().CreateSwitch(tag, safety_block, tag_mappings.size()); std::vector blocks; @@ -122,43 +122,12 @@ void instruction_jump::gen_llvm(llvm_context& ctx, Function* f) const { ctx.get_builder().SetInsertPoint(safety_block); } -void instruction_if::print(int indent, std::ostream& to) const { - print_indent(indent, to); - to << "If(" << std::endl; - for(auto& instruction : on_true) { - instruction->print(indent + 2, to); - } - to << std::endl; - for(auto& instruction : on_false) { - instruction->print(indent + 2, to); - } - print_indent(indent, to); - to << ")" << std::endl; +Value* instruction_jump::get_case_value(llvm_context& ctx, Value* v) const { + return ctx.unwrap_data_tag(v); } -void instruction_if::gen_llvm(llvm_context& ctx, llvm::Function* f) const { - auto top_node = ctx.create_peek(f, ctx.create_size(0)); - auto num = ctx.unwrap_num(top_node); - - auto nonzero_block = ctx.create_basic_block("nonzero", f); - auto zero_block = ctx.create_basic_block("zero", f); - auto resume_block = ctx.create_basic_block("resume", f); - auto switch_op = ctx.get_builder().CreateSwitch(num, nonzero_block, 2); - - switch_op->addCase(ctx.create_i32(0), zero_block); - ctx.get_builder().SetInsertPoint(nonzero_block); - for(auto& instruction : on_true) { - instruction->gen_llvm(ctx, f); - } - ctx.get_builder().CreateBr(resume_block); - - ctx.get_builder().SetInsertPoint(zero_block); - for(auto& instruction : on_false) { - instruction->gen_llvm(ctx, f); - } - ctx.get_builder().CreateBr(resume_block); - - ctx.get_builder().SetInsertPoint(resume_block); +Value* instruction_ijump::get_case_value(llvm_context& ctx, Value* v) const { + return ctx.unwrap_num(v); } void instruction_slide::print(int indent, std::ostream& to) const { diff --git a/code/compiler/13/instruction.hpp b/code/compiler/13/instruction.hpp index 36b4191..15639ed 100644 --- a/code/compiler/13/instruction.hpp +++ b/code/compiler/13/instruction.hpp @@ -99,19 +99,12 @@ struct instruction_jump : public instruction { void print(int indent, std::ostream& to) const; void gen_llvm(llvm_context& ctx, llvm::Function* f) const; + + virtual llvm::Value* get_case_value(llvm_context& ctx, llvm::Value*) const; }; -struct instruction_if : public instruction { - std::vector on_true; - std::vector on_false; - - instruction_if( - std::vector t, - std::vector f) - : on_true(std::move(t)), on_false(std::move(f)) {} - - void print(int indent, std::ostream& to) const; - void gen_llvm(llvm_context& ctx, llvm::Function* f) const; +struct instruction_ijump : public instruction_jump { + llvm::Value* get_case_value(llvm_context& ctx, llvm::Value*) const; }; struct instruction_slide : public instruction {