Skip to content

Commit

Permalink
fix: is_record was used incorrectly in code gen,
Browse files Browse the repository at this point in the history
the real solution was to look up the datatype and check constructors length
  • Loading branch information
MicroProofs committed Sep 13, 2023
1 parent d042d55 commit a450013
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 22 deletions.
15 changes: 8 additions & 7 deletions crates/aiken-lang/src/gen_uplc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ impl<'a> CodeGenerator<'a> {
assignment.hoist_over(clause_then)
} else {
clauses = if subject.tipo().is_list() {
rearrange_list_clauses(clauses)
rearrange_list_clauses(clauses, &self.data_types)
} else {
clauses
};
Expand Down Expand Up @@ -1767,8 +1767,8 @@ impl<'a> CodeGenerator<'a> {

let mut is_wild_card_elems_clause = clause.guard.is_none();
for element in elements.iter() {
is_wild_card_elems_clause =
is_wild_card_elems_clause && !pattern_has_conditions(element);
is_wild_card_elems_clause = is_wild_card_elems_clause
&& !pattern_has_conditions(element, &self.data_types);
}

if *checked_index < elements_len.try_into().unwrap()
Expand Down Expand Up @@ -2447,9 +2447,7 @@ impl<'a> CodeGenerator<'a> {
}
}
Pattern::Constructor {
name: constr_name,
is_record,
..
name: constr_name, ..
} => {
if subject_tipo.is_bool() {
props.complex_clause = true;
Expand All @@ -2461,7 +2459,10 @@ impl<'a> CodeGenerator<'a> {
} else {
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
} else {
props.complex_clause = true;
Expand Down
38 changes: 23 additions & 15 deletions crates/aiken-lang/src/gen_uplc/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -763,28 +763,36 @@ pub fn modify_self_calls(
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 {
Pattern::List { .. } | Pattern::Int { .. } => true,
Pattern::Tuple { elems, .. } => elems
.iter()
.any(|elem| pattern_has_conditions(elem, data_types)),
Pattern::Constructor {
is_record: false, ..
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::List { .. }
| Pattern::Int { .. } => true,
Pattern::Tuple { elems, .. } => elems.iter().any(pattern_has_conditions),
Pattern::Constructor {
is_record: true,
arguments,
..
} => arguments
.iter()
.any(|arg| pattern_has_conditions(&arg.value)),
Pattern::Assign { pattern, .. } => pattern_has_conditions(pattern),
Pattern::Assign { pattern, .. } => pattern_has_conditions(pattern, data_types),
Pattern::Var { .. } | Pattern::Discard { .. } => false,
}
}

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

// if we have a list sort clauses so we can plug holes for cases not covered by clauses
Expand Down Expand Up @@ -954,7 +962,7 @@ pub fn rearrange_list_clauses(clauses: Vec<TypedClause>) -> Vec<TypedClause> {

for element in elements.iter() {
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 {
Expand Down

0 comments on commit a450013

Please sign in to comment.