Register booleans as internal types.

This commit is contained in:
2020-09-10 00:54:35 -07:00
parent df5f5eba1c
commit 73441dc93b
4 changed files with 126 additions and 29 deletions

View File

@@ -204,10 +204,10 @@ type_ptr ast_case::typecheck(type_mgr& mgr, type_env_ptr& env) {
input_type = mgr.resolve(case_type, var);
type_app* app_type;
if(!(app_type = dynamic_cast<type_app*>(input_type.get())) ||
!dynamic_cast<type_data*>(app_type->constructor.get())) {
throw type_error("attempting case analysis of non-data type", of->loc);
}
// if(!(app_type = dynamic_cast<type_app*>(input_type.get())) ||
// !dynamic_cast<type_data*>(app_type->constructor.get())) {
// throw type_error("attempting case analysis of non-data type", of->loc);
// }
return branch_type;
}
@@ -250,6 +250,11 @@ struct case_mappings {
assert(default_case);
return *default_case;
}
std::vector<instruction_ptr>& get_case_for(tag_type tag) {
if(case_defined_for(tag)) return get_specific_case_for(tag);
return get_default_case();
}
bool case_defined_for(tag_type tag) {
return defined_cases.find(tag) != defined_cases.end();
@@ -288,8 +293,19 @@ struct case_strategy_bool {
return 2;
}
instruction_ptr into_instruction(const type* type, case_mappings<case_strategy_bool>& ms) {
throw std::runtime_error("boolean case unimplemented!");
void into_instructions(
const type* type,
case_mappings<case_strategy_bool>& ms,
std::vector<instruction_ptr>& into) {
if(ms.defined_cases_count() == 0) {
for(auto& instruction : ms.get_default_case())
into.push_back(std::move(instruction));
return;
}
into.push_back(instruction_ptr(new instruction_if(
std::move(ms.get_case_for(true)),
std::move(ms.get_case_for(false)))));
}
};
@@ -327,7 +343,10 @@ struct case_strategy_data {
return static_cast<const type_data*>(type)->constructors.size();
}
instruction_ptr into_instruction(const type* type, case_mappings<case_strategy_data>& ms) {
void into_instructions(
const type* type,
case_mappings<case_strategy_data>& ms,
std::vector<instruction_ptr>& into) {
instruction_jump* jump_instruction = new instruction_jump();
instruction_ptr inst(jump_instruction);
@@ -350,7 +369,7 @@ struct case_strategy_data {
}
}
return std::move(inst);
into.push_back(std::move(inst));
}
};
@@ -364,6 +383,7 @@ void compile_case(const ast_case& node, const env_ptr& env, const type* type, st
auto& branch_into = cases.make_default_case();
env_ptr new_env(new env_var(branch->expr->env->get_mangled_name(vpat->var), env));
branch->expr->compile(new_env, branch_into);
branch_into.push_back(instruction_ptr(new instruction_slide(1)));
} else {
auto repr = strategy.from_typed_pattern(branch->pat, type);
auto& branch_into = cases.make_case_for(strategy.tag_from_repr(repr));
@@ -375,7 +395,7 @@ void compile_case(const ast_case& node, const env_ptr& env, const type* type, st
cases.default_case_defined()))
throw type_error("incomplete patterns", node.loc);
into.push_back(strategy.into_instruction(type, cases));
strategy.into_instructions(type, cases, into);
}
void ast_case::compile(const env_ptr& env, std::vector<instruction_ptr>& into) const {