nested lists now work
This commit is contained in:
parent
6126ee4cb4
commit
b7d506a8db
|
@ -134,6 +134,7 @@ pub enum Air {
|
||||||
tail_name: String,
|
tail_name: String,
|
||||||
next_tail_name: Option<String>,
|
next_tail_name: Option<String>,
|
||||||
complex_clause: bool,
|
complex_clause: bool,
|
||||||
|
inverse: bool,
|
||||||
},
|
},
|
||||||
|
|
||||||
TupleClause {
|
TupleClause {
|
||||||
|
@ -150,7 +151,6 @@ pub enum Air {
|
||||||
scope: Vec<u64>,
|
scope: Vec<u64>,
|
||||||
subject_name: String,
|
subject_name: String,
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
invert: bool,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
Discard {
|
Discard {
|
||||||
|
|
|
@ -443,7 +443,7 @@ pub fn rearrange_clauses(
|
||||||
let mut final_clauses = sorted_clauses.clone();
|
let mut final_clauses = sorted_clauses.clone();
|
||||||
let mut holes_to_fill = vec![];
|
let mut holes_to_fill = vec![];
|
||||||
let mut assign_plug_in_name = None;
|
let mut assign_plug_in_name = None;
|
||||||
let mut last_clause_index = sorted_clauses.len() - 1;
|
let mut last_clause_index = 0;
|
||||||
let mut last_clause_set = false;
|
let mut last_clause_set = false;
|
||||||
|
|
||||||
// If we have a catch all, use that. Otherwise use todo which will result in error
|
// If we have a catch all, use that. Otherwise use todo which will result in error
|
||||||
|
@ -454,10 +454,10 @@ pub fn rearrange_clauses(
|
||||||
sorted_clauses[sorted_clauses.len() - 1].clone().then
|
sorted_clauses[sorted_clauses.len() - 1].clone().then
|
||||||
}
|
}
|
||||||
Pattern::Discard { .. } => sorted_clauses[sorted_clauses.len() - 1].clone().then,
|
Pattern::Discard { .. } => sorted_clauses[sorted_clauses.len() - 1].clone().then,
|
||||||
_ => TypedExpr::Todo {
|
_ => TypedExpr::ErrorTerm {
|
||||||
location: Span::empty(),
|
location: Span::empty(),
|
||||||
label: None,
|
|
||||||
tipo: sorted_clauses[sorted_clauses.len() - 1].then.tipo(),
|
tipo: sorted_clauses[sorted_clauses.len() - 1].then.tipo(),
|
||||||
|
label: Some("Clause not filled".to_string()),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -512,12 +512,20 @@ pub fn rearrange_clauses(
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we have a pattern with no clause guards and a tail then no lists will get past here to other clauses
|
// if we have a pattern with no clause guards and a tail then no lists will get past here to other clauses
|
||||||
if let Pattern::List {
|
match &clause.pattern[0] {
|
||||||
|
Pattern::Var { .. } => {
|
||||||
|
last_clause_index = index;
|
||||||
|
last_clause_set = true;
|
||||||
|
}
|
||||||
|
Pattern::Discard { .. } => {
|
||||||
|
last_clause_index = index;
|
||||||
|
last_clause_set = true;
|
||||||
|
}
|
||||||
|
Pattern::List {
|
||||||
elements,
|
elements,
|
||||||
tail: Some(tail),
|
tail: Some(tail),
|
||||||
..
|
..
|
||||||
} = &clause.pattern[0]
|
} => {
|
||||||
{
|
|
||||||
let mut elements = elements.clone();
|
let mut elements = elements.clone();
|
||||||
elements.push(*tail.clone());
|
elements.push(*tail.clone());
|
||||||
if elements
|
if elements
|
||||||
|
@ -525,25 +533,16 @@ pub fn rearrange_clauses(
|
||||||
.all(|element| matches!(element, Pattern::Var { .. } | Pattern::Discard { .. }))
|
.all(|element| matches!(element, Pattern::Var { .. } | Pattern::Discard { .. }))
|
||||||
&& !last_clause_set
|
&& !last_clause_set
|
||||||
{
|
{
|
||||||
last_clause_index = index;
|
last_clause_index = index + 1;
|
||||||
last_clause_set = true;
|
last_clause_set = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
// If the last condition doesn't have a catch all or tail then add a catch all with a todo
|
// If the last condition doesn't have a catch all or tail then add a catch all with a todo
|
||||||
if index == sorted_clauses.len() - 1 {
|
if index == sorted_clauses.len() - 1 {
|
||||||
if let Pattern::List {
|
if let Pattern::List { tail: None, .. } = &clause.pattern[0] {
|
||||||
elements,
|
|
||||||
tail: Some(tail),
|
|
||||||
..
|
|
||||||
} = &clause.pattern[0]
|
|
||||||
{
|
|
||||||
let mut elements = elements.clone();
|
|
||||||
elements.push(*tail.clone());
|
|
||||||
if !elements
|
|
||||||
.iter()
|
|
||||||
.all(|element| matches!(element, Pattern::Var { .. } | Pattern::Discard { .. }))
|
|
||||||
{
|
|
||||||
final_clauses.push(Clause {
|
final_clauses.push(Clause {
|
||||||
location: Span::empty(),
|
location: Span::empty(),
|
||||||
pattern: vec![Pattern::Discard {
|
pattern: vec![Pattern::Discard {
|
||||||
|
@ -556,13 +555,14 @@ pub fn rearrange_clauses(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
elems_len += 1;
|
elems_len += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encountered a tail so stop there with that as last clause
|
// Encountered a tail so stop there with that as last clause
|
||||||
final_clauses = final_clauses[0..(last_clause_index + 1)].to_vec();
|
if last_clause_set {
|
||||||
|
final_clauses = final_clauses[0..last_clause_index].to_vec();
|
||||||
|
}
|
||||||
|
|
||||||
// insert hole fillers into clauses
|
// insert hole fillers into clauses
|
||||||
for (index, clause) in holes_to_fill.into_iter().rev() {
|
for (index, clause) in holes_to_fill.into_iter().rev() {
|
||||||
|
@ -1201,6 +1201,7 @@ pub fn monomorphize(
|
||||||
tail_name,
|
tail_name,
|
||||||
complex_clause,
|
complex_clause,
|
||||||
next_tail_name,
|
next_tail_name,
|
||||||
|
inverse,
|
||||||
} => {
|
} => {
|
||||||
if tipo.is_generic() {
|
if tipo.is_generic() {
|
||||||
let mut tipo = tipo.clone();
|
let mut tipo = tipo.clone();
|
||||||
|
@ -1212,6 +1213,7 @@ pub fn monomorphize(
|
||||||
tail_name,
|
tail_name,
|
||||||
complex_clause,
|
complex_clause,
|
||||||
next_tail_name,
|
next_tail_name,
|
||||||
|
inverse,
|
||||||
};
|
};
|
||||||
needs_variant = false;
|
needs_variant = false;
|
||||||
}
|
}
|
||||||
|
@ -1220,7 +1222,6 @@ pub fn monomorphize(
|
||||||
tipo,
|
tipo,
|
||||||
scope,
|
scope,
|
||||||
subject_name,
|
subject_name,
|
||||||
invert,
|
|
||||||
} => {
|
} => {
|
||||||
if tipo.is_generic() {
|
if tipo.is_generic() {
|
||||||
let mut tipo = tipo.clone();
|
let mut tipo = tipo.clone();
|
||||||
|
@ -1230,7 +1231,6 @@ pub fn monomorphize(
|
||||||
scope,
|
scope,
|
||||||
subject_name,
|
subject_name,
|
||||||
tipo,
|
tipo,
|
||||||
invert,
|
|
||||||
};
|
};
|
||||||
needs_variant = false;
|
needs_variant = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use itertools::Itertools;
|
||||||
use uplc::{
|
use uplc::{
|
||||||
ast::{
|
ast::{
|
||||||
builder::{
|
builder::{
|
||||||
self, constr_index_exposer, delayed_choose_list, delayed_if_else, if_else,
|
self, choose_list, constr_index_exposer, delayed_choose_list, delayed_if_else, if_else,
|
||||||
CONSTR_FIELDS_EXPOSER, CONSTR_GET_FIELD,
|
CONSTR_FIELDS_EXPOSER, CONSTR_GET_FIELD,
|
||||||
},
|
},
|
||||||
Constant as UplcConstant, Name, NamedDeBruijn, Program, Term, Type as UplcType,
|
Constant as UplcConstant, Name, NamedDeBruijn, Program, Term, Type as UplcType,
|
||||||
|
@ -621,9 +621,17 @@ impl<'a> CodeGenerator<'a> {
|
||||||
scope,
|
scope,
|
||||||
tipo: subject_type.clone(),
|
tipo: subject_type.clone(),
|
||||||
tail_name: subject_name,
|
tail_name: subject_name,
|
||||||
complex_clause: *clause_properties.is_complex_clause(),
|
|
||||||
next_tail_name: next_tail,
|
next_tail_name: next_tail,
|
||||||
|
complex_clause: *clause_properties.is_complex_clause(),
|
||||||
|
inverse: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
match clause_properties {
|
||||||
|
ClauseProperties::ListClause { current_index, .. } => {
|
||||||
|
*current_index += 1;
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ClauseProperties::TupleClause {
|
ClauseProperties::TupleClause {
|
||||||
original_subject_name,
|
original_subject_name,
|
||||||
|
@ -763,13 +771,11 @@ impl<'a> CodeGenerator<'a> {
|
||||||
self.when_recursive_ir(
|
self.when_recursive_ir(
|
||||||
pattern,
|
pattern,
|
||||||
pattern_vec,
|
pattern_vec,
|
||||||
&mut vec![],
|
values,
|
||||||
clause_properties.clone(),
|
clause_properties.clone(),
|
||||||
tipo,
|
tipo,
|
||||||
scope,
|
scope,
|
||||||
);
|
);
|
||||||
|
|
||||||
pattern_vec.append(values);
|
|
||||||
}
|
}
|
||||||
Pattern::Constructor {
|
Pattern::Constructor {
|
||||||
arguments,
|
arguments,
|
||||||
|
@ -890,8 +896,6 @@ impl<'a> CodeGenerator<'a> {
|
||||||
pattern_vec.append(values);
|
pattern_vec.append(values);
|
||||||
}
|
}
|
||||||
Pattern::List { elements, tail, .. } => {
|
Pattern::List { elements, tail, .. } => {
|
||||||
// let mut elements_vec = vec![];
|
|
||||||
|
|
||||||
let mut names = vec![];
|
let mut names = vec![];
|
||||||
let mut nested_pattern = vec![];
|
let mut nested_pattern = vec![];
|
||||||
let items_type = &tipo.get_inner_types()[0];
|
let items_type = &tipo.get_inner_types()[0];
|
||||||
|
@ -957,8 +961,8 @@ impl<'a> CodeGenerator<'a> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pattern_vec.append(values);
|
|
||||||
pattern_vec.append(&mut nested_pattern);
|
pattern_vec.append(&mut nested_pattern);
|
||||||
|
pattern_vec.append(values);
|
||||||
}
|
}
|
||||||
Pattern::Constructor {
|
Pattern::Constructor {
|
||||||
is_record,
|
is_record,
|
||||||
|
@ -1011,7 +1015,11 @@ impl<'a> CodeGenerator<'a> {
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|item| {
|
.filter_map(|item| {
|
||||||
let label = item.label.clone().unwrap_or_default();
|
let label = item.label.clone().unwrap_or_default();
|
||||||
let field_index = field_map.fields.get(&label).unwrap_or(&0);
|
let field_index = field_map
|
||||||
|
.fields
|
||||||
|
.get(&label)
|
||||||
|
.map(|(index, _)| index)
|
||||||
|
.unwrap_or(&0);
|
||||||
let var_name = self.nested_pattern_ir_and_label(
|
let var_name = self.nested_pattern_ir_and_label(
|
||||||
&item.value,
|
&item.value,
|
||||||
&mut nested_pattern,
|
&mut nested_pattern,
|
||||||
|
@ -1095,30 +1103,73 @@ impl<'a> CodeGenerator<'a> {
|
||||||
Pattern::Var { name, .. } => Some(name.clone()),
|
Pattern::Var { name, .. } => Some(name.clone()),
|
||||||
Pattern::Discard { .. } => None,
|
Pattern::Discard { .. } => None,
|
||||||
a @ Pattern::List { elements, tail, .. } => {
|
a @ Pattern::List { elements, tail, .. } => {
|
||||||
let item_name = format!("list_item_id_{}", self.id_gen.next());
|
let item_name = format!("__list_item_id_{}", self.id_gen.next());
|
||||||
|
let new_tail_name = "__list_tail".to_string();
|
||||||
|
|
||||||
if elements.is_empty() {
|
if elements.is_empty() {
|
||||||
pattern_vec.push(Air::ClauseGuard {
|
pattern_vec.push(Air::ListClause {
|
||||||
scope: scope.clone(),
|
scope: scope.clone(),
|
||||||
subject_name: item_name.clone(),
|
|
||||||
tipo: pattern_type.clone(),
|
tipo: pattern_type.clone(),
|
||||||
invert: false,
|
tail_name: item_name.clone(),
|
||||||
|
next_tail_name: None,
|
||||||
|
complex_clause: false,
|
||||||
|
inverse: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
pattern_vec.push(Air::Discard {
|
||||||
|
scope: scope.clone(),
|
||||||
|
});
|
||||||
|
|
||||||
|
pattern_vec.push(Air::Var {
|
||||||
|
scope,
|
||||||
|
constructor: ValueConstructor::public(
|
||||||
|
pattern_type.clone(),
|
||||||
|
ValueConstructorVariant::LocalVariable {
|
||||||
|
location: Span::empty(),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
name: "__other_clauses_delayed".to_string(),
|
||||||
|
variant_name: String::new(),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
for (index, element) in elements.iter().enumerate() {
|
for (index, _) in elements.iter().enumerate() {
|
||||||
if index == 0 {
|
let prev_tail_name = if index == 0 {
|
||||||
pattern_vec.push(Air::ClauseGuard {
|
item_name.clone()
|
||||||
scope: scope.clone(),
|
} else {
|
||||||
subject_name: item_name.clone(),
|
format!("{}_{}", new_tail_name, index - 1)
|
||||||
tipo: pattern_type.clone(),
|
};
|
||||||
invert: true,
|
|
||||||
});
|
let mut clause_properties = ClauseProperties::ListClause {
|
||||||
pattern_vec.push(Air::ListAccessor {
|
clause_var_name: item_name.clone(),
|
||||||
|
needs_constr_var: false,
|
||||||
|
is_complex_clause: false,
|
||||||
|
original_subject_name: item_name.clone(),
|
||||||
|
current_index: index,
|
||||||
|
};
|
||||||
|
|
||||||
|
let tail_name = format!("{}_{}", new_tail_name, index);
|
||||||
|
|
||||||
|
if elements.len() - 1 == index {
|
||||||
|
if tail.is_some() {
|
||||||
|
let tail_name = match *tail.clone().unwrap() {
|
||||||
|
Pattern::Var { name, .. } => name,
|
||||||
|
Pattern::Discard { .. } => "_".to_string(),
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
pattern_vec.push(Air::ListClause {
|
||||||
scope: scope.clone(),
|
scope: scope.clone(),
|
||||||
tipo: pattern_type.clone(),
|
tipo: pattern_type.clone(),
|
||||||
names: vec![format!("todo")],
|
tail_name: prev_tail_name,
|
||||||
tail: false,
|
next_tail_name: Some(tail_name),
|
||||||
|
complex_clause: false,
|
||||||
|
inverse: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
pattern_vec.push(Air::Discard {
|
||||||
|
scope: scope.clone(),
|
||||||
|
});
|
||||||
|
|
||||||
pattern_vec.push(Air::Var {
|
pattern_vec.push(Air::Var {
|
||||||
scope: scope.clone(),
|
scope: scope.clone(),
|
||||||
constructor: ValueConstructor::public(
|
constructor: ValueConstructor::public(
|
||||||
|
@ -1127,20 +1178,9 @@ impl<'a> CodeGenerator<'a> {
|
||||||
location: Span::empty(),
|
location: Span::empty(),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
name: item_name.clone(),
|
name: "__other_clauses_delayed".to_string(),
|
||||||
variant_name: String::new(),
|
variant_name: "".to_string(),
|
||||||
});
|
});
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut clause_properties = ClauseProperties::ListClause {
|
|
||||||
clause_var_name: item_name.clone(),
|
|
||||||
needs_constr_var: false,
|
|
||||||
is_complex_clause: false,
|
|
||||||
original_subject_name: item_name.clone(),
|
|
||||||
current_index: 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
self.when_ir(
|
self.when_ir(
|
||||||
a,
|
a,
|
||||||
|
@ -1148,8 +1188,111 @@ impl<'a> CodeGenerator<'a> {
|
||||||
&mut vec![],
|
&mut vec![],
|
||||||
pattern_type,
|
pattern_type,
|
||||||
&mut clause_properties,
|
&mut clause_properties,
|
||||||
scope,
|
scope.clone(),
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
pattern_vec.push(Air::ListClause {
|
||||||
|
scope: scope.clone(),
|
||||||
|
tipo: pattern_type.clone(),
|
||||||
|
tail_name: prev_tail_name,
|
||||||
|
next_tail_name: Some(tail_name.clone()),
|
||||||
|
complex_clause: false,
|
||||||
|
inverse: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
pattern_vec.push(Air::Discard {
|
||||||
|
scope: scope.clone(),
|
||||||
|
});
|
||||||
|
|
||||||
|
pattern_vec.push(Air::Var {
|
||||||
|
scope: scope.clone(),
|
||||||
|
constructor: ValueConstructor::public(
|
||||||
|
pattern_type.clone(),
|
||||||
|
ValueConstructorVariant::LocalVariable {
|
||||||
|
location: Span::empty(),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
name: "__other_clauses_delayed".to_string(),
|
||||||
|
variant_name: String::new(),
|
||||||
|
});
|
||||||
|
|
||||||
|
pattern_vec.push(Air::ListClause {
|
||||||
|
scope: scope.clone(),
|
||||||
|
tipo: pattern_type.clone(),
|
||||||
|
tail_name: tail_name.clone(),
|
||||||
|
next_tail_name: None,
|
||||||
|
complex_clause: false,
|
||||||
|
inverse: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
pattern_vec.push(Air::Discard {
|
||||||
|
scope: scope.clone(),
|
||||||
|
});
|
||||||
|
|
||||||
|
pattern_vec.push(Air::Var {
|
||||||
|
scope: scope.clone(),
|
||||||
|
constructor: ValueConstructor::public(
|
||||||
|
pattern_type.clone(),
|
||||||
|
ValueConstructorVariant::LocalVariable {
|
||||||
|
location: Span::empty(),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
name: "__other_clauses_delayed".to_string(),
|
||||||
|
variant_name: String::new(),
|
||||||
|
});
|
||||||
|
|
||||||
|
self.when_ir(
|
||||||
|
a,
|
||||||
|
pattern_vec,
|
||||||
|
&mut vec![],
|
||||||
|
pattern_type,
|
||||||
|
&mut clause_properties,
|
||||||
|
scope.clone(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let tail_name = match *tail.clone().unwrap() {
|
||||||
|
Pattern::Var { name, .. } => name,
|
||||||
|
Pattern::Discard { .. } => "_".to_string(),
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
pattern_vec.push(Air::ListClause {
|
||||||
|
scope: scope.clone(),
|
||||||
|
tipo: pattern_type.clone(),
|
||||||
|
tail_name: prev_tail_name,
|
||||||
|
next_tail_name: Some(tail_name),
|
||||||
|
complex_clause: false,
|
||||||
|
inverse: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
pattern_vec.push(Air::Discard {
|
||||||
|
scope: scope.clone(),
|
||||||
|
});
|
||||||
|
|
||||||
|
pattern_vec.push(Air::Var {
|
||||||
|
scope: scope.clone(),
|
||||||
|
constructor: ValueConstructor::public(
|
||||||
|
pattern_type.clone(),
|
||||||
|
ValueConstructorVariant::LocalVariable {
|
||||||
|
location: Span::empty(),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
name: "__other_clauses_delayed".to_string(),
|
||||||
|
variant_name: "".to_string(),
|
||||||
|
});
|
||||||
|
|
||||||
|
self.when_ir(
|
||||||
|
a,
|
||||||
|
pattern_vec,
|
||||||
|
&mut vec![],
|
||||||
|
pattern_type,
|
||||||
|
&mut clause_properties,
|
||||||
|
scope.clone(),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// self.when_recursive_ir(a);
|
// self.when_recursive_ir(a);
|
||||||
Some(item_name)
|
Some(item_name)
|
||||||
|
@ -1183,7 +1326,6 @@ impl<'a> CodeGenerator<'a> {
|
||||||
scope: scope.clone(),
|
scope: scope.clone(),
|
||||||
tipo: tipo.clone(),
|
tipo: tipo.clone(),
|
||||||
subject_name: constr_var_name.clone(),
|
subject_name: constr_var_name.clone(),
|
||||||
invert: false,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1200,7 +1342,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
&mut vec![],
|
&mut vec![],
|
||||||
tipo,
|
tipo,
|
||||||
&mut clause_properties,
|
&mut clause_properties,
|
||||||
scope.clone(),
|
scope,
|
||||||
);
|
);
|
||||||
|
|
||||||
Some(constr_var_name)
|
Some(constr_var_name)
|
||||||
|
@ -3196,16 +3338,26 @@ impl<'a> CodeGenerator<'a> {
|
||||||
Air::ListClause {
|
Air::ListClause {
|
||||||
tail_name,
|
tail_name,
|
||||||
next_tail_name,
|
next_tail_name,
|
||||||
|
inverse,
|
||||||
|
complex_clause,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
// discard to pop off
|
// discard to pop off
|
||||||
let _ = arg_stack.pop().unwrap();
|
let _ = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
// the body to be run if the clause matches
|
// the body to be run if the clause matches
|
||||||
|
// the next branch in the when expression
|
||||||
|
let (body, mut term) = if inverse {
|
||||||
|
let term = arg_stack.pop().unwrap();
|
||||||
let body = arg_stack.pop().unwrap();
|
let body = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
// the next branch in the when expression
|
(body, term)
|
||||||
let mut term = arg_stack.pop().unwrap();
|
} else {
|
||||||
|
let body = arg_stack.pop().unwrap();
|
||||||
|
let term = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
|
(body, term)
|
||||||
|
};
|
||||||
|
|
||||||
let arg = if let Some(next_tail_name) = next_tail_name {
|
let arg = if let Some(next_tail_name) = next_tail_name {
|
||||||
Term::Apply {
|
Term::Apply {
|
||||||
|
@ -3231,6 +3383,32 @@ impl<'a> CodeGenerator<'a> {
|
||||||
term
|
term
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if complex_clause {
|
||||||
|
term = choose_list(
|
||||||
|
Term::Var(Name {
|
||||||
|
text: tail_name,
|
||||||
|
unique: 0.into(),
|
||||||
|
}),
|
||||||
|
Term::Delay(body.into()),
|
||||||
|
Term::Var(Name {
|
||||||
|
text: "__other_clauses_delayed".to_string(),
|
||||||
|
unique: 0.into(),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.force_wrap();
|
||||||
|
|
||||||
|
term = Term::Apply {
|
||||||
|
function: Term::Lambda {
|
||||||
|
parameter_name: Name {
|
||||||
|
text: "__other_clauses_delayed".into(),
|
||||||
|
unique: 0.into(),
|
||||||
|
},
|
||||||
|
body: term.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: Term::Delay(arg.into()).into(),
|
||||||
|
};
|
||||||
|
} else {
|
||||||
term = delayed_choose_list(
|
term = delayed_choose_list(
|
||||||
Term::Var(Name {
|
Term::Var(Name {
|
||||||
text: tail_name,
|
text: tail_name,
|
||||||
|
@ -3239,14 +3417,12 @@ impl<'a> CodeGenerator<'a> {
|
||||||
body,
|
body,
|
||||||
arg,
|
arg,
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
arg_stack.push(term);
|
arg_stack.push(term);
|
||||||
}
|
}
|
||||||
Air::ClauseGuard {
|
Air::ClauseGuard {
|
||||||
subject_name,
|
subject_name, tipo, ..
|
||||||
tipo,
|
|
||||||
invert,
|
|
||||||
..
|
|
||||||
} => {
|
} => {
|
||||||
let condition = arg_stack.pop().unwrap();
|
let condition = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
|
|
|
@ -314,7 +314,7 @@ pub fn delayed_choose_list(
|
||||||
Term::Apply {
|
Term::Apply {
|
||||||
function: Term::Apply {
|
function: Term::Apply {
|
||||||
function: Term::Apply {
|
function: Term::Apply {
|
||||||
function: Term::Builtin(DefaultFunction::IfThenElse)
|
function: Term::Builtin(DefaultFunction::ChooseList)
|
||||||
.force_wrap()
|
.force_wrap()
|
||||||
.force_wrap()
|
.force_wrap()
|
||||||
.into(),
|
.into(),
|
||||||
|
@ -337,7 +337,7 @@ pub fn choose_list(
|
||||||
Term::Apply {
|
Term::Apply {
|
||||||
function: Term::Apply {
|
function: Term::Apply {
|
||||||
function: Term::Apply {
|
function: Term::Apply {
|
||||||
function: Term::Builtin(DefaultFunction::IfThenElse)
|
function: Term::Builtin(DefaultFunction::ChooseList)
|
||||||
.force_wrap()
|
.force_wrap()
|
||||||
.force_wrap()
|
.force_wrap()
|
||||||
.into(),
|
.into(),
|
||||||
|
|
Loading…
Reference in New Issue