fix: is_record was used incorrectly in code gen,
the real solution was to look up the datatype and check constructors length
This commit is contained in:
parent
d042d55d42
commit
a45001376d
|
@ -476,7 +476,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
assignment.hoist_over(clause_then)
|
assignment.hoist_over(clause_then)
|
||||||
} else {
|
} else {
|
||||||
clauses = if subject.tipo().is_list() {
|
clauses = if subject.tipo().is_list() {
|
||||||
rearrange_list_clauses(clauses)
|
rearrange_list_clauses(clauses, &self.data_types)
|
||||||
} else {
|
} else {
|
||||||
clauses
|
clauses
|
||||||
};
|
};
|
||||||
|
@ -1767,8 +1767,8 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
let mut is_wild_card_elems_clause = clause.guard.is_none();
|
let mut is_wild_card_elems_clause = clause.guard.is_none();
|
||||||
for element in elements.iter() {
|
for element in elements.iter() {
|
||||||
is_wild_card_elems_clause =
|
is_wild_card_elems_clause = is_wild_card_elems_clause
|
||||||
is_wild_card_elems_clause && !pattern_has_conditions(element);
|
&& !pattern_has_conditions(element, &self.data_types);
|
||||||
}
|
}
|
||||||
|
|
||||||
if *checked_index < elements_len.try_into().unwrap()
|
if *checked_index < elements_len.try_into().unwrap()
|
||||||
|
@ -2447,9 +2447,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Pattern::Constructor {
|
Pattern::Constructor {
|
||||||
name: constr_name,
|
name: constr_name, ..
|
||||||
is_record,
|
|
||||||
..
|
|
||||||
} => {
|
} => {
|
||||||
if subject_tipo.is_bool() {
|
if subject_tipo.is_bool() {
|
||||||
props.complex_clause = true;
|
props.complex_clause = true;
|
||||||
|
@ -2461,7 +2459,10 @@ impl<'a> CodeGenerator<'a> {
|
||||||
} else {
|
} else {
|
||||||
let (cond, assign) = self.clause_pattern(pattern, subject_tipo, props);
|
let (cond, assign) = self.clause_pattern(pattern, subject_tipo, props);
|
||||||
|
|
||||||
if *is_record {
|
let data_type = lookup_data_type_by_tipo(&self.data_types, subject_tipo)
|
||||||
|
.expect("Missing data type");
|
||||||
|
|
||||||
|
if data_type.constructors.len() == 1 {
|
||||||
assign
|
assign
|
||||||
} else {
|
} else {
|
||||||
props.complex_clause = true;
|
props.complex_clause = true;
|
||||||
|
|
|
@ -763,28 +763,36 @@ pub fn modify_self_calls(
|
||||||
recursive_nonstatics
|
recursive_nonstatics
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pattern_has_conditions(pattern: &TypedPattern) -> bool {
|
pub fn pattern_has_conditions(
|
||||||
|
pattern: &TypedPattern,
|
||||||
|
data_types: &IndexMap<DataTypeKey, &TypedDataType>,
|
||||||
|
) -> bool {
|
||||||
match pattern {
|
match pattern {
|
||||||
Pattern::Constructor {
|
Pattern::List { .. } | Pattern::Int { .. } => true,
|
||||||
is_record: false, ..
|
Pattern::Tuple { elems, .. } => elems
|
||||||
}
|
|
||||||
| Pattern::List { .. }
|
|
||||||
| Pattern::Int { .. } => true,
|
|
||||||
Pattern::Tuple { elems, .. } => elems.iter().any(pattern_has_conditions),
|
|
||||||
Pattern::Constructor {
|
|
||||||
is_record: true,
|
|
||||||
arguments,
|
|
||||||
..
|
|
||||||
} => arguments
|
|
||||||
.iter()
|
.iter()
|
||||||
.any(|arg| pattern_has_conditions(&arg.value)),
|
.any(|elem| pattern_has_conditions(elem, data_types)),
|
||||||
Pattern::Assign { pattern, .. } => pattern_has_conditions(pattern),
|
Pattern::Constructor {
|
||||||
|
arguments, tipo, ..
|
||||||
|
} => {
|
||||||
|
let data_type =
|
||||||
|
lookup_data_type_by_tipo(data_types, tipo).expect("Data type not found");
|
||||||
|
|
||||||
|
data_type.constructors.len() > 1
|
||||||
|
|| arguments
|
||||||
|
.iter()
|
||||||
|
.any(|arg| pattern_has_conditions(&arg.value, data_types))
|
||||||
|
}
|
||||||
|
Pattern::Assign { pattern, .. } => pattern_has_conditions(pattern, data_types),
|
||||||
Pattern::Var { .. } | Pattern::Discard { .. } => false,
|
Pattern::Var { .. } | Pattern::Discard { .. } => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: write some tests
|
// TODO: write some tests
|
||||||
pub fn rearrange_list_clauses(clauses: Vec<TypedClause>) -> Vec<TypedClause> {
|
pub fn rearrange_list_clauses(
|
||||||
|
clauses: Vec<TypedClause>,
|
||||||
|
data_types: &IndexMap<DataTypeKey, &TypedDataType>,
|
||||||
|
) -> Vec<TypedClause> {
|
||||||
let mut sorted_clauses = clauses;
|
let mut sorted_clauses = clauses;
|
||||||
|
|
||||||
// if we have a list sort clauses so we can plug holes for cases not covered by clauses
|
// if we have a list sort clauses so we can plug holes for cases not covered by clauses
|
||||||
|
@ -954,7 +962,7 @@ pub fn rearrange_list_clauses(clauses: Vec<TypedClause>) -> Vec<TypedClause> {
|
||||||
|
|
||||||
for element in elements.iter() {
|
for element in elements.iter() {
|
||||||
is_wild_card_elems_clause =
|
is_wild_card_elems_clause =
|
||||||
is_wild_card_elems_clause && !pattern_has_conditions(element);
|
is_wild_card_elems_clause && !pattern_has_conditions(element, data_types);
|
||||||
}
|
}
|
||||||
|
|
||||||
if is_wild_card_elems_clause {
|
if is_wild_card_elems_clause {
|
||||||
|
|
Loading…
Reference in New Issue