constants are back. I had broke them when switching how data casting works

This commit is contained in:
microproofs 2023-07-28 18:37:16 -04:00 committed by Kasey
parent 0b8266dfd1
commit 5aecb96668
3 changed files with 79 additions and 11 deletions

View File

@ -38,9 +38,9 @@ use crate::{
use self::{
air::Air,
builder::{
cast_validator_args, constants_ir, convert_type_to_data, lookup_data_type_by_tipo,
modify_self_calls, rearrange_list_clauses, AssignmentProperties, ClauseProperties,
DataTypeKey, FunctionAccessKey, UserFunction,
cast_validator_args, constants_ir, convert_type_to_data, extract_constant,
lookup_data_type_by_tipo, modify_self_calls, rearrange_list_clauses, AssignmentProperties,
ClauseProperties, DataTypeKey, FunctionAccessKey, UserFunction,
},
tree::{AirExpression, AirTree, TreePath},
};
@ -3226,8 +3226,9 @@ impl<'a> CodeGenerator<'a> {
}
let mut constants = vec![];
for arg in &args {
if let Term::Constant(c) = arg {
constants.push(c.clone())
let maybe_const = extract_constant(arg);
if let Some(c) = maybe_const {
constants.push(c);
}
}
@ -3695,14 +3696,52 @@ impl<'a> CodeGenerator<'a> {
Air::CastFromData { tipo } => {
let mut term = arg_stack.pop().unwrap();
term = builder::convert_data_to_type(term, &tipo);
if extract_constant(&term).is_some() {
term = builder::convert_data_to_type(term, &tipo);
let mut program: Program<Name> = Program {
version: (1, 0, 0),
term,
};
let mut interner = Interner::new();
interner.program(&mut program);
let eval_program: Program<NamedDeBruijn> = program.try_into().unwrap();
let evaluated_term: Term<NamedDeBruijn> =
eval_program.eval(ExBudget::default()).result().unwrap();
term = evaluated_term.try_into().unwrap();
} else {
term = builder::convert_data_to_type(term, &tipo);
}
arg_stack.push(term);
}
Air::CastToData { tipo } => {
let mut term = arg_stack.pop().unwrap();
term = builder::convert_type_to_data(term, &tipo);
if extract_constant(&term).is_some() {
term = builder::convert_type_to_data(term, &tipo);
let mut program: Program<Name> = Program {
version: (1, 0, 0),
term,
};
let mut interner = Interner::new();
interner.program(&mut program);
let eval_program: Program<NamedDeBruijn> = program.try_into().unwrap();
let evaluated_term: Term<NamedDeBruijn> =
eval_program.eval(ExBudget::default()).result().unwrap();
term = evaluated_term.try_into().unwrap();
} else {
term = builder::convert_type_to_data(term, &tipo);
}
arg_stack.push(term);
}
@ -4069,7 +4108,10 @@ impl<'a> CodeGenerator<'a> {
.apply(Term::integer(constr_index.into()))
.apply(term);
if arg_vec.iter().all(|item| matches!(item, Term::Constant(_))) {
if arg_vec.iter().all(|item| {
let maybe_const = extract_constant(item);
maybe_const.is_some()
}) {
let mut program: Program<Name> = Program {
version: (1, 0, 0),
term,
@ -4195,8 +4237,9 @@ impl<'a> CodeGenerator<'a> {
}
let mut constants = vec![];
for arg in &args {
if let Term::Constant(c) = arg {
constants.push(c.clone())
let maybe_const = extract_constant(arg);
if let Some(c) = maybe_const {
constants.push(c);
}
}

View File

@ -1424,3 +1424,26 @@ pub fn wrap_validator_condition(air_tree: AirTree) -> AirTree {
AirTree::if_branches(success_branch, void(), otherwise)
}
pub fn extract_constant(term: &Term<Name>) -> Option<Rc<UplcConstant>> {
let mut constant = None;
if let Term::Constant(c) = term {
constant = Some(c.clone());
} else if let Term::Apply { function, argument } = term {
if let Term::Constant(c) = argument.as_ref() {
if let Term::Builtin(b) = function.as_ref() {
if matches!(
b,
DefaultFunction::BData
| DefaultFunction::IData
| DefaultFunction::MapData
| DefaultFunction::ListData
) {
constant = Some(c.clone());
}
}
}
}
constant
}

View File

@ -1391,7 +1391,9 @@ fn acceptance_test_14_list_creation() {
)
.apply(
Term::mk_cons()
.apply(Term::i_data().apply(Term::integer(0.into())))
.apply(Term::Constant(
Constant::Data(Data::integer(0.into())).into(),
))
.apply(Term::empty_list()),
),
),