delay otherwise branch to prevent premature errors
This commit is contained in:
parent
df939e20ce
commit
e09f6bbc87
|
@ -259,7 +259,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
let air_value = self.build(value, module_build_name, &[]);
|
let air_value = self.build(value, module_build_name, &[]);
|
||||||
|
|
||||||
let otherwise = match (self.tracing, kind) {
|
let otherwise_delayed = match (self.tracing, kind) {
|
||||||
(
|
(
|
||||||
TraceLevel::Silent,
|
TraceLevel::Silent,
|
||||||
AssignmentKind::Let { .. } | AssignmentKind::Expect { .. },
|
AssignmentKind::Let { .. } | AssignmentKind::Expect { .. },
|
||||||
|
@ -285,7 +285,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
self.special_functions.insert_new_function(
|
self.special_functions.insert_new_function(
|
||||||
msg_func_name.clone(),
|
msg_func_name.clone(),
|
||||||
Term::Error.delayed_trace(Term::string(msg)),
|
Term::Error.delayed_trace(Term::string(msg)).delay(),
|
||||||
void(),
|
void(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -307,7 +307,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
kind: *kind,
|
kind: *kind,
|
||||||
remove_unused: kind.is_let(),
|
remove_unused: kind.is_let(),
|
||||||
full_check: !tipo.is_data() && value.tipo().is_data() && kind.is_expect(),
|
full_check: !tipo.is_data() && value.tipo().is_data() && kind.is_expect(),
|
||||||
otherwise,
|
otherwise: otherwise_delayed,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
@ -645,7 +645,11 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let body = self.build(&branch.body, module_build_name, &[]);
|
let body = self.build(&branch.body, module_build_name, &[]);
|
||||||
|
|
||||||
match &branch.is {
|
match &branch.is {
|
||||||
Some(pattern) => self.assignment(
|
Some(pattern) => AirTree::let_assignment(
|
||||||
|
"acc_var",
|
||||||
|
// use anon function as a delay to avoid evaluating the acc
|
||||||
|
AirTree::anon_func(vec![], acc),
|
||||||
|
self.assignment(
|
||||||
pattern,
|
pattern,
|
||||||
condition,
|
condition,
|
||||||
body,
|
body,
|
||||||
|
@ -655,9 +659,10 @@ impl<'a> CodeGenerator<'a> {
|
||||||
kind: AssignmentKind::Expect { backpassing: () },
|
kind: AssignmentKind::Expect { backpassing: () },
|
||||||
remove_unused: false,
|
remove_unused: false,
|
||||||
full_check: true,
|
full_check: true,
|
||||||
otherwise: acc,
|
otherwise: AirTree::local_var("acc_var", void()),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
),
|
||||||
None => AirTree::if_branch(tipo.clone(), condition, body, acc),
|
None => AirTree::if_branch(tipo.clone(), condition, body, acc),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -3030,7 +3035,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
let actual_type = convert_opaque_type(&arg.tipo, &self.data_types, true);
|
let actual_type = convert_opaque_type(&arg.tipo, &self.data_types, true);
|
||||||
|
|
||||||
let otherwise = match self.tracing {
|
let otherwise_delayed = match self.tracing {
|
||||||
TraceLevel::Silent => AirTree::error(void(), false),
|
TraceLevel::Silent => AirTree::error(void(), false),
|
||||||
TraceLevel::Compact | TraceLevel::Verbose => {
|
TraceLevel::Compact | TraceLevel::Verbose => {
|
||||||
let msg = match self.tracing {
|
let msg = match self.tracing {
|
||||||
|
@ -3051,7 +3056,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
self.special_functions.insert_new_function(
|
self.special_functions.insert_new_function(
|
||||||
msg_func_name.to_string(),
|
msg_func_name.to_string(),
|
||||||
Term::Error.delayed_trace(Term::string(msg)),
|
Term::Error.delayed_trace(Term::string(msg)).delay(),
|
||||||
void(),
|
void(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -3072,7 +3077,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
kind: AssignmentKind::expect(),
|
kind: AssignmentKind::expect(),
|
||||||
remove_unused: false,
|
remove_unused: false,
|
||||||
full_check: true,
|
full_check: true,
|
||||||
otherwise,
|
otherwise: otherwise_delayed,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -4835,7 +4840,8 @@ impl<'a> CodeGenerator<'a> {
|
||||||
)
|
)
|
||||||
.apply(constr),
|
.apply(constr),
|
||||||
)
|
)
|
||||||
.delayed_if_then_else(term, otherwise);
|
.if_then_else(term.delay(), otherwise)
|
||||||
|
.force();
|
||||||
|
|
||||||
Some(term)
|
Some(term)
|
||||||
}
|
}
|
||||||
|
@ -4846,9 +4852,9 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let otherwise = arg_stack.pop().unwrap();
|
let otherwise = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
if is_true {
|
if is_true {
|
||||||
term = value.delayed_if_then_else(term, otherwise)
|
term = value.if_then_else(term.delay(), otherwise).force()
|
||||||
} else {
|
} else {
|
||||||
term = value.delayed_if_then_else(otherwise, term)
|
term = value.if_then_else(otherwise, term.delay()).force()
|
||||||
}
|
}
|
||||||
Some(term)
|
Some(term)
|
||||||
}
|
}
|
||||||
|
@ -5339,7 +5345,8 @@ impl<'a> CodeGenerator<'a> {
|
||||||
.use_function_uplc(CONSTR_FIELDS_EXPOSER.to_string()),
|
.use_function_uplc(CONSTR_FIELDS_EXPOSER.to_string()),
|
||||||
)
|
)
|
||||||
.apply(value)
|
.apply(value)
|
||||||
.delayed_choose_list(term, otherwise);
|
.choose_list(term.delay(), otherwise)
|
||||||
|
.force();
|
||||||
|
|
||||||
Some(term)
|
Some(term)
|
||||||
}
|
}
|
||||||
|
@ -5349,7 +5356,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let mut term = arg_stack.pop().unwrap();
|
let mut term = arg_stack.pop().unwrap();
|
||||||
let otherwise = arg_stack.pop().unwrap();
|
let otherwise = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
term = value.delayed_choose_list(term, otherwise);
|
term = value.choose_list(term.delay(), otherwise).force();
|
||||||
|
|
||||||
Some(term)
|
Some(term)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1038,117 +1038,138 @@ pub fn unknown_data_to_type(term: Term<Name>, field_type: &Type) -> Term<Name> {
|
||||||
pub fn unknown_data_to_type_otherwise(
|
pub fn unknown_data_to_type_otherwise(
|
||||||
term: Term<Name>,
|
term: Term<Name>,
|
||||||
field_type: &Type,
|
field_type: &Type,
|
||||||
error_term: Term<Name>,
|
otherwise_delayed: Term<Name>,
|
||||||
) -> Term<Name> {
|
) -> Term<Name> {
|
||||||
let uplc_type = field_type.get_uplc_type();
|
let uplc_type = field_type.get_uplc_type();
|
||||||
|
|
||||||
match uplc_type {
|
match uplc_type {
|
||||||
Some(UplcType::Integer) => Term::var("__val")
|
Some(UplcType::Integer) => Term::var("__val")
|
||||||
.delayed_choose_data(
|
.choose_data(
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
Term::un_i_data().apply(Term::var("__val")),
|
Term::un_i_data().apply(Term::var("__val")).delay(),
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
)
|
)
|
||||||
|
.force()
|
||||||
.lambda("__val")
|
.lambda("__val")
|
||||||
.apply(term),
|
.apply(term),
|
||||||
Some(UplcType::ByteString) => Term::var("__val")
|
Some(UplcType::ByteString) => Term::var("__val")
|
||||||
.delayed_choose_data(
|
.choose_data(
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
Term::un_b_data().apply(Term::var("__val")),
|
Term::un_b_data().apply(Term::var("__val")).delay(),
|
||||||
)
|
)
|
||||||
|
.force()
|
||||||
.lambda("__val")
|
.lambda("__val")
|
||||||
.apply(term),
|
.apply(term),
|
||||||
Some(UplcType::String) => Term::var("__val")
|
Some(UplcType::String) => Term::var("__val")
|
||||||
.delayed_choose_data(
|
.choose_data(
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
Term::decode_utf8().apply(Term::un_b_data().apply(Term::var("__val"))),
|
Term::decode_utf8()
|
||||||
|
.apply(Term::un_b_data().apply(Term::var("__val")))
|
||||||
|
.delay(),
|
||||||
)
|
)
|
||||||
|
.force()
|
||||||
.lambda("__val")
|
.lambda("__val")
|
||||||
.apply(term),
|
.apply(term),
|
||||||
|
|
||||||
Some(UplcType::List(_)) if field_type.is_map() => Term::var("__val")
|
Some(UplcType::List(_)) if field_type.is_map() => Term::var("__val")
|
||||||
.delayed_choose_data(
|
.choose_data(
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
Term::unmap_data().apply(Term::var("__val")),
|
Term::unmap_data().apply(Term::var("__val")).delay(),
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
)
|
)
|
||||||
|
.force()
|
||||||
.lambda("__val")
|
.lambda("__val")
|
||||||
.apply(term),
|
.apply(term),
|
||||||
Some(UplcType::List(_)) => Term::var("__val")
|
Some(UplcType::List(_)) => Term::var("__val")
|
||||||
.delayed_choose_data(
|
.choose_data(
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
Term::unlist_data().apply(Term::var("__val")),
|
Term::unlist_data().apply(Term::var("__val")).delay(),
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
)
|
)
|
||||||
|
.force()
|
||||||
.lambda("__val")
|
.lambda("__val")
|
||||||
.apply(term),
|
.apply(term),
|
||||||
|
|
||||||
Some(UplcType::Bls12_381G1Element) => Term::var("__val")
|
Some(UplcType::Bls12_381G1Element) => Term::var("__val")
|
||||||
.delayed_choose_data(
|
.choose_data(
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
Term::bls12_381_g1_uncompress().apply(Term::un_b_data().apply(Term::var("__val"))),
|
Term::bls12_381_g1_uncompress()
|
||||||
|
.apply(Term::un_b_data().apply(Term::var("__val")))
|
||||||
|
.delay(),
|
||||||
)
|
)
|
||||||
|
.force()
|
||||||
.lambda("__val")
|
.lambda("__val")
|
||||||
.apply(term),
|
.apply(term),
|
||||||
Some(UplcType::Bls12_381G2Element) => Term::var("__val")
|
Some(UplcType::Bls12_381G2Element) => Term::var("__val")
|
||||||
.delayed_choose_data(
|
.choose_data(
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
Term::bls12_381_g2_uncompress().apply(Term::un_b_data().apply(Term::var("__val"))),
|
Term::bls12_381_g2_uncompress()
|
||||||
|
.apply(Term::un_b_data().apply(Term::var("__val")))
|
||||||
|
.delay(),
|
||||||
)
|
)
|
||||||
|
.force()
|
||||||
.lambda("__val")
|
.lambda("__val")
|
||||||
.apply(term),
|
.apply(term),
|
||||||
Some(UplcType::Bls12_381MlResult) => panic!("ML Result not supported"),
|
Some(UplcType::Bls12_381MlResult) => panic!("ML Result not supported"),
|
||||||
Some(UplcType::Pair(_, _)) => Term::var("__val")
|
Some(UplcType::Pair(_, _)) => Term::var("__val")
|
||||||
.delayed_choose_data(
|
.choose_data(
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
Term::var("__list_data")
|
Term::var("__list_data")
|
||||||
.delayed_choose_list(
|
.choose_list(
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
Term::var("__tail")
|
Term::var("__tail")
|
||||||
.delayed_choose_list(
|
.choose_list(
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
Term::tail_list()
|
Term::tail_list()
|
||||||
.apply(Term::var("__tail"))
|
.apply(Term::var("__tail"))
|
||||||
.delayed_choose_list(
|
.choose_list(
|
||||||
Term::mk_pair_data()
|
Term::mk_pair_data()
|
||||||
.apply(
|
.apply(
|
||||||
Term::head_list().apply(Term::var("__list_data")),
|
Term::head_list().apply(Term::var("__list_data")),
|
||||||
)
|
)
|
||||||
.apply(Term::head_list().apply(Term::var("__tail"))),
|
.apply(Term::head_list().apply(Term::var("__tail")))
|
||||||
error_term.clone(),
|
.delay(),
|
||||||
),
|
otherwise_delayed.clone(),
|
||||||
)
|
)
|
||||||
|
.force()
|
||||||
|
.delay(),
|
||||||
|
)
|
||||||
|
.force()
|
||||||
.lambda("__tail")
|
.lambda("__tail")
|
||||||
.apply(Term::tail_list().apply(Term::var("__list_data"))),
|
.apply(Term::tail_list().apply(Term::var("__list_data")))
|
||||||
|
.delay(),
|
||||||
)
|
)
|
||||||
|
.force()
|
||||||
.lambda("__list_data")
|
.lambda("__list_data")
|
||||||
.apply(Term::unlist_data().apply(Term::var("__val"))),
|
.apply(Term::unlist_data().apply(Term::var("__val")))
|
||||||
error_term.clone(),
|
.delay(),
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
|
otherwise_delayed.clone(),
|
||||||
)
|
)
|
||||||
|
.force()
|
||||||
.lambda("__val")
|
.lambda("__val")
|
||||||
.apply(term),
|
.apply(term),
|
||||||
Some(UplcType::Bool) => Term::var("__val")
|
Some(UplcType::Bool) => Term::var("__val")
|
||||||
.delayed_choose_data(
|
.choose_data(
|
||||||
Term::snd_pair()
|
Term::snd_pair()
|
||||||
.apply(Term::var("__pair__"))
|
.apply(Term::var("__pair__"))
|
||||||
.delayed_choose_list(
|
.delayed_choose_list(
|
||||||
|
@ -1160,48 +1181,56 @@ pub fn unknown_data_to_type_otherwise(
|
||||||
Term::equals_integer()
|
Term::equals_integer()
|
||||||
.apply(Term::integer(0.into()))
|
.apply(Term::integer(0.into()))
|
||||||
.apply(Term::fst_pair().apply(Term::var("__pair__")))
|
.apply(Term::fst_pair().apply(Term::var("__pair__")))
|
||||||
.delayed_if_then_else(Term::bool(false), error_term.clone()),
|
.delayed_if_then_else(
|
||||||
|
Term::bool(false),
|
||||||
|
otherwise_delayed.clone(),
|
||||||
),
|
),
|
||||||
error_term.clone(),
|
),
|
||||||
|
otherwise_delayed.clone(),
|
||||||
)
|
)
|
||||||
.lambda("__pair__")
|
.lambda("__pair__")
|
||||||
.apply(Term::unconstr_data().apply(Term::var("__val"))),
|
.apply(Term::unconstr_data().apply(Term::var("__val")))
|
||||||
error_term.clone(),
|
.delay(),
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
|
otherwise_delayed.clone(),
|
||||||
)
|
)
|
||||||
|
.force()
|
||||||
.lambda("__val")
|
.lambda("__val")
|
||||||
.apply(term),
|
.apply(term),
|
||||||
Some(UplcType::Unit) => Term::var("__val")
|
Some(UplcType::Unit) => Term::var("__val")
|
||||||
.delayed_choose_data(
|
.choose_data(
|
||||||
Term::equals_integer()
|
Term::equals_integer()
|
||||||
.apply(Term::integer(0.into()))
|
.apply(Term::integer(0.into()))
|
||||||
.apply(Term::fst_pair().apply(Term::unconstr_data().apply(Term::var("__val"))))
|
.apply(Term::fst_pair().apply(Term::unconstr_data().apply(Term::var("__val"))))
|
||||||
.delayed_if_then_else(
|
.delayed_if_then_else(
|
||||||
Term::snd_pair()
|
Term::snd_pair()
|
||||||
.apply(Term::unconstr_data().apply(Term::var("__val")))
|
.apply(Term::unconstr_data().apply(Term::var("__val")))
|
||||||
.delayed_choose_list(Term::unit(), error_term.clone()),
|
.delayed_choose_list(Term::unit(), otherwise_delayed.clone()),
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
),
|
|
||||||
error_term.clone(),
|
|
||||||
error_term.clone(),
|
|
||||||
error_term.clone(),
|
|
||||||
error_term.clone(),
|
|
||||||
)
|
)
|
||||||
|
.delay(),
|
||||||
|
otherwise_delayed.clone(),
|
||||||
|
otherwise_delayed.clone(),
|
||||||
|
otherwise_delayed.clone(),
|
||||||
|
otherwise_delayed.clone(),
|
||||||
|
)
|
||||||
|
.force()
|
||||||
.lambda("__val")
|
.lambda("__val")
|
||||||
.apply(term),
|
.apply(term),
|
||||||
|
|
||||||
Some(UplcType::Data) => term,
|
Some(UplcType::Data) => term,
|
||||||
// constr type
|
// constr type
|
||||||
None => Term::var("__val")
|
None => Term::var("__val")
|
||||||
.delayed_choose_data(
|
.choose_data(
|
||||||
Term::var("__val"),
|
Term::var("__val").delay(),
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
error_term.clone(),
|
otherwise_delayed.clone(),
|
||||||
)
|
)
|
||||||
|
.force()
|
||||||
.lambda("__val")
|
.lambda("__val")
|
||||||
.apply(term),
|
.apply(term),
|
||||||
}
|
}
|
||||||
|
@ -1362,7 +1391,7 @@ pub fn list_access_to_uplc(
|
||||||
term: Term<Name>,
|
term: Term<Name>,
|
||||||
is_list_accessor: bool,
|
is_list_accessor: bool,
|
||||||
expect_level: ExpectLevel,
|
expect_level: ExpectLevel,
|
||||||
otherwise: Term<Name>,
|
otherwise_delayed: Term<Name>,
|
||||||
) -> Term<Name> {
|
) -> Term<Name> {
|
||||||
let names_len = names_types_ids.len();
|
let names_len = names_types_ids.len();
|
||||||
|
|
||||||
|
@ -1393,7 +1422,8 @@ pub fn list_access_to_uplc(
|
||||||
}
|
}
|
||||||
|
|
||||||
return Term::var("empty_list")
|
return Term::var("empty_list")
|
||||||
.delayed_choose_list(term, otherwise)
|
.choose_list(term.delay(), otherwise_delayed)
|
||||||
|
.force()
|
||||||
.lambda("empty_list");
|
.lambda("empty_list");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1412,7 +1442,7 @@ pub fn list_access_to_uplc(
|
||||||
Term::head_list().apply(Term::var(tail_name.to_string()))
|
Term::head_list().apply(Term::var(tail_name.to_string()))
|
||||||
} else if matches!(expect_level, ExpectLevel::Full) {
|
} else if matches!(expect_level, ExpectLevel::Full) {
|
||||||
// Expect level is full so we have an unknown piece of data to cast
|
// Expect level is full so we have an unknown piece of data to cast
|
||||||
if otherwise == Term::Error {
|
if otherwise_delayed == Term::Error {
|
||||||
unknown_data_to_type(
|
unknown_data_to_type(
|
||||||
Term::head_list().apply(Term::var(tail_name.to_string())),
|
Term::head_list().apply(Term::var(tail_name.to_string())),
|
||||||
&tipo.to_owned(),
|
&tipo.to_owned(),
|
||||||
|
@ -1421,7 +1451,7 @@ pub fn list_access_to_uplc(
|
||||||
unknown_data_to_type_otherwise(
|
unknown_data_to_type_otherwise(
|
||||||
Term::head_list().apply(Term::var(tail_name.to_string())),
|
Term::head_list().apply(Term::var(tail_name.to_string())),
|
||||||
&tipo.to_owned(),
|
&tipo.to_owned(),
|
||||||
otherwise.clone(),
|
otherwise_delayed.clone(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1456,36 +1486,40 @@ pub fn list_access_to_uplc(
|
||||||
ExpectLevel::None => acc.lambda(name).apply(head_item).lambda(tail_name),
|
ExpectLevel::None => acc.lambda(name).apply(head_item).lambda(tail_name),
|
||||||
|
|
||||||
ExpectLevel::Full | ExpectLevel::Items => {
|
ExpectLevel::Full | ExpectLevel::Items => {
|
||||||
if otherwise == Term::Error && tail_present {
|
if otherwise_delayed == Term::Error && tail_present {
|
||||||
// No need to check last item if tail was present
|
// No need to check last item if tail was present
|
||||||
acc.lambda(name).apply(head_item).lambda(tail_name)
|
acc.lambda(name).apply(head_item).lambda(tail_name)
|
||||||
} else if tail_present {
|
} else if tail_present {
|
||||||
// Custom error instead of trying to do head_item on a possibly empty list.
|
// Custom error instead of trying to do head_item on a possibly empty list.
|
||||||
Term::var(tail_name.to_string())
|
Term::var(tail_name.to_string())
|
||||||
.delayed_choose_list(
|
.choose_list(
|
||||||
otherwise.clone(),
|
otherwise_delayed.clone(),
|
||||||
acc.lambda(name).apply(head_item),
|
acc.lambda(name).apply(head_item).delay(),
|
||||||
)
|
)
|
||||||
|
.force()
|
||||||
.lambda(tail_name)
|
.lambda(tail_name)
|
||||||
} else if otherwise == Term::Error {
|
} else if otherwise_delayed == Term::Error {
|
||||||
// Check head is last item in this list
|
// Check head is last item in this list
|
||||||
Term::tail_list()
|
Term::tail_list()
|
||||||
.apply(Term::var(tail_name.to_string()))
|
.apply(Term::var(tail_name.to_string()))
|
||||||
.delayed_choose_list(acc, otherwise.clone())
|
.choose_list(acc.delay(), otherwise_delayed.clone())
|
||||||
|
.force()
|
||||||
.lambda(name)
|
.lambda(name)
|
||||||
.apply(head_item)
|
.apply(head_item)
|
||||||
.lambda(tail_name)
|
.lambda(tail_name)
|
||||||
} else {
|
} else {
|
||||||
// Custom error if list is not empty after this head
|
// Custom error if list is not empty after this head
|
||||||
Term::var(tail_name.to_string())
|
Term::var(tail_name.to_string())
|
||||||
.delayed_choose_list(
|
.choose_list(
|
||||||
otherwise.clone(),
|
otherwise_delayed.clone(),
|
||||||
Term::tail_list()
|
Term::tail_list()
|
||||||
.apply(Term::var(tail_name.to_string()))
|
.apply(Term::var(tail_name.to_string()))
|
||||||
.delayed_choose_list(acc, otherwise.clone())
|
.choose_list(acc.delay(), otherwise_delayed.clone())
|
||||||
|
.force()
|
||||||
.lambda(name)
|
.lambda(name)
|
||||||
.apply(head_item),
|
.apply(head_item),
|
||||||
)
|
)
|
||||||
|
.force()
|
||||||
.lambda(tail_name)
|
.lambda(tail_name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1498,7 +1532,8 @@ pub fn list_access_to_uplc(
|
||||||
|
|
||||||
let head_item = head_item(name, tipo, &tail_name);
|
let head_item = head_item(name, tipo, &tail_name);
|
||||||
|
|
||||||
if matches!(expect_level, ExpectLevel::None) || otherwise == Term::Error {
|
if matches!(expect_level, ExpectLevel::None) || otherwise_delayed == Term::Error
|
||||||
|
{
|
||||||
acc.apply(Term::tail_list().apply(Term::var(tail_name.to_string())))
|
acc.apply(Term::tail_list().apply(Term::var(tail_name.to_string())))
|
||||||
.lambda(name)
|
.lambda(name)
|
||||||
.apply(head_item)
|
.apply(head_item)
|
||||||
|
@ -1506,14 +1541,16 @@ pub fn list_access_to_uplc(
|
||||||
} else {
|
} else {
|
||||||
// case for a custom error if the list is empty at this point
|
// case for a custom error if the list is empty at this point
|
||||||
Term::var(tail_name.to_string())
|
Term::var(tail_name.to_string())
|
||||||
.delayed_choose_list(
|
.choose_list(
|
||||||
otherwise.clone(),
|
otherwise_delayed.clone(),
|
||||||
acc.apply(
|
acc.apply(
|
||||||
Term::tail_list().apply(Term::var(tail_name.to_string())),
|
Term::tail_list().apply(Term::var(tail_name.to_string())),
|
||||||
)
|
)
|
||||||
.lambda(name)
|
.lambda(name)
|
||||||
.apply(head_item),
|
.apply(head_item)
|
||||||
|
.delay(),
|
||||||
)
|
)
|
||||||
|
.force()
|
||||||
.lambda(tail_name)
|
.lambda(tail_name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue