From 542e39f093e982464eb4963e12be47cad41baede Mon Sep 17 00:00:00 2001 From: Kasey White Date: Tue, 27 Dec 2022 17:29:03 -0500 Subject: [PATCH] feat: finish up zero arg issues with dependencies --- crates/aiken-lang/src/builder.rs | 44 ++++++++++++-------- crates/aiken-lang/src/uplc.rs | 66 ++++++++++++++++++++---------- examples/sample/validators/swap.ak | 9 +++- 3 files changed, 78 insertions(+), 41 deletions(-) diff --git a/crates/aiken-lang/src/builder.rs b/crates/aiken-lang/src/builder.rs index 8afa32d0..9d14177b 100644 --- a/crates/aiken-lang/src/builder.rs +++ b/crates/aiken-lang/src/builder.rs @@ -1346,12 +1346,14 @@ pub fn handle_func_deps_ir( defined_functions: &mut HashMap, func_index_map: &IndexMap>, func_scope: &[u64], + to_be_defined: &mut HashMap, ) { let mut funt_comp = funt_comp.clone(); // deal with function dependencies while let Some(dependency) = funt_comp.dependencies.pop() { let mut insert_var_vec = vec![]; - if defined_functions.contains_key(&dependency) || func_components.get(&dependency).is_none() + if (defined_functions.contains_key(&dependency) && !funt_comp.args.is_empty()) + || func_components.get(&dependency).is_none() { continue; } @@ -1360,27 +1362,28 @@ pub fn handle_func_deps_ir( let dep_scope = func_index_map.get(&dependency).unwrap(); - if get_common_ancestor(dep_scope, func_scope) == func_scope.to_vec() { + if get_common_ancestor(dep_scope, func_scope) == func_scope.to_vec() + || funt_comp.args.is_empty() + { + // we handle zero arg functions and their dependencies in a unique way if !depend_comp.args.is_empty() { funt_comp .dependencies .extend(depend_comp.dependencies.clone()); - } - for (index, ir) in depend_comp.ir.iter().enumerate() { - match_ir_for_recursion( - ir.clone(), - &mut insert_var_vec, - &FunctionAccessKey { - function_name: dependency.function_name.clone(), - module_name: dependency.module_name.clone(), - variant_name: dependency.variant_name.clone(), - }, - index, - ); - } - // we handle zero arg functions and their dependencies in a unique way - if !depend_comp.args.is_empty() { + for (index, ir) in depend_comp.ir.iter().enumerate() { + match_ir_for_recursion( + ir.clone(), + &mut insert_var_vec, + &FunctionAccessKey { + function_name: dependency.function_name.clone(), + module_name: dependency.module_name.clone(), + variant_name: dependency.variant_name.clone(), + }, + index, + ); + } + let mut recursion_ir = depend_comp.ir.clone(); for (index, ir) in insert_var_vec.clone() { recursion_ir.insert(index, ir); @@ -1412,8 +1415,13 @@ pub fn handle_func_deps_ir( temp_ir.append(dep_ir); *dep_ir = temp_ir; - defined_functions.insert(dependency, ()); + if get_common_ancestor(dep_scope, func_scope) == func_scope.to_vec() { + defined_functions.insert(dependency, ()); + } } + } else { + // Dependency will need to be defined somewhere in the main body + to_be_defined.insert(dependency, ()); } } } diff --git a/crates/aiken-lang/src/uplc.rs b/crates/aiken-lang/src/uplc.rs index 96965241..f1a4e800 100644 --- a/crates/aiken-lang/src/uplc.rs +++ b/crates/aiken-lang/src/uplc.rs @@ -86,11 +86,9 @@ impl<'a> CodeGenerator<'a> { let scope = vec![self.id_gen.next()]; self.build_ir(&body, &mut ir_stack, scope); - println!("{ir_stack:#?}"); self.define_ir(&mut ir_stack); - println!("{ir_stack:#?}"); let mut term = self.uplc_code_gen(&mut ir_stack); if self.needs_field_access { @@ -120,7 +118,6 @@ impl<'a> CodeGenerator<'a> { version: (1, 0, 0), term, }; - println!("{}", program.to_pretty()); let mut interner = Interner::new(); @@ -1843,6 +1840,8 @@ impl<'a> CodeGenerator<'a> { ); let mut final_func_dep_ir = IndexMap::new(); + let mut zero_arg_defined_functions = HashMap::new(); + let mut to_be_defined = HashMap::new(); for func in func_index_map.clone() { if self.defined_functions.contains_key(&func.0) { continue; @@ -1852,22 +1851,45 @@ impl<'a> CodeGenerator<'a> { let mut dep_ir = vec![]; - // deal with function dependencies - handle_func_deps_ir( - &mut dep_ir, - funt_comp, - &func_components, - &mut self.defined_functions, - &func_index_map, - func_scope, - ); - if !funt_comp.args.is_empty() { + // deal with function dependencies + handle_func_deps_ir( + &mut dep_ir, + funt_comp, + &func_components, + &mut self.defined_functions, + &func_index_map, + func_scope, + &mut to_be_defined, + ); final_func_dep_ir.insert(func.0, dep_ir); } else { + // since zero arg functions are run at compile time we need to pull all deps + let mut defined_functions = HashMap::new(); + // deal with function dependencies in zero arg functions + handle_func_deps_ir( + &mut dep_ir, + funt_comp, + &func_components, + &mut defined_functions, + &func_index_map, + func_scope, + &mut HashMap::new(), + ); + let mut final_zero_arg_ir = dep_ir; final_zero_arg_ir.extend(funt_comp.ir.clone()); self.zero_arg_functions.insert(func.0, final_zero_arg_ir); + + for (key, val) in defined_functions.into_iter() { + zero_arg_defined_functions.insert(key, val); + } + } + } + + for (key, val) in zero_arg_defined_functions.into_iter() { + if !to_be_defined.contains_key(&key) { + self.defined_functions.insert(key, val); } } @@ -1948,7 +1970,7 @@ impl<'a> CodeGenerator<'a> { fn define_recurse_ir( &mut self, - ir_stack: &mut Vec, + ir_stack: &mut [Air], func_components: &mut IndexMap, func_index_map: &mut IndexMap>, mut recursion_func_map: IndexMap, @@ -1992,7 +2014,13 @@ impl<'a> CodeGenerator<'a> { }) { skip = true; - } else { + } else if func.clone() + == (FunctionAccessKey { + module_name: module.clone(), + function_name: func_name.clone(), + variant_name: variant_name.clone(), + }) + { recursion_func_map_to_add.insert( FunctionAccessKey { module_name: module.clone(), @@ -2040,7 +2068,7 @@ impl<'a> CodeGenerator<'a> { fn process_define_ir( &mut self, - ir_stack: &mut Vec, + ir_stack: &mut [Air], func_components: &mut IndexMap, func_index_map: &mut IndexMap>, ) { @@ -2048,10 +2076,7 @@ impl<'a> CodeGenerator<'a> { for (index, ir) in ir_stack.to_vec().iter().enumerate().rev() { match ir { Air::Var { - scope, - constructor, - name: temp_name, - .. + scope, constructor, .. } => { if let ValueConstructorVariant::ModuleFn { name, @@ -3565,7 +3590,6 @@ impl<'a> CodeGenerator<'a> { .into(), } } else if tipo.is_bool() { - // let term = todo!() } else if tipo.is_string() { Term::Apply { diff --git a/examples/sample/validators/swap.ak b/examples/sample/validators/swap.ak index 2a8b53b2..16a95b3b 100644 --- a/examples/sample/validators/swap.ak +++ b/examples/sample/validators/swap.ak @@ -32,9 +32,9 @@ pub type Dummy { } } -pub fn spend(datum: Datum, redeemer: Redeemer, context: Dummy) -> Bool { +pub fn spending(datum: Datum, redeemer: Redeemer, context: Dummy) -> Bool { let must_say_hello = string.from_bytearray(redeemer.msg) == "Hello, World!" - let must_be_signed = #(1, datum, #(redeemer.msg, context )) + let must_be_signed = #(1, datum, #(redeemer, context )) // context.transaction.extra_signatories // |> list.any(fn(vk) { vk == datum.owner }) @@ -44,4 +44,9 @@ pub fn spend(datum: Datum, redeemer: Redeemer, context: Dummy) -> Bool { } +} + + +test spend_1(){ + spending(Datum{ owner: #[254]}, Redeemer{msg: string.to_bytearray("Hello, World!")}, Mannequin{hands: #[], feet: 2}) == True } \ No newline at end of file