tuple destructuring nested and not now works

This commit is contained in:
Kasey White 2022-12-26 23:44:56 -05:00 committed by Lucas
parent a08c615da4
commit 919ea6c723
3 changed files with 170 additions and 70 deletions

View File

@ -383,9 +383,7 @@ pub fn convert_data_to_type(term: Term<Name>, field_type: &Arc<Type>) -> Term<Na
} }
.into(), .into(),
argument: Term::Apply { argument: Term::Apply {
function: Term::Builtin(DefaultFunction::UnListData) function: Term::Builtin(DefaultFunction::UnListData).into(),
.force_wrap()
.into(),
argument: term.into(), argument: term.into(),
} }
.into(), .into(),
@ -514,11 +512,11 @@ 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
match &clause.pattern[0] { match &clause.pattern[0] {
Pattern::Var { .. } => { Pattern::Var { .. } => {
last_clause_index = index; last_clause_index = index + 1;
last_clause_set = true; last_clause_set = true;
} }
Pattern::Discard { .. } => { Pattern::Discard { .. } => {
last_clause_index = index; last_clause_index = index + 1;
last_clause_set = true; last_clause_set = true;
} }
Pattern::List { Pattern::List {
@ -532,6 +530,7 @@ pub fn rearrange_clauses(
.iter() .iter()
.all(|element| matches!(element, Pattern::Var { .. } | Pattern::Discard { .. })) .all(|element| matches!(element, Pattern::Var { .. } | Pattern::Discard { .. }))
&& !last_clause_set && !last_clause_set
&& !elements.is_empty()
{ {
last_clause_index = index + 1; last_clause_index = index + 1;
last_clause_set = true; last_clause_set = true;
@ -627,8 +626,7 @@ pub fn list_access_to_uplc(
} }
.into(), .into(),
argument: Term::Apply { argument: Term::Apply {
function: Term::Force(Term::Builtin(DefaultFunction::TailList).into()) function: Term::Builtin(DefaultFunction::TailList).force_wrap().into(),
.into(),
argument: Term::Var(Name { argument: Term::Var(Name {
text: format!( text: format!(
"tail_index_{}_{}", "tail_index_{}_{}",
@ -697,8 +695,7 @@ pub fn list_access_to_uplc(
) )
.into(), .into(),
argument: Term::Apply { argument: Term::Apply {
function: Term::Force(Term::Builtin(DefaultFunction::TailList).into()) function: Term::Builtin(DefaultFunction::TailList).force_wrap().into(),
.into(),
argument: Term::Var(Name { argument: Term::Var(Name {
text: format!( text: format!(
"tail_index_{}_{}", "tail_index_{}_{}",
@ -1264,6 +1261,8 @@ pub fn monomorphize(
find_generics_to_replace(&mut tipo, &generic_types); find_generics_to_replace(&mut tipo, &generic_types);
needs_variant = false; needs_variant = false;
new_indices.push((ind, name, tipo)); new_indices.push((ind, name, tipo));
} else {
new_indices.push((ind, name, tipo));
} }
} }
new_air[index] = Air::FieldsExpose { new_air[index] = Air::FieldsExpose {
@ -1291,7 +1290,40 @@ pub fn monomorphize(
} }
} }
Air::RecordUpdate { .. } => todo!(), Air::RecordUpdate { .. } => todo!(),
Air::TupleAccessor { .. } => todo!(), Air::TupleAccessor { scope, names, tipo } => {
if tipo.is_generic() {
let mut tipo = tipo.clone();
find_generics_to_replace(&mut tipo, &generic_types);
new_air[index] = Air::TupleAccessor { scope, names, tipo };
needs_variant = false;
}
}
Air::TupleClause {
scope,
tipo,
indices,
predefined_indices,
subject_name,
count,
complex_clause,
} => {
if tipo.is_generic() {
let mut tipo = tipo.clone();
find_generics_to_replace(&mut tipo, &generic_types);
new_air[index] = Air::TupleClause {
scope,
tipo,
indices,
predefined_indices,
subject_name,
count,
complex_clause,
};
needs_variant = false;
}
}
_ => {} _ => {}
} }
} }

View File

@ -11,7 +11,7 @@ use uplc::{
ast::{ ast::{
builder::{ builder::{
self, apply_wrap, choose_list, constr_index_exposer, delayed_choose_list, self, apply_wrap, choose_list, constr_index_exposer, delayed_choose_list,
delayed_if_else, if_else, CONSTR_FIELDS_EXPOSER, CONSTR_GET_FIELD, delayed_if_else, if_else, repeat_tail_list, 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,
}, },
@ -1018,10 +1018,6 @@ impl<'a> CodeGenerator<'a> {
type_map.insert(label, field_type); type_map.insert(label, field_type);
} }
println!("TYPE MAP IS {type_map:#?}");
println!("Type args are {:#?}", tipo.arg_types());
println!("ARGUMENTS ARE {:#?}", arguments);
let arguments_index = arguments let arguments_index = arguments
.iter() .iter()
.filter_map(|item| { .filter_map(|item| {
@ -1141,7 +1137,6 @@ impl<'a> CodeGenerator<'a> {
defined_indices.insert((index, name)); defined_indices.insert((index, name));
} }
} }
println!("DEFINED INDICES ARE {:#?}", defined_indices);
for (index, name) in previous_defined_names { for (index, name) in previous_defined_names {
let new_name = names let new_name = names
@ -1179,8 +1174,6 @@ impl<'a> CodeGenerator<'a> {
_ => unreachable!(), _ => unreachable!(),
} }
println!("CLAUSE PROPERTIES IS NOW {:#?}", clause_properties);
pattern_vec.append(&mut nested_pattern); pattern_vec.append(&mut nested_pattern);
pattern_vec.append(values); pattern_vec.append(values);
} }
@ -1473,7 +1466,7 @@ impl<'a> CodeGenerator<'a> {
}; };
pattern_vec.push(Air::TupleClause { pattern_vec.push(Air::TupleClause {
scope: scope.clone(), scope,
tipo: pattern_type.clone(), tipo: pattern_type.clone(),
indices: defined_indices, indices: defined_indices,
predefined_indices: HashSet::new(), predefined_indices: HashSet::new(),
@ -2314,7 +2307,8 @@ impl<'a> CodeGenerator<'a> {
module, module,
.. ..
} => { } => {
let name = if *func_name == name { let name = if *func_name == name || name == format!("{module}_{func_name}")
{
format!("{module}_{func_name}{variant_name}") format!("{module}_{func_name}{variant_name}")
} else { } else {
format!("{func_name}{variant_name}") format!("{func_name}{variant_name}")
@ -2627,10 +2621,9 @@ impl<'a> CodeGenerator<'a> {
) )
.into(), .into(),
argument: Term::Apply { argument: Term::Apply {
function: Term::Force( function: Term::Builtin(DefaultFunction::TailList)
Term::Builtin(DefaultFunction::TailList).into(), .force_wrap()
) .into(),
.into(),
argument: Term::Var(Name { argument: Term::Var(Name {
text: format!("__list_{}", list_id), text: format!("__list_{}", list_id),
unique: 0.into(), unique: 0.into(),
@ -3602,10 +3595,10 @@ impl<'a> CodeGenerator<'a> {
} else { } else {
Term::Apply { Term::Apply {
function: DefaultFunction::EqualsInteger.into(), function: DefaultFunction::EqualsInteger.into(),
argument: Term::Var(Name { argument: constr_index_exposer(Term::Var(Name {
text: subject_name, text: subject_name,
unique: 0.into(), unique: 0.into(),
}) }))
.into(), .into(),
} }
}; };
@ -3794,7 +3787,6 @@ impl<'a> CodeGenerator<'a> {
.into(), .into(),
argument: Term::Apply { argument: Term::Apply {
function: Term::Builtin(DefaultFunction::TailList) function: Term::Builtin(DefaultFunction::TailList)
.force_wrap()
.force_wrap() .force_wrap()
.into(), .into(),
argument: prev_tail.into(), argument: prev_tail.into(),
@ -3814,7 +3806,6 @@ impl<'a> CodeGenerator<'a> {
.into(), .into(),
argument: Term::Apply { argument: Term::Apply {
function: Term::Builtin(DefaultFunction::TailList) function: Term::Builtin(DefaultFunction::TailList)
.force_wrap()
.force_wrap() .force_wrap()
.into(), .into(),
argument: prev_tail.into(), argument: prev_tail.into(),
@ -3891,7 +3882,7 @@ impl<'a> CodeGenerator<'a> {
arg_stack.push(term); arg_stack.push(term);
} else { } else {
let mut term = Term::Constant(UplcConstant::ProtoList(UplcType::Data, vec![])); let mut term = Term::Constant(UplcConstant::ProtoList(UplcType::Data, vec![]));
for (arg, tipo) in args.into_iter().zip(tuple_sub_types.into_iter()) { for (arg, tipo) in args.into_iter().zip(tuple_sub_types.into_iter()).rev() {
term = Term::Apply { term = Term::Apply {
function: Term::Apply { function: Term::Apply {
function: Term::Builtin(DefaultFunction::MkCons) function: Term::Builtin(DefaultFunction::MkCons)
@ -3936,6 +3927,7 @@ impl<'a> CodeGenerator<'a> {
} }
Air::TupleIndex { .. } => todo!(), Air::TupleIndex { .. } => todo!(),
Air::TupleAccessor { tipo, names, .. } => { Air::TupleAccessor { tipo, names, .. } => {
let inner_types = tipo.get_inner_types();
let value = arg_stack.pop().unwrap(); let value = arg_stack.pop().unwrap();
let mut term = arg_stack.pop().unwrap(); let mut term = arg_stack.pop().unwrap();
let list_id = self.id_gen.next(); let list_id = self.id_gen.next();
@ -3962,33 +3954,39 @@ impl<'a> CodeGenerator<'a> {
body: term.into(), body: term.into(),
} }
.into(), .into(),
argument: Term::Apply { argument: convert_data_to_type(
function: Term::Builtin(DefaultFunction::SndPair) Term::Apply {
.force_wrap() function: Term::Builtin(DefaultFunction::SndPair)
.force_wrap() .force_wrap()
.force_wrap()
.into(),
argument: Term::Var(Name {
text: format!("__tuple_{}", list_id),
unique: 0.into(),
})
.into(), .into(),
argument: Term::Var(Name { },
text: format!("__tuple_{}", list_id), &inner_types[1],
unique: 0.into(), )
})
.into(),
}
.into(), .into(),
} }
.into(), .into(),
} }
.into(), .into(),
argument: Term::Apply { argument: convert_data_to_type(
function: Term::Builtin(DefaultFunction::FstPair) Term::Apply {
.force_wrap() function: Term::Builtin(DefaultFunction::FstPair)
.force_wrap() .force_wrap()
.force_wrap()
.into(),
argument: Term::Var(Name {
text: format!("__tuple_{}", list_id),
unique: 0.into(),
})
.into(), .into(),
argument: Term::Var(Name { },
text: format!("__tuple_{}", list_id), &inner_types[0],
unique: 0.into(), )
})
.into(),
}
.into(), .into(),
} }
.into(), .into(),
@ -4105,31 +4103,104 @@ impl<'a> CodeGenerator<'a> {
Air::TupleClause { Air::TupleClause {
tipo, tipo,
indices, indices,
predefined_indices,
subject_name, subject_name,
complex_clause, complex_clause,
.. ..
} => { } => {
let term = arg_stack.pop().unwrap(); let mut term = arg_stack.pop().unwrap();
let tuple_types = tipo.get_inner_types(); let tuple_types = tipo.get_inner_types();
if tuple_types.len() == 2 { if tuple_types.len() == 2 {
for (index, name) in indices.iter() { for (index, name) in indices.iter() {
if *index == 0 { if *index == 0 {
// apply_wrap( term = apply_wrap(
// Term::Builtin(DefaultFunction::FstPair) Term::Lambda {
// .force_wrap() parameter_name: Name {
// .force_wrap(), text: name.clone(),
// Term::Var(Name { unique: 0.into(),
// text: subject_name.clone(), },
// unique: 0.into(), body: term.into(),
// }), },
// ) convert_data_to_type(
apply_wrap(
Term::Builtin(DefaultFunction::FstPair)
.force_wrap()
.force_wrap(),
Term::Var(Name {
text: subject_name.clone(),
unique: 0.into(),
}),
),
&tuple_types[*index].clone(),
),
);
} else {
term = apply_wrap(
Term::Lambda {
parameter_name: Name {
text: name.clone(),
unique: 0.into(),
},
body: term.into(),
},
convert_data_to_type(
apply_wrap(
Term::Builtin(DefaultFunction::SndPair)
.force_wrap()
.force_wrap(),
Term::Var(Name {
text: subject_name.clone(),
unique: 0.into(),
}),
),
&tuple_types[*index].clone(),
),
);
} }
} }
} else { } else {
for (index, name) in indices.iter() {
term = apply_wrap(
Term::Lambda {
parameter_name: Name {
text: name.clone(),
unique: 0.into(),
},
body: term.into(),
},
convert_data_to_type(
apply_wrap(
Term::Builtin(DefaultFunction::HeadList).force_wrap(),
repeat_tail_list(
Term::Var(Name {
text: subject_name.clone(),
unique: 0.into(),
}),
*index,
),
),
&tuple_types[*index].clone(),
),
);
}
} }
if complex_clause {
let next_clause = arg_stack.pop().unwrap();
term = apply_wrap(
Term::Lambda {
parameter_name: Name {
text: "__other_clauses_delayed".to_string(),
unique: 0.into(),
},
body: term.into(),
},
Term::Delay(next_clause.into()),
)
}
arg_stack.push(term);
} }
} }
} }

View File

@ -570,7 +570,6 @@ where
Ok(programs) Ok(programs)
} }
// TODO: revisit ownership and lifetimes of data in this function
fn collect_scripts( fn collect_scripts(
&mut self, &mut self,
verbose: bool, verbose: bool,
@ -595,12 +594,8 @@ where
let mut scripts = Vec::new(); let mut scripts = Vec::new();
for module in self for module in self.checked_modules.values() {
.checked_modules for def in module.ast.definitions() {
.values()
.filter(|checked| checked.package == self.config.name.to_string())
{
for (_index, def) in module.ast.definitions().enumerate() {
match def { match def {
Definition::Fn(func) => { Definition::Fn(func) => {
functions.insert( functions.insert(
@ -611,15 +606,15 @@ where
}, },
func, func,
); );
if should_collect(def) {
if should_collect(def) && module.package == self.config.name.to_string() {
scripts.push((module.input_path.clone(), module.name.clone(), func)); scripts.push((module.input_path.clone(), module.name.clone(), func));
} }
} }
Definition::Test(func) => { Definition::Test(func) => {
if should_collect(def) { if should_collect(def) && module.package == self.config.name.to_string() {
scripts.push((module.input_path.clone(), module.name.clone(), func)); scripts.push((module.input_path.clone(), module.name.clone(), func));
} }
// indices_to_remove.push(index);
} }
Definition::TypeAlias(ta) => { Definition::TypeAlias(ta) => {
type_aliases.insert((module.name.clone(), ta.alias.clone()), ta); type_aliases.insert((module.name.clone(), ta.alias.clone()), ta);
@ -673,10 +668,12 @@ where
.generate(*left_src, vec![], false) .generate(*left_src, vec![], false)
.try_into() .try_into()
.unwrap(); .unwrap();
let right = CodeGenerator::new(&functions, &data_types, &self.module_types) let right = CodeGenerator::new(&functions, &data_types, &self.module_types)
.generate(*right_src, vec![], false) .generate(*right_src, vec![], false)
.try_into() .try_into()
.unwrap(); .unwrap();
Some(EvalHint { Some(EvalHint {
bin_op, bin_op,
left, left,