From 765ceefd38cd97e6145969c61d0e5dfdeb7b297b Mon Sep 17 00:00:00 2001 From: Kasey White Date: Sun, 12 Feb 2023 18:53:02 -0500 Subject: [PATCH] feat: add ability to downcast void to data --- crates/aiken-lang/src/builder.rs | 37 ++++++++- crates/aiken-lang/src/uplc.rs | 20 +++-- examples/acceptance_tests/055/lib/tests.ak | 90 ++++++++++++++++++++++ 3 files changed, 140 insertions(+), 7 deletions(-) diff --git a/crates/aiken-lang/src/builder.rs b/crates/aiken-lang/src/builder.rs index 3225cb37..d4c052b6 100644 --- a/crates/aiken-lang/src/builder.rs +++ b/crates/aiken-lang/src/builder.rs @@ -4,7 +4,7 @@ use indexmap::{IndexMap, IndexSet}; use itertools::Itertools; use uplc::{ ast::{ - builder::{apply_wrap, delayed_choose_list, if_else}, + builder::{apply_wrap, delayed_choose_list, delayed_if_else, if_else}, Constant as UplcConstant, Name, Term, Type as UplcType, }, builtins::DefaultFunction, @@ -190,6 +190,18 @@ pub fn convert_type_to_data(term: Term, field_type: &Arc) -> Term, field_type: &Arc) -> Term>) -> Vec d.clone(), - _ => unreachable!(), + UplcConstant::Unit => UplcConstant::Data(PlutusData::Constr(Constr { + tag: convert_constr_to_tag(0).unwrap(), + any_constructor: None, + fields: vec![], + })), }; new_constants.push(constant); } diff --git a/crates/aiken-lang/src/uplc.rs b/crates/aiken-lang/src/uplc.rs index 22d522a1..3d475899 100644 --- a/crates/aiken-lang/src/uplc.rs +++ b/crates/aiken-lang/src/uplc.rs @@ -253,12 +253,22 @@ impl<'a> CodeGenerator<'a> { count: args.len(), }); - for arg in args { - let mut scope = scope.clone(); - scope.push(self.id_gen.next()); - self.build_ir(&arg.value, ir_stack, scope); + if let Some(fun_arg_types) = fun.tipo().arg_types() { + for (arg, func_type) in args.iter().zip(fun_arg_types) { + let mut scope = scope.clone(); + scope.push(self.id_gen.next()); + + if func_type.is_data() && !arg.value.tipo().is_data() { + ir_stack.push(Air::WrapData { + scope: scope.clone(), + tipo: arg.value.tipo(), + }) + } + + self.build_ir(&arg.value, ir_stack, scope); + } + return; } - return; } } } diff --git a/examples/acceptance_tests/055/lib/tests.ak b/examples/acceptance_tests/055/lib/tests.ak index 482e6035..b2bc6811 100644 --- a/examples/acceptance_tests/055/lib/tests.ak +++ b/examples/acceptance_tests/055/lib/tests.ak @@ -1,7 +1,16 @@ use aiken/bytearray +use aiken/dict use aiken/hash.{Hash, Sha2_256, sha2_256} +use aiken/interval.{Interval, IntervalBound, PositiveInfinity} use aiken/list use aiken/string +use aiken/transaction.{ + InlineDatum, Input, Output, OutputReference, Transaction, TransactionId, +} +use aiken/transaction/credential.{ + Address, PublicKeyCredential, ScriptCredential, StakeCredential, +} +use aiken/transaction/value // MerkleTree in Aiken (ported from: https://github.com/input-output-hk/hydra/blob/master/plutus-merkle-tree/src/Plutus/MerkleTree.hs) @@ -64,3 +73,84 @@ test foo() { let mt = from_list(items) size(mt) == 3 } + +// const keyhash = #"010203040506" + +// const scripthash = #"060504030201" + +// pub fn keyhash_address(with_stake_credential: Option) { +// Address { +// payment_credential: PublicKeyCredential(keyhash), +// stake_credential: with_stake_credential, +// } +// } + +// pub fn scripthash_address(with_stake_credential: Option) { +// Address { +// payment_credential: ScriptCredential(scripthash), +// stake_credential: with_stake_credential, +// } +// } + +// type SampleData { +// a: Int, +// b: ByteArray, +// } + +// pub fn tx_1() -> Transaction { +// let sample_datum = SampleData { a: 1, b: #"01" } +// // let sample_data: Data = sample_datum +// let tx = +// Transaction { +// inputs: [ +// Input { +// output_reference: OutputReference { +// transaction_id: TransactionId { hash: #"" }, +// output_index: 0, +// }, +// output: Output { +// address: scripthash_address(None), +// value: value.zero(), +// datum: InlineDatum(sample_datum), +// reference_script: None, +// }, +// }, +// ], +// reference_inputs: [], +// outputs: [ +// Output { +// address: keyhash_address(None), +// value: value.from_lovelace(10000), +// datum: InlineDatum(sample_datum), +// reference_script: None, +// }, +// ], +// fee: value.zero(), +// mint: value.from_asset(#"000000", #"00", -1), +// certificates: [], +// withdrawals: dict.new(), +// validity_range: Interval { +// lower_bound: IntervalBound { +// bound_type: PositiveInfinity, +// is_inclusive: True, +// }, +// upper_bound: IntervalBound { +// bound_type: PositiveInfinity, +// is_inclusive: True, +// }, +// }, +// extra_signatories: [keyhash], +// redeemers: dict.new(), +// datums: dict.new(), +// id: TransactionId { hash: #"" }, +// } +// tx +// } + +// test some_test2() { +// tx_1() == tx_1() +// } + +test some_test1() { + InlineDatum(Void) == InlineDatum(Void) +}