From e8fa8f54235770ff8a6159d284afcef439da4003 Mon Sep 17 00:00:00 2001 From: microproofs Date: Thu, 27 Jul 2023 17:05:22 -0400 Subject: [PATCH] fixing list clause issues --- crates/aiken-lang/src/gen_uplc.rs | 63 ++++++++++++++++------- crates/aiken-lang/src/gen_uplc/builder.rs | 22 +++++--- 2 files changed, 58 insertions(+), 27 deletions(-) diff --git a/crates/aiken-lang/src/gen_uplc.rs b/crates/aiken-lang/src/gen_uplc.rs index e9b95ce9..9adb8fba 100644 --- a/crates/aiken-lang/src/gen_uplc.rs +++ b/crates/aiken-lang/src/gen_uplc.rs @@ -1672,8 +1672,13 @@ impl<'a> CodeGenerator<'a> { None } else { let next_clause = &rest_clauses[0]; + let mut next_clause_pattern = &rest_clauses[0].pattern; - let next_elements_len = match &next_clause.pattern { + if let Pattern::Assign { pattern, .. } = next_clause_pattern { + next_clause_pattern = pattern; + } + + let next_elements_len = match next_clause_pattern { Pattern::List { elements, tail, .. } => { elements.len() - usize::from(tail.is_some()) } @@ -1686,8 +1691,8 @@ impl<'a> CodeGenerator<'a> { defined_tails.push(format!( "tail_index_{}_span_{}_{}", *current_index, - clause.pattern.location().start, - clause.pattern.location().end + next_clause.pattern.location().start, + next_clause.pattern.location().end )); Some(format!( @@ -1706,12 +1711,14 @@ impl<'a> CodeGenerator<'a> { for elements in elements.iter() { if let Pattern::Constructor { .. } | Pattern::Tuple { .. } - | Pattern::List { .. } = elements + | Pattern::List { .. } + | Pattern::Assign { .. } = elements { is_wild_card_elems_clause = false; } } let elements_len = elements.len() - usize::from(tail.is_some()); + let current_checked_index = *checked_index; if *checked_index < elements_len.try_into().unwrap() && is_wild_card_elems_clause @@ -1739,20 +1746,31 @@ impl<'a> CodeGenerator<'a> { let complex_clause = props.complex_clause; - // TODO: stuff - AirTree::list_clause( - tail_name, - subject_tipo.clone(), - clause_assign_hoisted, - self.handle_each_clause( - rest_clauses, - final_clause, - subject_tipo, - &mut next_clause_props, - ), - next_tail_name, - complex_clause, - ) + if current_checked_index < elements_len.try_into().unwrap() { + AirTree::list_clause( + tail_name, + subject_tipo.clone(), + clause_assign_hoisted, + self.handle_each_clause( + rest_clauses, + final_clause, + subject_tipo, + &mut next_clause_props, + ), + next_tail_name, + complex_clause, + ) + } else { + AirTree::wrap_clause( + clause_assign_hoisted, + self.handle_each_clause( + rest_clauses, + final_clause, + subject_tipo, + &mut next_clause_props, + ), + ) + } } SpecificClause::TupleClause { defined_tuple_indices, @@ -1946,7 +1964,9 @@ impl<'a> CodeGenerator<'a> { list_tail = Some((tail, elem_name.to_string())); } - defined_heads.push(elem_name) + if props.final_clause && defined_tails.is_empty() { + defined_heads.push(elem_name); + } }); let list_assign = if props.final_clause && defined_tails.is_empty() { @@ -1958,6 +1978,8 @@ impl<'a> CodeGenerator<'a> { AirTree::local_var(&props.original_subject_name, subject_tipo.clone()), ) } else { + assert!(defined_tails.len() >= defined_heads.len()); + AirTree::list_expose( defined_heads .into_iter() @@ -2272,7 +2294,8 @@ impl<'a> CodeGenerator<'a> { SpecificClause::ListClause { current_index, defined_tails, - .. + checked_index: _, + }, .. } = props diff --git a/crates/aiken-lang/src/gen_uplc/builder.rs b/crates/aiken-lang/src/gen_uplc/builder.rs index 594f1160..4cab244f 100644 --- a/crates/aiken-lang/src/gen_uplc/builder.rs +++ b/crates/aiken-lang/src/gen_uplc/builder.rs @@ -113,12 +113,12 @@ impl ClauseProperties { ClauseProperties { clause_var_name: constr_var, complex_clause: false, - original_subject_name: subject_name, + original_subject_name: subject_name.clone(), final_clause: false, needs_constr_var: false, specific_clause: SpecificClause::ListClause { current_index: 0, - defined_tails: vec![], + defined_tails: vec![subject_name], checked_index: -1, }, } @@ -695,6 +695,8 @@ pub fn rearrange_list_clauses(clauses: Vec) -> Vec { None }; + println!("sorted clauses: {:#?}", sorted_clauses); + for (index, clause) in sorted_clauses.iter().enumerate() { if last_clause_set { continue; @@ -708,7 +710,10 @@ pub fn rearrange_list_clauses(clauses: Vec) -> Vec { assert!(matches!( clause_pattern, - Pattern::List { .. } | Pattern::Var { .. } | Pattern::Discard { .. } + Pattern::List { .. } + | Pattern::Var { .. } + | Pattern::Discard { .. } + | Pattern::Assign { .. } )); if let Pattern::List { elements, tail, .. } = &clause.pattern { @@ -760,8 +765,10 @@ pub fn rearrange_list_clauses(clauses: Vec) -> Vec { let mut is_wild_card_elems_clause = clause.guard.is_none(); for elements in elements.iter() { - if let Pattern::Constructor { .. } | Pattern::Tuple { .. } | Pattern::List { .. } = - elements + if let Pattern::Constructor { .. } + | Pattern::Tuple { .. } + | Pattern::List { .. } + | Pattern::Assign { .. } = elements { is_wild_card_elems_clause = false; } @@ -769,7 +776,7 @@ pub fn rearrange_list_clauses(clauses: Vec) -> Vec { if is_wild_card_elems_clause { wild_card_clause_elems += 1; - if clause.guard.is_none() && tail.is_some() { + if clause.guard.is_none() && tail.is_some() && !elements.is_empty() { last_clause_index = index; last_clause_set = true; } @@ -801,13 +808,14 @@ pub fn rearrange_list_clauses(clauses: Vec) -> Vec { // Encountered a tail so stop there with that as last clause if last_clause_set { - final_clauses = final_clauses[0..last_clause_index].to_vec(); + final_clauses = final_clauses[0..last_clause_index + 1].to_vec(); } // insert hole fillers into clauses for (index, clause) in holes_to_fill.into_iter().rev() { final_clauses.insert(index, clause); } + assert!(final_clauses.len() > 1); final_clauses }