From 5aecb96668e2434fd8d622365e3f1dca9ce95396 Mon Sep 17 00:00:00 2001 From: microproofs Date: Fri, 28 Jul 2023 18:37:16 -0400 Subject: [PATCH] constants are back. I had broke them when switching how data casting works --- crates/aiken-lang/src/gen_uplc.rs | 63 ++++++++++++++++++---- crates/aiken-lang/src/gen_uplc/builder.rs | 23 ++++++++ crates/aiken-project/src/tests/gen_uplc.rs | 4 +- 3 files changed, 79 insertions(+), 11 deletions(-) diff --git a/crates/aiken-lang/src/gen_uplc.rs b/crates/aiken-lang/src/gen_uplc.rs index a101d942..097c50de 100644 --- a/crates/aiken-lang/src/gen_uplc.rs +++ b/crates/aiken-lang/src/gen_uplc.rs @@ -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 = Program { + version: (1, 0, 0), + term, + }; + + let mut interner = Interner::new(); + + interner.program(&mut program); + + let eval_program: Program = program.try_into().unwrap(); + + let evaluated_term: Term = + 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 = Program { + version: (1, 0, 0), + term, + }; + + let mut interner = Interner::new(); + + interner.program(&mut program); + + let eval_program: Program = program.try_into().unwrap(); + + let evaluated_term: Term = + 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 = 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); } } diff --git a/crates/aiken-lang/src/gen_uplc/builder.rs b/crates/aiken-lang/src/gen_uplc/builder.rs index 4a758a5e..52718641 100644 --- a/crates/aiken-lang/src/gen_uplc/builder.rs +++ b/crates/aiken-lang/src/gen_uplc/builder.rs @@ -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) -> Option> { + 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 +} diff --git a/crates/aiken-project/src/tests/gen_uplc.rs b/crates/aiken-project/src/tests/gen_uplc.rs index b1aa10c9..641c705b 100644 --- a/crates/aiken-project/src/tests/gen_uplc.rs +++ b/crates/aiken-project/src/tests/gen_uplc.rs @@ -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()), ), ),