Implement ast_case::compile for compiler series and reference code

This commit is contained in:
Danila Fedorin 2019-10-08 23:46:35 -07:00
parent e4bf3a8672
commit 007c89501b
2 changed files with 51 additions and 0 deletions

View File

@ -176,7 +176,51 @@ void ast_case::resolve(const type_mgr& mgr) const {
}
void ast_case::compile(const env_ptr& env, std::vector<instruction_ptr>& into) const {
type_data* type = dynamic_cast<type_data*>(node_type.get());
of->compile(env, into);
into.push_back(instruction_ptr(new instruction_eval()));
instruction_jump* jump_instruction = new instruction_jump();
into.push_back(instruction_ptr(jump_instruction));
for(auto& branch : branches) {
std::vector<instruction_ptr> branch_instructions;
pattern_var* vpat;
pattern_constr* cpat;
if((vpat = dynamic_cast<pattern_var*>(branch->pat.get()))) {
branch->expr->compile(env_ptr(new env_offset(1, env)), branch_instructions);
for(auto& constr_pair : type->constructors) {
if(jump_instruction->tag_mappings.find(constr_pair.second.tag) !=
jump_instruction->tag_mappings.end())
break;
jump_instruction->tag_mappings[constr_pair.second.tag] =
jump_instruction->branches.size();
}
jump_instruction->branches.push_back(std::move(branch_instructions));
} else if((cpat = dynamic_cast<pattern_constr*>(branch->pat.get()))) {
branch_instructions.push_back(instruction_ptr(new instruction_split()));
branch->expr->compile(env_ptr(new env_offset(cpat->params.size(), env)),
branch_instructions);
int new_tag = type->constructors[cpat->constr].tag;
if(jump_instruction->tag_mappings.find(new_tag) !=
jump_instruction->tag_mappings.end())
throw type_error("technically not a type error: duplicate pattern");
jump_instruction->tag_mappings[new_tag] =
jump_instruction->branches.size();
jump_instruction->branches.push_back(std::move(branch_instructions));
}
}
for(auto& constr_pair : type->constructors) {
if(jump_instruction->tag_mappings.find(constr_pair.second.tag) ==
jump_instruction->tag_mappings.end())
throw type_error("non-total pattern");
}
}
void pattern_var::print(std::ostream& to) const {

View File

@ -2,6 +2,8 @@
#include <string>
#include <memory>
#include "binop.hpp"
#include <vector>
#include <map>
struct instruction {
virtual ~instruction() = default;
@ -53,6 +55,11 @@ struct instruction_split : public instruction {
};
struct instruction_jump : public instruction {
std::vector<std::vector<instruction_ptr>> branches;
std::map<int, int> tag_mappings;
};
struct instruction_slide : public instruction {
int offset;