fix: multiple list cases of the same length weren't being handled

This commit is contained in:
Kasey White 2023-01-21 16:10:26 -05:00 committed by Lucas
parent a178cee7bf
commit e36f91c39c
4 changed files with 66 additions and 26 deletions

View File

@ -125,6 +125,10 @@ pub enum Air {
complex_clause: bool, complex_clause: bool,
}, },
WrapClause {
scope: Vec<u64>,
},
TupleClause { TupleClause {
scope: Vec<u64>, scope: Vec<u64>,
tipo: Arc<Type>, tipo: Arc<Type>,
@ -250,6 +254,8 @@ impl Air {
| Air::When { scope, .. } | Air::When { scope, .. }
| Air::Clause { scope, .. } | Air::Clause { scope, .. }
| Air::ListClause { scope, .. } | Air::ListClause { scope, .. }
| Air::TupleClause { scope, .. }
| Air::WrapClause { scope }
| Air::ClauseGuard { scope, .. } | Air::ClauseGuard { scope, .. }
| Air::ListClauseGuard { scope, .. } | Air::ListClauseGuard { scope, .. }
| Air::Discard { scope } | Air::Discard { scope }
@ -265,8 +271,7 @@ impl Air {
| Air::UnOp { scope, .. } | Air::UnOp { scope, .. }
| Air::Trace { scope, .. } | Air::Trace { scope, .. }
| Air::TupleAccessor { scope, .. } | Air::TupleAccessor { scope, .. }
| Air::TupleIndex { scope, .. } | Air::TupleIndex { scope, .. } => scope.to_vec(),
| Air::TupleClause { scope, .. } => scope.to_vec(),
} }
} }

View File

@ -61,7 +61,7 @@ pub enum ClauseProperties {
needs_constr_var: bool, needs_constr_var: bool,
is_complex_clause: bool, is_complex_clause: bool,
original_subject_name: String, original_subject_name: String,
current_index: usize, current_index: i64,
}, },
TupleClause { TupleClause {
clause_var_name: String, clause_var_name: String,
@ -80,7 +80,7 @@ impl ClauseProperties {
needs_constr_var: false, needs_constr_var: false,
is_complex_clause: false, is_complex_clause: false,
original_subject_name: subject_name, original_subject_name: subject_name,
current_index: 0, current_index: -1,
} }
} else if t.is_tuple() { } else if t.is_tuple() {
ClauseProperties::TupleClause { ClauseProperties::TupleClause {

View File

@ -645,7 +645,14 @@ impl<'a> CodeGenerator<'a> {
current_index, current_index,
.. ..
} => { } => {
let current_clause_index = *current_index; let current_clause_index =
if let Pattern::List { elements, .. } = &clause.pattern[0] {
elements.len()
} else {
unreachable!()
};
let prev_index = *current_index;
let subject_name = if current_clause_index == 0 { let subject_name = if current_clause_index == 0 {
original_subject_name.clone() original_subject_name.clone()
@ -665,20 +672,36 @@ impl<'a> CodeGenerator<'a> {
let next_tail = if index == clauses.len() - 1 { let next_tail = if index == clauses.len() - 1 {
None None
} else { } else {
Some(format!("__tail_{}", current_clause_index)) let next_list_size = if let Pattern::List { elements, .. } =
&clauses[index + 1].pattern[0]
{
elements.len()
} else {
unreachable!()
};
if next_list_size == current_clause_index {
None
} else {
Some(format!("__tail_{}", current_clause_index))
}
}; };
ir_stack.push(Air::ListClause { if current_clause_index as i64 == prev_index {
scope, ir_stack.push(Air::WrapClause { scope });
tipo: subject_type.clone(), } else {
tail_name: subject_name, ir_stack.push(Air::ListClause {
next_tail_name: next_tail, scope,
complex_clause: *clause_properties.is_complex_clause(), tipo: subject_type.clone(),
}); tail_name: subject_name,
next_tail_name: next_tail,
complex_clause: *clause_properties.is_complex_clause(),
});
}
match clause_properties { match clause_properties {
ClauseProperties::ListClause { current_index, .. } => { ClauseProperties::ListClause { current_index, .. } => {
*current_index += 1; *current_index = current_clause_index as i64;
} }
_ => unreachable!(), _ => unreachable!(),
} }
@ -1245,24 +1268,18 @@ impl<'a> CodeGenerator<'a> {
needs_constr_var: false, needs_constr_var: false,
is_complex_clause: false, is_complex_clause: false,
original_subject_name: item_name.clone(), original_subject_name: item_name.clone(),
current_index: index, current_index: index as i64,
}; };
let tail_name = format!("{}_{}", new_tail_name, index); let tail_name = format!("{}_{}", new_tail_name, index);
if elements.len() - 1 == index { if elements.len() - 1 == index {
if tail.is_some() { if tail.is_some() {
let tail_name = match *tail.clone().unwrap() {
Pattern::Var { name, .. } => name,
Pattern::Discard { .. } => "_".to_string(),
_ => unreachable!(),
};
pattern_vec.push(Air::ListClauseGuard { pattern_vec.push(Air::ListClauseGuard {
scope: scope.clone(), scope: scope.clone(),
tipo: pattern_type.clone(), tipo: pattern_type.clone(),
tail_name: prev_tail_name, tail_name: prev_tail_name,
next_tail_name: Some(tail_name), next_tail_name: None,
inverse: true, inverse: true,
}); });
@ -1331,7 +1348,6 @@ impl<'a> CodeGenerator<'a> {
} }
} }
// self.when_recursive_ir(a);
Some(item_name) Some(item_name)
} }
a @ Pattern::Constructor { a @ Pattern::Constructor {
@ -3796,6 +3812,25 @@ impl<'a> CodeGenerator<'a> {
arg_stack.push(term); arg_stack.push(term);
} }
Air::WrapClause { .. } => {
let _ = arg_stack.pop().unwrap();
let mut term = arg_stack.pop().unwrap();
let arg = arg_stack.pop().unwrap();
term = apply_wrap(
Term::Lambda {
parameter_name: Name {
text: "__other_clauses_delayed".into(),
unique: 0.into(),
},
body: term.into(),
},
Term::Delay(arg.into()),
);
arg_stack.push(term);
}
Air::ClauseGuard { Air::ClauseGuard {
subject_name, tipo, .. subject_name, tipo, ..
} => { } => {

View File

@ -1,9 +1,9 @@
test sort_by_1() { test sort_by_1() {
let xs = [[4, 3, 2, 1], [2, 3, 4, 5]] let xs = [[4, 3, 2, 1], [2, 3, 4, 5]]
when xs is { when xs is {
[[], ys] -> True [[], ys] -> False
[xs, []] -> True [xs, []] -> False
[[x, ..xs2], [y, ..ys2]] -> True [[x, ..xs2], [y, ..ys2]] -> True
_ -> True _ -> False
} }
} }