diff --git a/crates/aiken-lang/src/gen_uplc.rs b/crates/aiken-lang/src/gen_uplc.rs index 0e0a69b9..f0fb2792 100644 --- a/crates/aiken-lang/src/gen_uplc.rs +++ b/crates/aiken-lang/src/gen_uplc.rs @@ -2519,7 +2519,8 @@ impl<'a> CodeGenerator<'a> { let mut data_type_variant = String::new(); if let Some(types) = tipo.arg_types() { - for tipo in types { + for mut tipo in types { + replace_opaque_type(&mut tipo, &self.data_types); get_variant_name(&mut data_type_variant, &tipo); } } @@ -3178,7 +3179,7 @@ impl<'a> CodeGenerator<'a> { mono_types = map.into_iter().collect(); let (variant_name, func_ir) = - builder::monomorphize(func_ir, mono_types, &constructor.tipo); + builder::monomorphize(func_ir, mono_types, &constructor.tipo, &self.data_types); let function_key = FunctionAccessKey { module_name: module.clone(), @@ -3264,8 +3265,12 @@ impl<'a> CodeGenerator<'a> { let temp_ir = func_stack.complete(); - let (variant_name, _) = - builder::monomorphize(temp_ir, mono_types, &constructor.tipo); + let (variant_name, _) = builder::monomorphize( + temp_ir, + mono_types, + &constructor.tipo, + &self.data_types, + ); func_calls.insert( FunctionAccessKey { diff --git a/crates/aiken-lang/src/gen_uplc/builder.rs b/crates/aiken-lang/src/gen_uplc/builder.rs index 634d5709..e20cca77 100644 --- a/crates/aiken-lang/src/gen_uplc/builder.rs +++ b/crates/aiken-lang/src/gen_uplc/builder.rs @@ -929,17 +929,12 @@ pub fn get_variant_name(new_name: &mut String, t: &Arc) { } else if t.is_unbound() { "_unbound".to_string() } else { - let mut full_type = "_data".to_string(); + let full_type = "_data".to_string(); if t.is_generic() { panic!("FOUND A POLYMORPHIC TYPE. EXPECTED MONOMORPHIC TYPE"); } - let inner_types = t.get_inner_types(); - - for arg_type in inner_types { - get_variant_name(&mut full_type, &arg_type); - } full_type }); } @@ -1061,6 +1056,7 @@ pub fn monomorphize( ir: Vec, mono_types: IndexMap>, full_type: &Arc, + data_types: &IndexMap, ) -> (String, Vec) { let mut new_air = ir.clone(); let mut new_name = String::new(); @@ -1084,14 +1080,19 @@ pub fn monomorphize( let mut constructor = constructor.clone(); constructor.tipo = tipo; - if let Type::Fn { args, .. } = &*constructor.tipo { + if let Type::Fn { args, ret } = &*constructor.tipo { if matches!( constructor.variant, ValueConstructorVariant::ModuleFn { .. } ) { for arg in args { - get_variant_name(&mut variant, arg); + let mut arg = arg.clone(); + replace_opaque_type(&mut arg, data_types); + get_variant_name(&mut variant, &arg); } + let mut ret = ret.clone(); + replace_opaque_type(&mut ret, data_types); + get_variant_name(&mut variant, &ret); } } new_air[index] = Air::Var { @@ -1500,11 +1501,16 @@ pub fn monomorphize( } } - if let Type::Fn { args, .. } = &**full_type { + if let Type::Fn { args, ret } = &**full_type { if needs_variant { for arg in args { - get_variant_name(&mut new_name, arg); + let mut arg = arg.clone(); + replace_opaque_type(&mut arg, data_types); + get_variant_name(&mut new_name, &arg); } + let mut ret = ret.clone(); + replace_opaque_type(&mut ret, data_types); + get_variant_name(&mut new_name, &ret) } } diff --git a/examples/acceptance_tests/083/aiken.lock b/examples/acceptance_tests/083/aiken.lock new file mode 100644 index 00000000..0423f31b --- /dev/null +++ b/examples/acceptance_tests/083/aiken.lock @@ -0,0 +1,13 @@ +# This file was generated by Aiken +# You typically do not need to edit this file + +[[requirements]] +name = "aiken-lang/stdlib" +version = "main" +source = "github" + +[[packages]] +name = "aiken-lang/stdlib" +version = "main" +requirements = [] +source = "github" diff --git a/examples/acceptance_tests/083/aiken.toml b/examples/acceptance_tests/083/aiken.toml new file mode 100644 index 00000000..1d26e775 --- /dev/null +++ b/examples/acceptance_tests/083/aiken.toml @@ -0,0 +1,8 @@ +name = "aiken-lang/acceptance_test_083" +version = "0.0.0" +description = "" + +[[dependencies]] +name = 'aiken-lang/stdlib' +version = 'main' +source = 'github' diff --git a/examples/acceptance_tests/083/lib/tests.ak b/examples/acceptance_tests/083/lib/tests.ak new file mode 100644 index 00000000..78c0ed60 --- /dev/null +++ b/examples/acceptance_tests/083/lib/tests.ak @@ -0,0 +1,112 @@ +use aiken/bytearray +use aiken/dict.{Dict} +use aiken/int +use aiken/list +use aiken/transaction.{OutputReference, TransactionId} +use aiken/transaction/credential.{Address, VerificationKeyCredential} +use aiken/transaction/value.{AssetName, PolicyId, Value} + +fn compare_out_ref(ref1: OutputReference, ref2: OutputReference) -> Ordering { + let OutputReference(TransactionId(tx_id1), out_index1) = ref1 + let OutputReference(TransactionId(tx_id2), out_index2) = ref2 + when bytearray.compare(tx_id1, tx_id2) is { + Less -> Less + Greater -> Greater + Equal -> int.compare(out_index1, out_index2) + } +} + +// Compare two values based on a specific asset. Ordering doesn't matter; they just shouldn't +// be equal. +fn compare_value( + loan_id: AssetName, + sym: PolicyId, + val1: Value, + val2: Value, +) -> Ordering { + if + value.quantity_of(val1, sym, loan_id) == value.quantity_of(val2, sym, loan_id){ + + error @"Should not be equal" + } else { + Less + } +} + +test dict_test1() { + let offer_input_ref = OutputReference(TransactionId("00"), 0) + let ask_input_ref = OutputReference(TransactionId("00"), 1) + let pairings = + [(ask_input_ref, offer_input_ref)] + + let (ask_map, asize, offer_map, osize) = + ( + dict.from_list([(ask_input_ref, transaction.NoDatum)], compare_out_ref), + 1, + dict.from_list([(offer_input_ref, transaction.NoDatum)], compare_out_ref), + 1, + ) + + (ask_map, asize, offer_map, osize) == ( + dict.from_list([(ask_input_ref, transaction.NoDatum)], compare_out_ref), + 1, + dict.from_list([(offer_input_ref, transaction.NoDatum)], compare_out_ref), + 1, + ) +} + +// test dict_test2() { +// let offer_input_ref = OutputReference(TransactionId("00"), 0) +// let ask_input_ref = OutputReference(TransactionId("00"), 1) +// let pairings = +// [(ask_input_ref, offer_input_ref)] + +// let foo = +// fn(pair: (OutputReference, OutputReference), acc: Dict) { +// let new_pay_map = +// dict.insert( +// acc, +// value.zero(), +// Address(VerificationKeyCredential("00"), None), +// compare_value("", "", _, _), +// ) + +// new_pay_map +// } + +// let pay_map = list.foldl(pairings, dict.new(), foo) + +// pay_map == dict.new() +// } + +// test dict_test3() { +// let offer_input_ref = OutputReference(TransactionId("00"), 0) +// let ask_input_ref = OutputReference(TransactionId("00"), 1) +// let pairings = +// [(ask_input_ref, offer_input_ref)] + +// let (ask_map, asize, offer_map, osize) = +// ( +// dict.from_list([(ask_input_ref, transaction.NoDatum)], compare_out_ref), +// 1, +// dict.from_list([(offer_input_ref, transaction.NoDatum)], compare_out_ref), +// 1, +// ) + +// let foo = +// fn(pair: (OutputReference, OutputReference), acc: Dict) { +// let new_pay_map = +// dict.insert( +// acc, +// value.zero(), +// Address(VerificationKeyCredential("00"), None), +// compare_value("", "", _, _), +// ) + +// new_pay_map +// } + +// let pay_map = list.foldl(pairings, dict.new(), foo) + +// pay_map == dict.new() +// }