Make make_case_for throw from the second time on.
Also clean up the errors thrown a little bit.
This commit is contained in:
parent
0e816e523a
commit
828be79ab5
14
13/ast.cpp
14
13/ast.cpp
|
@ -228,8 +228,6 @@ struct case_mappings {
|
||||||
std::optional<std::vector<instruction_ptr>> default_case;
|
std::optional<std::vector<instruction_ptr>> default_case;
|
||||||
|
|
||||||
std::vector<instruction_ptr>& make_case_for(tag_type tag) {
|
std::vector<instruction_ptr>& make_case_for(tag_type tag) {
|
||||||
auto existing_case = defined_cases.find(tag);
|
|
||||||
if(existing_case != defined_cases.end()) return existing_case->second;
|
|
||||||
if(default_case)
|
if(default_case)
|
||||||
throw type_error("attempted pattern match after catch-all");
|
throw type_error("attempted pattern match after catch-all");
|
||||||
return defined_cases[tag];
|
return defined_cases[tag];
|
||||||
|
@ -279,7 +277,9 @@ struct case_strategy_bool {
|
||||||
if(!(cpat = dynamic_cast<pattern_constr*>(pt.get())) ||
|
if(!(cpat = dynamic_cast<pattern_constr*>(pt.get())) ||
|
||||||
(cpat->constr != "True" && cpat->constr != "False") ||
|
(cpat->constr != "True" && cpat->constr != "False") ||
|
||||||
cpat->params.size() != 0)
|
cpat->params.size() != 0)
|
||||||
throw type_error("pattern cannot be converted to a boolean");
|
throw type_error(
|
||||||
|
"pattern cannot be converted to a boolean",
|
||||||
|
pt->loc);
|
||||||
return cpat->constr == "True";
|
return cpat->constr == "True";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,7 +321,9 @@ struct case_strategy_data {
|
||||||
repr_type from_typed_pattern(const pattern_ptr& pt, const type* type) {
|
repr_type from_typed_pattern(const pattern_ptr& pt, const type* type) {
|
||||||
pattern_constr* cpat;
|
pattern_constr* cpat;
|
||||||
if(!(cpat = dynamic_cast<pattern_constr*>(pt.get())))
|
if(!(cpat = dynamic_cast<pattern_constr*>(pt.get())))
|
||||||
throw type_error("pattern cannot be interpreted as constructor.");
|
throw type_error(
|
||||||
|
"pattern cannot be interpreted as constructor.",
|
||||||
|
pt->loc);
|
||||||
return std::make_pair(
|
return std::make_pair(
|
||||||
&static_cast<const type_data*>(type)->constructors.find(cpat->constr)->second,
|
&static_cast<const type_data*>(type)->constructors.find(cpat->constr)->second,
|
||||||
&cpat->params);
|
&cpat->params);
|
||||||
|
@ -383,6 +385,8 @@ void compile_case(const ast_case& node, const env_ptr& env, const type* type, st
|
||||||
for(auto& branch : node.branches) {
|
for(auto& branch : node.branches) {
|
||||||
pattern_var* vpat;
|
pattern_var* vpat;
|
||||||
if((vpat = dynamic_cast<pattern_var*>(branch->pat.get()))) {
|
if((vpat = dynamic_cast<pattern_var*>(branch->pat.get()))) {
|
||||||
|
if(cases.defined_cases_count() == strategy.case_count(type))
|
||||||
|
throw type_error("redundant catch-all pattern", branch->pat->loc);
|
||||||
auto& branch_into = cases.make_default_case();
|
auto& branch_into = cases.make_default_case();
|
||||||
env_ptr new_env(new env_var(branch->expr->env->get_mangled_name(vpat->var), env));
|
env_ptr new_env(new env_var(branch->expr->env->get_mangled_name(vpat->var), env));
|
||||||
branch->expr->compile(new_env, branch_into);
|
branch->expr->compile(new_env, branch_into);
|
||||||
|
@ -589,5 +593,5 @@ void pattern_constr::typecheck(type_ptr t, type_mgr& mgr, type_env_ptr& env) con
|
||||||
constructor_type = arr->right;
|
constructor_type = arr->right;
|
||||||
}
|
}
|
||||||
|
|
||||||
mgr.unify(constructor_type, t, loc);
|
mgr.unify(t, constructor_type, loc);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user