refactor term::apply to apply_wrap. Fixed a list eq binop

This commit is contained in:
Kasey White 2023-01-08 13:35:37 -05:00 committed by Lucas
parent d649b34ec3
commit ea135e6f42
3 changed files with 761 additions and 1064 deletions

View File

@ -230,8 +230,8 @@ pub enum Air {
RecordUpdate { RecordUpdate {
scope: Vec<u64>, scope: Vec<u64>,
tipo: Arc<Type>, highest_index: usize,
count: usize, indices: Vec<(usize, Arc<Type>)>,
}, },
UnOp { UnOp {

View File

@ -7,7 +7,10 @@ use std::{
use indexmap::IndexMap; use indexmap::IndexMap;
use itertools::Itertools; use itertools::Itertools;
use uplc::{ use uplc::{
ast::{builder::apply_wrap, Constant as UplcConstant, Name, Term, Type as UplcType}, ast::{
builder::{apply_wrap, if_else},
Constant as UplcConstant, Name, Term, Type as UplcType,
},
builtins::DefaultFunction, builtins::DefaultFunction,
machine::runtime::convert_constr_to_tag, machine::runtime::convert_constr_to_tag,
BigInt, Constr, KeyValuePairs, PlutusData, BigInt, Constr, KeyValuePairs, PlutusData,
@ -162,129 +165,75 @@ impl ClauseProperties {
pub fn convert_type_to_data(term: Term<Name>, field_type: &Arc<Type>) -> Term<Name> { pub fn convert_type_to_data(term: Term<Name>, field_type: &Arc<Type>) -> Term<Name> {
if field_type.is_bytearray() { if field_type.is_bytearray() {
Term::Apply { apply_wrap(DefaultFunction::BData.into(), term)
function: DefaultFunction::BData.into(),
argument: term.into(),
}
} else if field_type.is_int() { } else if field_type.is_int() {
Term::Apply { apply_wrap(DefaultFunction::IData.into(), term)
function: DefaultFunction::IData.into(),
argument: term.into(),
}
} else if field_type.is_map() { } else if field_type.is_map() {
Term::Apply { apply_wrap(DefaultFunction::MapData.into(), term)
function: DefaultFunction::MapData.into(),
argument: term.into(),
}
} else if field_type.is_list() {
Term::Apply {
function: DefaultFunction::ListData.into(),
argument: term.into(),
}
} else if field_type.is_string() { } else if field_type.is_string() {
Term::Apply { apply_wrap(
function: DefaultFunction::BData.into(), DefaultFunction::BData.into(),
argument: Term::Apply { apply_wrap(DefaultFunction::EncodeUtf8.into(), term),
function: DefaultFunction::EncodeUtf8.into(), )
argument: term.into(), } else if field_type.is_tuple() && matches!(field_type.get_uplc_type(), UplcType::Pair(_, _)) {
} apply_wrap(
.into(), Term::Lambda {
}
} else if field_type.is_tuple() {
match field_type.get_uplc_type() {
UplcType::List(_) => Term::Apply {
function: DefaultFunction::ListData.into(),
argument: term.into(),
},
UplcType::Pair(_, _) => Term::Apply {
function: Term::Lambda {
parameter_name: Name { parameter_name: Name {
text: "__pair".to_string(), text: "__pair".to_string(),
unique: 0.into(), unique: 0.into(),
}, },
body: Term::Apply { body: apply_wrap(
function: DefaultFunction::ListData.into(), DefaultFunction::ListData.into(),
argument: Term::Apply { apply_wrap(
function: Term::Apply { apply_wrap(
function: Term::Builtin(DefaultFunction::MkCons) Term::Builtin(DefaultFunction::MkCons).force_wrap(),
apply_wrap(
Term::Builtin(DefaultFunction::FstPair)
.force_wrap() .force_wrap()
.into(), .force_wrap(),
argument: Term::Apply { Term::Var(Name {
function: Term::Builtin(DefaultFunction::FstPair)
.force_wrap()
.force_wrap()
.into(),
argument: Term::Var(Name {
text: "__pair".to_string(), text: "__pair".to_string(),
unique: 0.into(), unique: 0.into(),
}) }),
.into(), ),
} ),
.into(), apply_wrap(
} apply_wrap(
.into(), Term::Builtin(DefaultFunction::MkCons).force_wrap(),
apply_wrap(
argument: Term::Apply { Term::Builtin(DefaultFunction::SndPair)
function: Term::Apply {
function: Term::Builtin(DefaultFunction::MkCons)
.force_wrap() .force_wrap()
.into(), .force_wrap(),
argument: Term::Apply { Term::Var(Name {
function: Term::Builtin(DefaultFunction::SndPair)
.force_wrap()
.force_wrap()
.into(),
argument: Term::Var(Name {
text: "__pair".to_string(), text: "__pair".to_string(),
unique: 0.into(), unique: 0.into(),
}) }),
),
),
Term::Constant(UplcConstant::ProtoList(UplcType::Data, vec![])),
),
),
)
.into(), .into(),
}
.into(),
}
.into(),
argument: Term::Constant(UplcConstant::ProtoList(
UplcType::Data,
vec![],
))
.into(),
}
.into(),
}
.into(),
}
.into(),
}
.into(),
argument: term.into(),
}, },
_ => unreachable!(), term,
} )
} else if field_type.is_list() || field_type.is_tuple() {
apply_wrap(DefaultFunction::ListData.into(), term)
} else if field_type.is_bool() { } else if field_type.is_bool() {
Term::Apply { if_else(
function: Term::Apply { term,
function: Term::Apply { Term::Constant(UplcConstant::Data(PlutusData::Constr(Constr {
function: Term::Builtin(DefaultFunction::IfThenElse)
.force_wrap()
.into(),
argument: term.into(),
}
.into(),
argument: Term::Constant(UplcConstant::Data(PlutusData::Constr(Constr {
tag: convert_constr_to_tag(1), tag: convert_constr_to_tag(1),
any_constructor: None, any_constructor: None,
fields: vec![], fields: vec![],
}))) }))),
.into(), Term::Constant(UplcConstant::Data(PlutusData::Constr(Constr {
}
.into(),
argument: Term::Constant(UplcConstant::Data(PlutusData::Constr(Constr {
tag: convert_constr_to_tag(0), tag: convert_constr_to_tag(0),
any_constructor: None, any_constructor: None,
fields: vec![], fields: vec![],
}))) }))),
.into(), )
}
} else { } else {
term term
} }
@ -292,124 +241,77 @@ pub fn convert_type_to_data(term: Term<Name>, field_type: &Arc<Type>) -> Term<Na
pub fn convert_data_to_type(term: Term<Name>, field_type: &Arc<Type>) -> Term<Name> { pub fn convert_data_to_type(term: Term<Name>, field_type: &Arc<Type>) -> Term<Name> {
if field_type.is_int() { if field_type.is_int() {
Term::Apply { apply_wrap(DefaultFunction::UnIData.into(), term)
function: DefaultFunction::UnIData.into(),
argument: term.into(),
}
} else if field_type.is_bytearray() { } else if field_type.is_bytearray() {
Term::Apply { apply_wrap(DefaultFunction::UnBData.into(), term)
function: DefaultFunction::UnBData.into(),
argument: term.into(),
}
} else if field_type.is_map() { } else if field_type.is_map() {
Term::Apply { apply_wrap(DefaultFunction::UnMapData.into(), term)
function: DefaultFunction::UnMapData.into(),
argument: term.into(),
}
} else if field_type.is_list() {
Term::Apply {
function: DefaultFunction::UnListData.into(),
argument: term.into(),
}
} else if field_type.is_string() { } else if field_type.is_string() {
Term::Apply { apply_wrap(
function: DefaultFunction::DecodeUtf8.into(), DefaultFunction::DecodeUtf8.into(),
argument: Term::Apply { apply_wrap(DefaultFunction::UnBData.into(), term),
function: DefaultFunction::UnBData.into(), )
argument: term.into(), } else if field_type.is_tuple() && matches!(field_type.get_uplc_type(), UplcType::Pair(_, _)) {
} apply_wrap(
.into(), Term::Lambda {
}
} else if field_type.is_tuple() {
match field_type.get_uplc_type() {
UplcType::List(_) => Term::Apply {
function: DefaultFunction::UnListData.into(),
argument: term.into(),
},
UplcType::Pair(_, _) => Term::Apply {
function: Term::Lambda {
parameter_name: Name { parameter_name: Name {
text: "__list_data".to_string(), text: "__list_data".to_string(),
unique: 0.into(), unique: 0.into(),
}, },
body: Term::Apply { body: apply_wrap(
function: Term::Lambda { Term::Lambda {
parameter_name: Name { parameter_name: Name {
text: "__tail".to_string(), text: "__tail".to_string(),
unique: 0.into(), unique: 0.into(),
}, },
body: Term::Apply { body: apply_wrap(
function: Term::Apply { apply_wrap(
function: Term::Builtin(DefaultFunction::MkPairData).into(), Term::Builtin(DefaultFunction::MkPairData),
argument: Term::Apply { apply_wrap(
function: Term::Builtin(DefaultFunction::HeadList) Term::Builtin(DefaultFunction::HeadList).force_wrap(),
.force_wrap() Term::Var(Name {
.into(),
argument: Term::Var(Name {
text: "__list_data".to_string(), text: "__list_data".to_string(),
unique: 0.into(), unique: 0.into(),
}) }),
.into(), ),
} ),
.into(), apply_wrap(
} Term::Builtin(DefaultFunction::HeadList).force_wrap(),
.into(), Term::Var(Name {
argument: Term::Apply {
function: Term::Builtin(DefaultFunction::HeadList)
.force_wrap()
.into(),
argument: Term::Var(Name {
text: "__tail".to_string(), text: "__tail".to_string(),
unique: 0.into(), unique: 0.into(),
}) }),
.into(), ),
} )
.into(),
}
.into(),
}
.into(),
argument: Term::Apply {
function: Term::Builtin(DefaultFunction::TailList).force_wrap().into(),
argument: Term::Var(Name {
text: "__list_data".to_string(),
unique: 0.into(),
})
.into(),
}
.into(),
}
.into(),
}
.into(),
argument: Term::Apply {
function: Term::Builtin(DefaultFunction::UnListData).into(),
argument: term.into(),
}
.into(), .into(),
}, },
_ => unreachable!(), apply_wrap(
} Term::Builtin(DefaultFunction::TailList).force_wrap(),
Term::Var(Name {
text: "__list_data".to_string(),
unique: 0.into(),
}),
),
)
.into(),
},
apply_wrap(Term::Builtin(DefaultFunction::UnListData), term),
)
} else if field_type.is_list() || field_type.is_tuple() {
apply_wrap(DefaultFunction::UnListData.into(), term)
} else if field_type.is_bool() { } else if field_type.is_bool() {
Term::Apply { apply_wrap(
function: Term::Apply { apply_wrap(
function: Term::Builtin(DefaultFunction::EqualsInteger).into(), DefaultFunction::EqualsInteger.into(),
argument: Term::Constant(UplcConstant::Integer(1)).into(), Term::Constant(UplcConstant::Integer(1)),
} ),
.into(), apply_wrap(
argument: Term::Apply { Term::Builtin(DefaultFunction::FstPair)
function: Term::Builtin(DefaultFunction::FstPair)
.force_wrap() .force_wrap()
.force_wrap() .force_wrap(),
.into(), apply_wrap(DefaultFunction::UnConstrData.into(), term),
argument: Term::Apply { ),
function: Term::Builtin(DefaultFunction::UnConstrData).into(), )
argument: term.into(),
}
.into(),
}
.into(),
}
} else { } else {
term term
} }
@ -582,24 +484,22 @@ pub fn list_access_to_uplc(
let (first, names) = names.split_first().unwrap(); let (first, names) = names.split_first().unwrap();
let head_list = if tipo.is_map() { let head_list = if tipo.is_map() {
Term::Apply { apply_wrap(
function: Term::Force(Term::Builtin(DefaultFunction::HeadList).into()).into(), Term::Builtin(DefaultFunction::HeadList).force_wrap(),
argument: Term::Var(Name { Term::Var(Name {
text: format!("tail_index_{}_{}", current_index, id_list[current_index]), text: format!("tail_index_{}_{}", current_index, id_list[current_index]),
unique: 0.into(), unique: 0.into(),
}) }),
.into(), )
}
} else { } else {
convert_data_to_type( convert_data_to_type(
Term::Apply { apply_wrap(
function: Term::Force(Term::Builtin(DefaultFunction::HeadList).into()).into(), Term::Builtin(DefaultFunction::HeadList).force_wrap(),
argument: Term::Var(Name { Term::Var(Name {
text: format!("tail_index_{}_{}", current_index, id_list[current_index]), text: format!("tail_index_{}_{}", current_index, id_list[current_index]),
unique: 0.into(), unique: 0.into(),
}) }),
.into(), ),
},
&tipo.clone().get_inner_types()[0], &tipo.clone().get_inner_types()[0],
) )
}; };
@ -610,39 +510,35 @@ pub fn list_access_to_uplc(
text: format!("tail_index_{}_{}", current_index, id_list[current_index]), text: format!("tail_index_{}_{}", current_index, id_list[current_index]),
unique: 0.into(), unique: 0.into(),
}, },
body: Term::Apply { body: apply_wrap(
function: Term::Lambda { Term::Lambda {
parameter_name: Name { parameter_name: Name {
text: first.clone(), text: first.clone(),
unique: 0.into(), unique: 0.into(),
}, },
body: Term::Apply { body: apply_wrap(
function: Term::Lambda { Term::Lambda {
parameter_name: Name { parameter_name: Name {
text: names[0].clone(), text: names[0].clone(),
unique: 0.into(), unique: 0.into(),
}, },
body: term.into(), body: term.into(),
} },
.into(), apply_wrap(
argument: Term::Apply { Term::Builtin(DefaultFunction::TailList).force_wrap(),
function: Term::Builtin(DefaultFunction::TailList).force_wrap().into(), Term::Var(Name {
argument: Term::Var(Name {
text: format!( text: format!(
"tail_index_{}_{}", "tail_index_{}_{}",
current_index, id_list[current_index] current_index, id_list[current_index]
), ),
unique: 0.into(), unique: 0.into(),
}) }),
),
)
.into(), .into(),
} },
.into(), head_list,
} )
.into(),
}
.into(),
argument: head_list.into(),
}
.into(), .into(),
} }
} else if names.is_empty() { } else if names.is_empty() {
@ -651,25 +547,22 @@ pub fn list_access_to_uplc(
text: format!("tail_index_{}_{}", current_index, id_list[current_index]), text: format!("tail_index_{}_{}", current_index, id_list[current_index]),
unique: 0.into(), unique: 0.into(),
}, },
body: Term::Apply { body: apply_wrap(
function: Term::Lambda { Term::Lambda {
parameter_name: Name { parameter_name: Name {
text: first.clone(), text: first.clone(),
unique: 0.into(), unique: 0.into(),
}, },
body: term.into(), body: term.into(),
} },
.into(), apply_wrap(
argument: Term::Apply { Term::Builtin(DefaultFunction::HeadList).force_wrap(),
function: Term::Force(Term::Builtin(DefaultFunction::HeadList).into()).into(), Term::Var(Name {
argument: Term::Var(Name {
text: format!("tail_index_{}_{}", current_index, id_list[current_index]), text: format!("tail_index_{}_{}", current_index, id_list[current_index]),
unique: 0.into(), unique: 0.into(),
}) }),
.into(), ),
} )
.into(),
}
.into(), .into(),
} }
} else { } else {
@ -678,40 +571,29 @@ pub fn list_access_to_uplc(
text: format!("tail_index_{}_{}", current_index, id_list[current_index]), text: format!("tail_index_{}_{}", current_index, id_list[current_index]),
unique: 0.into(), unique: 0.into(),
}, },
body: Term::Apply { body: apply_wrap(
function: Term::Lambda { Term::Lambda {
parameter_name: Name { parameter_name: Name {
text: first.clone(), text: first.clone(),
unique: 0.into(), unique: 0.into(),
}, },
body: Term::Apply { body: apply_wrap(
function: list_access_to_uplc( list_access_to_uplc(names, id_list, tail, current_index + 1, term, tipo),
names, apply_wrap(
id_list, Term::Builtin(DefaultFunction::TailList).force_wrap(),
tail, Term::Var(Name {
current_index + 1,
term,
tipo,
)
.into(),
argument: Term::Apply {
function: Term::Builtin(DefaultFunction::TailList).force_wrap().into(),
argument: Term::Var(Name {
text: format!( text: format!(
"tail_index_{}_{}", "tail_index_{}_{}",
current_index, id_list[current_index] current_index, id_list[current_index]
), ),
unique: 0.into(), unique: 0.into(),
}) }),
),
)
.into(), .into(),
} },
.into(), head_list,
} )
.into(),
}
.into(),
argument: head_list.into(),
}
.into(), .into(),
} }
} }
@ -1393,15 +1275,28 @@ pub fn monomorphize(
needs_variant = true; needs_variant = true;
} }
} }
Air::RecordUpdate { scope, tipo, count } => { Air::RecordUpdate {
scope,
highest_index,
indices,
} => {
let mut new_indices = vec![];
for (ind, tipo) in indices {
if tipo.is_generic() { if tipo.is_generic() {
let mut tipo = tipo.clone(); let mut tipo = tipo.clone();
find_generics_to_replace(&mut tipo, &generic_types); find_generics_to_replace(&mut tipo, &generic_types);
new_air[index] = Air::RecordUpdate { scope, tipo, count };
needs_variant = true; needs_variant = true;
new_indices.push((ind, tipo));
} else {
new_indices.push((ind, tipo));
} }
} }
new_air[index] = Air::RecordUpdate {
scope,
highest_index,
indices: new_indices,
};
}
Air::TupleAccessor { scope, names, tipo } => { Air::TupleAccessor { scope, names, tipo } => {
if tipo.is_generic() { if tipo.is_generic() {
let mut tipo = tipo.clone(); let mut tipo = tipo.clone();

File diff suppressed because it is too large Load Diff