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:
microproofs 2023-09-13 00:33:02 -04:00
parent d042d55d42
commit a45001376d
2 changed files with 32 additions and 23 deletions

View File

@ -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;

View File

@ -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 {