feat: Do a major overhaul on how we check types to allow for match patterns instead of if statements

Also fix one more test
This commit is contained in:
microproofs 2024-03-30 13:35:42 -04:00 committed by Kasey
parent 3c332ca42a
commit 75b076552c
4 changed files with 467 additions and 475 deletions

View File

@ -1516,6 +1516,7 @@ impl<'a> CodeGenerator<'a> {
let uplc_type = tipo.get_uplc_type();
match uplc_type {
// primitives
UplcType::Integer
| UplcType::String
| UplcType::Bool
@ -4618,111 +4619,73 @@ impl<'a> CodeGenerator<'a> {
let left = arg_stack.pop().unwrap();
let right = arg_stack.pop().unwrap();
let builtin = if tipo.is_int() {
Term::equals_integer()
} else if tipo.is_string() {
Term::equals_string()
} else if tipo.is_bytearray() {
Term::equals_bytestring()
} else if tipo.is_bls381_12_g1() {
Term::bls12_381_g1_equal()
} else if tipo.is_bls381_12_g2() {
Term::bls12_381_g2_equal()
} else if tipo.is_ml_result() {
panic!("ML Result equality is not supported")
} else {
Term::equals_data()
};
let uplc_type = tipo.get_uplc_type();
let term =
match name {
let term = match name {
BinOp::And => left.delayed_if_then_else(right, Term::bool(false)),
BinOp::Or => left.delayed_if_then_else(Term::bool(true), right),
BinOp::Eq => {
if tipo.is_bool() {
let term = left.delayed_if_then_else(
BinOp::Eq | BinOp::NotEq => {
let builtin = match &uplc_type {
UplcType::Integer => Term::equals_integer(),
UplcType::String => Term::equals_string(),
UplcType::ByteString => Term::equals_bytestring(),
UplcType::Bls12_381G1Element => Term::bls12_381_g1_equal(),
UplcType::Bls12_381G2Element => Term::bls12_381_g2_equal(),
UplcType::Bool | UplcType::Unit => Term::unit(),
UplcType::List(_) | UplcType::Pair(_, _) | UplcType::Data => {
Term::equals_data()
}
UplcType::Bls12_381MlResult => {
panic!("ML Result equality is not supported")
}
};
let binop_eq = match uplc_type {
UplcType::Bool => {
if matches!(name, BinOp::Eq) {
left.delayed_if_then_else(
right.clone(),
right.if_then_else(Term::bool(false), Term::bool(true)),
);
return Some(term);
}
if tipo.is_map() {
let term = builtin
.apply(Term::map_data().apply(left))
.apply(Term::map_data().apply(right));
return Some(term);
}
if tipo.is_pair() {
let term = builtin
.apply(Term::map_data().apply(
Term::mk_cons().apply(left).apply(Term::empty_map()),
))
.apply(Term::map_data().apply(
Term::mk_cons().apply(right).apply(Term::empty_map()),
));
return Some(term);
}
if tipo.is_list() || tipo.is_tuple() {
let term = builtin
.apply(Term::list_data().apply(left))
.apply(Term::list_data().apply(right));
return Some(term);
}
if tipo.is_void() {
let term = left.choose_unit(right.choose_unit(Term::bool(true)));
return Some(term);
}
builtin.apply(left).apply(right)
}
BinOp::NotEq => {
if tipo.is_bool() {
let term = left.delayed_if_then_else(
)
} else {
left.delayed_if_then_else(
right
.clone()
.if_then_else(Term::bool(false), Term::bool(true)),
right,
);
return Some(term);
)
}
if tipo.is_map() {
let term = builtin
}
UplcType::List(_) if tipo.is_map() => builtin
.apply(Term::map_data().apply(left))
.apply(Term::map_data().apply(right))
.if_then_else(Term::bool(false), Term::bool(true));
return Some(term);
}
if tipo.is_pair() {
let term = builtin
.apply(Term::map_data().apply(right)),
UplcType::List(_) => builtin
.apply(Term::list_data().apply(left))
.apply(Term::list_data().apply(right)),
UplcType::Pair(_, _) => {
builtin
.apply(Term::map_data().apply(
Term::mk_cons().apply(left).apply(Term::empty_map()),
))
.apply(Term::map_data().apply(
Term::mk_cons().apply(right).apply(Term::empty_map()),
))
.if_then_else(Term::bool(false), Term::bool(true));
return Some(term);
}
if tipo.is_list() || tipo.is_tuple() {
let term = builtin
.apply(Term::list_data().apply(left))
.apply(Term::list_data().apply(right))
.if_then_else(Term::bool(false), Term::bool(true));
return Some(term);
}
if tipo.is_void() {
return Some(Term::bool(false));
}
UplcType::Data
| UplcType::Bls12_381G1Element
| UplcType::Bls12_381G2Element
| UplcType::Bls12_381MlResult
| UplcType::Integer
| UplcType::String
| UplcType::ByteString => builtin.apply(left).apply(right),
UplcType::Unit => left.choose_unit(right.choose_unit(Term::bool(true))),
};
builtin
.apply(left)
.apply(right)
.if_then_else(Term::bool(false), Term::bool(true))
if !tipo.is_bool() && matches!(name, BinOp::NotEq) {
binop_eq.if_then_else(Term::bool(false), Term::bool(true))
} else {
binop_eq
}
}
BinOp::LtInt => Term::Builtin(DefaultFunction::LessThanInteger)
.apply(left)
@ -4973,25 +4936,25 @@ impl<'a> CodeGenerator<'a> {
} => {
let subject = arg_stack.pop().unwrap();
let subject = if tipo.is_int()
|| tipo.is_bytearray()
|| tipo.is_string()
|| tipo.is_list()
|| tipo.is_tuple()
|| tipo.is_pair()
|| tipo.is_bool()
|| tipo.is_bls381_12_g1()
|| tipo.is_bls381_12_g2()
{
subject
} else if tipo.is_ml_result() {
unreachable!()
} else {
Term::var(
let uplc_type = tipo.get_uplc_type();
let subject = match uplc_type {
UplcType::Bool
| UplcType::Integer
| UplcType::String
| UplcType::ByteString
| UplcType::Unit
| UplcType::List(_)
| UplcType::Pair(_, _)
| UplcType::Bls12_381G1Element
| UplcType::Bls12_381G2Element
| UplcType::Bls12_381MlResult => subject,
UplcType::Data if tipo.is_data() => subject,
UplcType::Data => Term::var(
self.special_functions
.use_function_uplc(CONSTR_INDEX_EXPOSER.to_string()),
)
.apply(subject)
.apply(subject),
};
let mut term = arg_stack.pop().unwrap();
@ -5009,68 +4972,67 @@ impl<'a> CodeGenerator<'a> {
let clause = arg_stack.pop().unwrap();
// the body to be run if the clause matches
let mut body = arg_stack.pop().unwrap();
let body = arg_stack.pop().unwrap();
// the next branch in the when expression
let mut term = arg_stack.pop().unwrap();
let term = arg_stack.pop().unwrap();
if tipo.is_bool() {
let other_clauses = if complex_clause {
Term::var("__other_clauses_delayed")
} else {
term.clone().delay()
};
let body = if tipo.is_bool() {
if matches!(clause, Term::Constant(boolean) if matches!(boolean.as_ref(), UplcConstant::Bool(true)))
{
body = Term::var(subject_name)
Term::var(subject_name)
.if_then_else(body.delay(), other_clauses)
.force();
.force()
} else {
body = Term::var(subject_name)
Term::var(subject_name)
.if_then_else(other_clauses, body.delay())
.force();
.force()
}
} else {
let uplc_type = tipo.get_uplc_type();
if complex_clause {
term = body.lambda("__other_clauses_delayed").apply(term.delay());
} else {
term = body;
}
} else {
let condition = if tipo.is_int() {
Term::equals_integer()
let condition = match uplc_type {
UplcType::Bool
| UplcType::Unit
| UplcType::List(_)
| UplcType::Pair(_, _)
| UplcType::Bls12_381MlResult => unreachable!("{:#?}", tipo),
UplcType::Integer => Term::equals_integer()
.apply(clause)
.apply(Term::var(subject_name))
} else if tipo.is_bytearray() {
Term::equals_bytestring()
.apply(Term::var(subject_name)),
UplcType::String => Term::equals_string()
.apply(clause)
.apply(Term::var(subject_name))
} else if tipo.is_string() {
Term::equals_string()
.apply(Term::var(subject_name)),
UplcType::ByteString => Term::equals_bytestring()
.apply(clause)
.apply(Term::var(subject_name))
} else if tipo.is_list() || tipo.is_tuple() || tipo.is_pair() {
unreachable!("{:#?}", tipo)
} else {
Term::equals_integer()
.apply(Term::var(subject_name)),
UplcType::Data if tipo.is_data() => unimplemented!(),
UplcType::Data => Term::equals_integer()
.apply(clause)
.apply(Term::var(subject_name))
.apply(Term::var(subject_name)),
UplcType::Bls12_381G1Element => Term::bls12_381_g1_equal()
.apply(clause)
.apply(Term::var(subject_name)),
UplcType::Bls12_381G2Element => Term::bls12_381_g2_equal()
.apply(clause)
.apply(Term::var(subject_name)),
};
condition.if_then_else(body.delay(), other_clauses).force()
};
if complex_clause {
term = condition
.if_then_else(body.delay(), Term::var("__other_clauses_delayed"))
.force()
.lambda("__other_clauses_delayed")
.apply(term.delay());
Some(body.lambda("__other_clauses_delayed").apply(term.delay()))
} else {
term = condition.delayed_if_then_else(body, term);
Some(body)
}
}
Some(term)
}
Air::ListClause {
tail_name,
next_tail_name,
@ -5181,50 +5143,61 @@ impl<'a> CodeGenerator<'a> {
let then = arg_stack.pop().unwrap();
let term = Term::var("__other_clauses_delayed");
if tipo.is_bool() {
let mut term = Term::var("__other_clauses_delayed");
if matches!(checker, Term::Constant(boolean) if matches!(boolean.as_ref(), UplcConstant::Bool(true)))
{
term = Term::var(subject_name)
Some(
Term::var(subject_name)
.if_then_else(then.delay(), term)
.force();
.force(),
)
} else {
term = Term::var(subject_name)
Some(
Term::var(subject_name)
.if_then_else(term, then.delay())
.force();
.force(),
)
}
Some(term)
} else if tipo.is_void() {
Some(then.lambda("_").apply(Term::var(subject_name)))
} else {
let condition = if tipo.is_int() {
Term::equals_integer()
let uplc_type = tipo.get_uplc_type();
let condition = match uplc_type {
UplcType::Bool
| UplcType::Unit
| UplcType::List(_)
| UplcType::Pair(_, _)
| UplcType::Bls12_381MlResult => unreachable!("{:#?}", tipo),
UplcType::Integer => Term::equals_integer()
.apply(checker)
.apply(Term::var(subject_name))
} else if tipo.is_bytearray() {
Term::equals_bytestring()
.apply(Term::var(subject_name)),
UplcType::String => Term::equals_string()
.apply(checker)
.apply(Term::var(subject_name))
} else if tipo.is_string() {
Term::equals_string()
.apply(Term::var(subject_name)),
UplcType::ByteString => Term::equals_bytestring()
.apply(checker)
.apply(Term::var(subject_name))
} else if tipo.is_list() || tipo.is_tuple() {
unreachable!()
} else {
Term::equals_integer().apply(checker).apply(
.apply(Term::var(subject_name)),
UplcType::Data if tipo.is_data() => unimplemented!(),
UplcType::Data => Term::equals_integer().apply(checker).apply(
Term::var(
self.special_functions
.use_function_uplc(CONSTR_INDEX_EXPOSER.to_string()),
)
.apply(Term::var(subject_name)),
)
),
UplcType::Bls12_381G1Element => Term::bls12_381_g1_equal()
.apply(checker)
.apply(Term::var(subject_name)),
UplcType::Bls12_381G2Element => Term::bls12_381_g2_equal()
.apply(checker)
.apply(Term::var(subject_name)),
};
let term = condition
.if_then_else(then.delay(), Term::var("__other_clauses_delayed"))
.force();
Some(term)
Some(condition.if_then_else(then.delay(), term).force())
}
}
Air::ListClauseGuard {

View File

@ -359,38 +359,25 @@ pub fn handle_clause_guard(clause_guard: &TypedClauseGuard) -> AirTree {
}
pub fn get_generic_variant_name(t: &Rc<Type>) -> String {
if t.is_string() {
"_string".to_string()
} else if t.is_int() {
"_int".to_string()
} else if t.is_bool() {
"_bool".to_string()
} else if t.is_bytearray() {
"_bytearray".to_string()
} else if t.is_bls381_12_g1() {
"_bls381_12_g1".to_string()
} else if t.is_bls381_12_g2() {
"_bls381_12_g2".to_string()
} else if t.is_ml_result() {
"_ml_result".to_string()
} else if t.is_map() {
"_map".to_string()
} else if t.is_pair() {
"_pair".to_string()
} else if t.is_list() {
"_list".to_string()
} else if t.is_tuple() {
"_tuple".to_string()
} else if t.is_unbound() {
"_unbound".to_string()
} else {
let full_type = "_data".to_string();
let uplc_type = t.get_uplc_type();
if t.is_generic() {
panic!("FOUND A POLYMORPHIC TYPE. EXPECTED MONOMORPHIC TYPE");
match uplc_type {
UplcType::Bool => "_bool".to_string(),
UplcType::Integer => "_int".to_string(),
UplcType::String => "_string".to_string(),
UplcType::ByteString => "_bytearray".to_string(),
UplcType::Unit => "_void".to_string(),
UplcType::List(_) if t.is_map() => "_map".to_string(),
UplcType::List(_) => "_list".to_string(),
UplcType::Pair(_, _) => "_pair".to_string(),
UplcType::Bls12_381G1Element => "_bls381_12_g1".to_string(),
UplcType::Bls12_381G2Element => "_bls381_12_g2".to_string(),
UplcType::Bls12_381MlResult => "_ml_result".to_string(),
UplcType::Data if t.is_unbound() => "_unbound".to_string(),
UplcType::Data if t.is_generic() => {
unreachable!("FOUND A POLYMORPHIC TYPE. EXPECTED MONOMORPHIC TYPE")
}
full_type
UplcType::Data => "_data".to_string(),
}
}
@ -958,62 +945,54 @@ pub fn find_list_clause_or_default_first(clauses: &[TypedClause]) -> &TypedClaus
}
pub fn known_data_to_type(term: Term<Name>, field_type: &Type) -> Term<Name> {
if field_type.is_int() {
Term::un_i_data().apply(term)
} else if field_type.is_bytearray() {
Term::un_b_data().apply(term)
} else if field_type.is_void() {
Term::unit().lambda("_").apply(term)
} else if field_type.is_map() {
Term::unmap_data().apply(term)
} else if field_type.is_string() {
Term::Builtin(DefaultFunction::DecodeUtf8).apply(Term::un_b_data().apply(term))
} else if field_type.is_pair() {
Term::mk_pair_data()
let uplc_type = field_type.get_uplc_type();
match uplc_type {
UplcType::Integer => Term::un_i_data().apply(term),
UplcType::ByteString => Term::un_b_data().apply(term),
UplcType::Bool => Term::less_than_integer()
.apply(Term::integer(0.into()))
.apply(Term::fst_pair().apply(Term::unconstr_data().apply(term))),
UplcType::String => Term::decode_utf8().apply(Term::un_b_data().apply(term)),
UplcType::Unit => Term::unit().lambda("_").apply(term),
UplcType::List(_) if field_type.is_map() => Term::unmap_data().apply(term),
UplcType::List(_) => Term::unlist_data().apply(term),
UplcType::Pair(_, _) => Term::mk_pair_data()
.apply(Term::head_list().apply(Term::var("__list_data")))
.apply(Term::head_list().apply(Term::tail_list().apply(Term::var("__list_data"))))
.lambda("__list_data")
.apply(Term::unlist_data().apply(term))
} else if field_type.is_list() || field_type.is_tuple() {
Term::unlist_data().apply(term)
} else if field_type.is_bool() {
Term::less_than_integer()
.apply(Term::integer(0.into()))
.apply(Term::fst_pair().apply(Term::unconstr_data().apply(term)))
} else if field_type.is_bls381_12_g1() {
.apply(Term::unlist_data().apply(term)),
UplcType::Data if field_type.is_data() => term,
UplcType::Data => term,
UplcType::Bls12_381G1Element => {
Term::bls12_381_g1_uncompress().apply(Term::un_b_data().apply(term))
} else if field_type.is_bls381_12_g2() {
}
UplcType::Bls12_381G2Element => {
Term::bls12_381_g2_uncompress().apply(Term::un_b_data().apply(term))
} else if field_type.is_ml_result() {
panic!("ML Result not supported")
} else {
term
}
UplcType::Bls12_381MlResult => panic!("ML Result not supported"),
}
}
pub fn unknown_data_to_type(term: Term<Name>, field_type: &Type) -> Term<Name> {
if field_type.is_int() {
Term::un_i_data().apply(term)
} else if field_type.is_bytearray() {
Term::un_b_data().apply(term)
} else if field_type.is_void() {
Term::equals_integer()
.apply(Term::integer(0.into()))
.apply(Term::fst_pair().apply(Term::var("__pair__")))
.delayed_if_then_else(
Term::snd_pair()
.apply(Term::var("__pair__"))
.delayed_choose_list(Term::unit(), Term::Error),
Term::Error,
)
.lambda("__pair__")
.apply(Term::unconstr_data().apply(term))
} else if field_type.is_map() {
Term::unmap_data().apply(term)
} else if field_type.is_string() {
Term::Builtin(DefaultFunction::DecodeUtf8).apply(Term::un_b_data().apply(term))
} else if field_type.is_pair() {
Term::tail_list()
let uplc_type = field_type.get_uplc_type();
match uplc_type {
UplcType::Integer => Term::un_i_data().apply(term),
UplcType::ByteString => Term::un_b_data().apply(term),
UplcType::String => Term::decode_utf8().apply(Term::un_b_data().apply(term)),
UplcType::List(_) if field_type.is_map() => Term::unmap_data().apply(term),
UplcType::List(_) => Term::unlist_data().apply(term),
UplcType::Data if field_type.is_data() => term,
UplcType::Data => term,
UplcType::Bls12_381G1Element => {
Term::bls12_381_g1_uncompress().apply(Term::un_b_data().apply(term))
}
UplcType::Bls12_381G2Element => {
Term::bls12_381_g2_uncompress().apply(Term::un_b_data().apply(term))
}
UplcType::Bls12_381MlResult => panic!("ML Result not supported"),
UplcType::Pair(_, _) => Term::tail_list()
.apply(Term::tail_list().apply(Term::var("__list_data")))
.delayed_choose_list(
Term::mk_pair_data()
@ -1024,11 +1003,8 @@ pub fn unknown_data_to_type(term: Term<Name>, field_type: &Type) -> Term<Name> {
Term::Error,
)
.lambda("__list_data")
.apply(Term::unlist_data().apply(term))
} else if field_type.is_list() || field_type.is_tuple() {
Term::unlist_data().apply(term)
} else if field_type.is_bool() {
Term::snd_pair()
.apply(Term::unlist_data().apply(term)),
UplcType::Bool => Term::snd_pair()
.apply(Term::var("__pair__"))
.delayed_choose_list(
Term::equals_integer()
@ -1044,25 +1020,33 @@ pub fn unknown_data_to_type(term: Term<Name>, field_type: &Type) -> Term<Name> {
Term::Error,
)
.lambda("__pair__")
.apply(Term::unconstr_data().apply(term))
} else if field_type.is_bls381_12_g1() {
Term::bls12_381_g1_uncompress().apply(Term::un_b_data().apply(term))
} else if field_type.is_bls381_12_g2() {
Term::bls12_381_g2_uncompress().apply(Term::un_b_data().apply(term))
} else if field_type.is_ml_result() {
panic!("ML Result not supported")
} else {
term
.apply(Term::unconstr_data().apply(term)),
UplcType::Unit => Term::equals_integer()
.apply(Term::integer(0.into()))
.apply(Term::fst_pair().apply(Term::var("__pair__")))
.delayed_if_then_else(
Term::snd_pair()
.apply(Term::var("__pair__"))
.delayed_choose_list(Term::unit(), Term::Error),
Term::Error,
)
.lambda("__pair__")
.apply(Term::unconstr_data().apply(term)),
}
}
/// Due to the nature of the types BLS12_381_G1Element and BLS12_381_G2Element and String coming from bytearray
/// We don't have error handling if the bytearray is not properly aligned to the type. Oh well lol
/// For BLS12_381_G1Element and BLS12_381_G2Element, hash to group exists so just adopt that.
pub fn unknown_data_to_type_debug(
term: Term<Name>,
field_type: &Type,
error_term: Term<Name>,
) -> Term<Name> {
if field_type.is_int() {
Term::var("__val")
let uplc_type = field_type.get_uplc_type();
match uplc_type {
UplcType::Integer => Term::var("__val")
.delayed_choose_data(
error_term.clone(),
error_term.clone(),
@ -1071,9 +1055,8 @@ pub fn unknown_data_to_type_debug(
error_term.clone(),
)
.lambda("__val")
.apply(term)
} else if field_type.is_bytearray() {
Term::var("__val")
.apply(term),
UplcType::ByteString => Term::var("__val")
.delayed_choose_data(
error_term.clone(),
error_term.clone(),
@ -1082,28 +1065,19 @@ pub fn unknown_data_to_type_debug(
Term::un_b_data().apply(Term::var("__val")),
)
.lambda("__val")
.apply(term)
} else if field_type.is_void() {
Term::var("__val")
.apply(term),
UplcType::String => Term::var("__val")
.delayed_choose_data(
Term::equals_integer()
.apply(Term::integer(0.into()))
.apply(Term::fst_pair().apply(Term::unconstr_data().apply(Term::var("__val"))))
.delayed_if_then_else(
Term::snd_pair()
.apply(Term::unconstr_data().apply(Term::var("__val")))
.delayed_choose_list(Term::unit(), error_term.clone()),
error_term.clone(),
),
error_term.clone(),
error_term.clone(),
error_term.clone(),
error_term.clone(),
Term::decode_utf8().apply(Term::un_b_data().apply(Term::var("__val"))),
)
.lambda("__val")
.apply(term)
} else if field_type.is_map() {
Term::var("__val")
.apply(term),
UplcType::List(_) if field_type.is_map() => Term::var("__val")
.delayed_choose_data(
error_term.clone(),
Term::unmap_data().apply(Term::var("__val")),
@ -1112,21 +1086,51 @@ pub fn unknown_data_to_type_debug(
error_term.clone(),
)
.lambda("__val")
.apply(term)
} else if field_type.is_string() {
Term::var("__val")
.apply(term),
UplcType::List(_) => Term::var("__val")
.delayed_choose_data(
error_term.clone(),
error_term.clone(),
Term::unlist_data().apply(Term::var("__val")),
error_term.clone(),
error_term.clone(),
)
.lambda("__val")
.apply(term),
UplcType::Data if field_type.is_data() => term,
// constr type
UplcType::Data => Term::var("__val")
.delayed_choose_data(
Term::var("__val"),
error_term.clone(),
error_term.clone(),
error_term.clone(),
error_term.clone(),
)
.lambda("__val")
.apply(term),
UplcType::Bls12_381G1Element => Term::var("__val")
.delayed_choose_data(
error_term.clone(),
error_term.clone(),
error_term.clone(),
error_term.clone(),
Term::Builtin(DefaultFunction::DecodeUtf8)
.apply(Term::un_b_data().apply(Term::var("__val"))),
Term::bls12_381_g1_uncompress().apply(Term::un_b_data().apply(Term::var("__val"))),
)
.lambda("__val")
.apply(term)
} else if field_type.is_pair() {
Term::var("__val")
.apply(term),
UplcType::Bls12_381G2Element => Term::var("__val")
.delayed_choose_data(
error_term.clone(),
error_term.clone(),
error_term.clone(),
error_term.clone(),
Term::bls12_381_g2_uncompress().apply(Term::un_b_data().apply(Term::var("__val"))),
)
.lambda("__val")
.apply(term),
UplcType::Bls12_381MlResult => panic!("ML Result not supported"),
UplcType::Pair(_, _) => Term::var("__val")
.delayed_choose_data(
error_term.clone(),
error_term.clone(),
@ -1156,20 +1160,8 @@ pub fn unknown_data_to_type_debug(
error_term.clone(),
)
.lambda("__val")
.apply(term)
} else if field_type.is_list() || field_type.is_tuple() {
Term::var("__val")
.delayed_choose_data(
error_term.clone(),
error_term.clone(),
Term::unlist_data().apply(Term::var("__val")),
error_term.clone(),
error_term.clone(),
)
.lambda("__val")
.apply(term)
} else if field_type.is_bool() {
Term::var("__val")
.apply(term),
UplcType::Bool => Term::var("__val")
.delayed_choose_data(
Term::snd_pair()
.apply(Term::var("__pair__"))
@ -1194,44 +1186,25 @@ pub fn unknown_data_to_type_debug(
error_term.clone(),
)
.lambda("__val")
.apply(term)
} else if field_type.is_bls381_12_g1() {
Term::var("__val")
.apply(term),
UplcType::Unit => Term::var("__val")
.delayed_choose_data(
Term::equals_integer()
.apply(Term::integer(0.into()))
.apply(Term::fst_pair().apply(Term::unconstr_data().apply(Term::var("__val"))))
.delayed_if_then_else(
Term::snd_pair()
.apply(Term::unconstr_data().apply(Term::var("__val")))
.delayed_choose_list(Term::unit(), error_term.clone()),
error_term.clone(),
error_term.clone(),
error_term.clone(),
error_term.clone(),
Term::bls12_381_g1_uncompress().apply(Term::un_b_data().apply(Term::var("__val"))),
)
.lambda("__val")
.apply(term)
} else if field_type.is_bls381_12_g2() {
Term::var("__val")
.delayed_choose_data(
error_term.clone(),
error_term.clone(),
error_term.clone(),
error_term.clone(),
Term::bls12_381_g2_uncompress().apply(Term::un_b_data().apply(Term::var("__val"))),
)
.lambda("__val")
.apply(term)
} else if field_type.is_ml_result() {
panic!("ML Result not supported")
} else if field_type.is_data() {
term
} else {
Term::var("__val")
.delayed_choose_data(
Term::var("__val"),
),
error_term.clone(),
error_term.clone(),
error_term.clone(),
error_term.clone(),
)
.lambda("__val")
.apply(term)
.apply(term),
}
}
@ -1323,25 +1296,24 @@ pub fn convert_constants_to_data(constants: Vec<Rc<UplcConstant>>) -> Vec<UplcCo
}
pub fn convert_type_to_data(term: Term<Name>, field_type: &Rc<Type>) -> Term<Name> {
if field_type.is_bytearray() {
Term::b_data().apply(term)
} else if field_type.is_int() {
Term::i_data().apply(term)
} else if field_type.is_void() {
term.choose_unit(Term::Constant(
UplcConstant::Data(PlutusData::Constr(Constr {
tag: convert_constr_to_tag(0).unwrap(),
any_constructor: None,
fields: vec![],
}))
.into(),
))
} else if field_type.is_map() {
Term::map_data().apply(term)
} else if field_type.is_string() {
Term::b_data().apply(Term::Builtin(DefaultFunction::EncodeUtf8).apply(term))
} else if field_type.is_pair() {
Term::list_data()
let uplc_type = field_type.get_uplc_type();
match uplc_type {
UplcType::Integer => Term::i_data().apply(term),
UplcType::String => Term::b_data().apply(Term::encode_utf8().apply(term)),
UplcType::ByteString => Term::b_data().apply(term),
UplcType::List(_) if field_type.is_map() => Term::map_data().apply(term),
UplcType::List(_) => Term::list_data().apply(term),
UplcType::Data if field_type.is_data() => term,
UplcType::Data => term,
UplcType::Bls12_381G1Element => {
Term::b_data().apply(Term::bls12_381_g1_compress().apply(term))
}
UplcType::Bls12_381G2Element => {
Term::b_data().apply(Term::bls12_381_g2_compress().apply(term))
}
UplcType::Bls12_381MlResult => panic!("ML Result not supported"),
UplcType::Pair(_, _) => Term::list_data()
.apply(
Term::mk_cons()
.apply(Term::fst_pair().apply(Term::var("__pair")))
@ -1352,11 +1324,18 @@ pub fn convert_type_to_data(term: Term<Name>, field_type: &Rc<Type>) -> Term<Nam
),
)
.lambda("__pair")
.apply(term)
} else if field_type.is_list() || field_type.is_tuple() {
Term::list_data().apply(term)
} else if field_type.is_bool() {
term.if_then_else(
.apply(term),
UplcType::Unit => Term::Constant(
UplcConstant::Data(PlutusData::Constr(Constr {
tag: convert_constr_to_tag(0).unwrap(),
any_constructor: None,
fields: vec![],
}))
.into(),
)
.lambda("_")
.apply(term),
UplcType::Bool => term.if_then_else(
Term::Constant(
UplcConstant::Data(PlutusData::Constr(Constr {
tag: convert_constr_to_tag(1).unwrap(),
@ -1373,15 +1352,7 @@ pub fn convert_type_to_data(term: Term<Name>, field_type: &Rc<Type>) -> Term<Nam
}))
.into(),
),
)
} else if field_type.is_bls381_12_g1() {
Term::b_data().apply(Term::bls12_381_g1_compress().apply(term))
} else if field_type.is_bls381_12_g2() {
Term::b_data().apply(Term::bls12_381_g2_compress().apply(term))
} else if field_type.is_ml_result() {
panic!("ML Result not supported")
} else {
term
),
}
}

View File

@ -267,12 +267,21 @@ impl Type {
}
pub fn is_primitive(&self) -> bool {
self.is_bool()
|| self.is_bytearray()
|| self.is_int()
|| self.is_string()
|| self.is_void()
|| self.is_data()
let uplc_type = self.get_uplc_type();
match uplc_type {
UplcType::Bool
| UplcType::Integer
| UplcType::String
| UplcType::ByteString
| UplcType::Unit
| UplcType::Bls12_381G1Element
| UplcType::Bls12_381G2Element
| UplcType::Bls12_381MlResult => true,
UplcType::Data if self.is_data() => true,
UplcType::Data => false,
UplcType::List(_) | UplcType::Pair(_, _) => false,
}
}
pub fn is_void(&self) -> bool {
@ -475,7 +484,6 @@ impl Type {
}
}
// TODO: THIS WILL CHANGE DUE TO PAIRS
pub fn get_uplc_type(&self) -> UplcType {
if self.is_int() {
UplcType::Integer
@ -485,6 +493,8 @@ impl Type {
UplcType::String
} else if self.is_bool() {
UplcType::Bool
} else if self.is_void() {
UplcType::Unit
} else if self.is_map() {
UplcType::List(UplcType::Pair(UplcType::Data.into(), UplcType::Data.into()).into())
} else if self.is_list() {

View File

@ -3304,7 +3304,7 @@ fn acceptance_test_29_union_tuple() {
src,
Term::equals_data()
.apply(
Term::map_data().apply(
Term::list_data().apply(
Term::var("union")
.lambda("union")
.apply(
@ -3332,18 +3332,22 @@ fn acceptance_test_29_union_tuple() {
)
.lambda("v")
.apply(
Term::un_i_data()
.apply(Term::snd_pair().apply(Term::var("pair"))),
Term::un_i_data().apply(Term::head_list().apply(
Term::tail_list().apply(Term::var("tuple")),
)),
)
.lambda("k")
.apply(
Term::un_b_data()
.apply(Term::fst_pair().apply(Term::var("pair"))),
.apply(Term::head_list().apply(Term::var("tuple"))),
)
.lambda("rest")
.apply(Term::tail_list().apply(Term::var("left")))
.lambda("pair")
.lambda("tuple")
.apply(
Term::unlist_data()
.apply(Term::head_list().apply(Term::var("left"))),
),
)
.lambda("right")
.lambda("left")
@ -3360,40 +3364,74 @@ fn acceptance_test_29_union_tuple() {
.delayed_choose_list(
Term::mk_cons()
.apply(
Term::mk_pair_data()
.apply(Term::b_data().apply(Term::var("k")))
Term::list_data().apply(
Term::mk_cons()
.apply(
Term::i_data().apply(Term::var("v")),
Term::b_data()
.apply(Term::var("k")),
)
.apply(
Term::mk_cons()
.apply(
Term::i_data()
.apply(Term::var("v")),
)
.apply(Term::empty_list()),
),
),
)
.apply(Term::empty_map()),
.apply(Term::empty_list()),
Term::equals_bytestring()
.apply(Term::var("k"))
.apply(Term::var("k2"))
.delayed_if_then_else(
Term::mk_cons()
.apply(
Term::mk_pair_data()
Term::list_data().apply(
Term::mk_cons()
.apply(
Term::b_data()
.apply(Term::var("k")),
)
.apply(
Term::mk_cons()
.apply(
Term::i_data()
.apply(Term::var("v")),
.apply(
Term::var(
"v",
),
),
)
.apply(
Term::empty_list(),
),
),
),
)
.apply(Term::var("rest")),
Term::mk_cons()
.apply(
Term::mk_pair_data()
Term::list_data().apply(
Term::mk_cons()
.apply(
Term::b_data()
.apply(Term::var("k2")),
)
.apply(
Term::mk_cons()
.apply(
Term::i_data()
.apply(Term::var("v2")),
.apply(
Term::var(
"v2",
),
),
)
.apply(
Term::empty_list(),
),
),
),
)
.apply(
@ -3404,16 +3442,20 @@ fn acceptance_test_29_union_tuple() {
)
.lambda("v2")
.apply(Term::un_i_data().apply(
Term::snd_pair().apply(Term::var("pair")),
Term::head_list().apply(
Term::tail_list().apply(Term::var("tuple")),
),
))
.lambda("k2")
.apply(Term::un_b_data().apply(
Term::fst_pair().apply(Term::var("pair")),
Term::head_list().apply(Term::var("tuple")),
))
.lambda("rest")
.apply(Term::tail_list().apply(Term::var("elems")))
.lambda("pair")
.apply(Term::head_list().apply(Term::var("elems"))),
.lambda("tuple")
.apply(Term::unlist_data().apply(
Term::head_list().apply(Term::var("elems")),
)),
)
.lambda("elems")
.lambda("do_insert"),
@ -3422,32 +3464,28 @@ fn acceptance_test_29_union_tuple() {
.lambda("k")
.lambda("elems"),
)
.apply(Term::map_values(vec![
Constant::ProtoPair(
Type::Data,
Type::Data,
Constant::Data(Data::bytestring("foo".as_bytes().to_vec())).into(),
Constant::Data(Data::integer(42.into())).into(),
),
Constant::ProtoPair(
Type::Data,
Type::Data,
Constant::Data(Data::bytestring("bar".as_bytes().to_vec())).into(),
Constant::Data(Data::integer(14.into())).into(),
),
]))
.apply(Term::empty_map()),
),
)
.apply(Term::data(Data::map(vec![
(
.apply(Term::list_values(vec![
Constant::Data(Data::list(vec![
Data::bytestring("foo".as_bytes().to_vec()),
Data::integer(42.into()),
),
(
])),
Constant::Data(Data::list(vec![
Data::bytestring("bar".as_bytes().to_vec()),
Data::integer(14.into()),
])),
]))
.apply(Term::empty_list()),
),
)
.apply(Term::data(Data::list(vec![
Data::list(vec![
Data::bytestring("foo".as_bytes().to_vec()),
Data::integer(42.into()),
]),
Data::list(vec![
Data::bytestring("bar".as_bytes().to_vec()),
Data::integer(14.into()),
]),
]))),
false,
);