feat: finish up zero arg issues with dependencies

This commit is contained in:
Kasey White 2022-12-27 17:29:03 -05:00 committed by Lucas
parent 30487cc232
commit 542e39f093
3 changed files with 78 additions and 41 deletions

View File

@ -1346,12 +1346,14 @@ pub fn handle_func_deps_ir(
defined_functions: &mut HashMap<FunctionAccessKey, ()>, defined_functions: &mut HashMap<FunctionAccessKey, ()>,
func_index_map: &IndexMap<FunctionAccessKey, Vec<u64>>, func_index_map: &IndexMap<FunctionAccessKey, Vec<u64>>,
func_scope: &[u64], func_scope: &[u64],
to_be_defined: &mut HashMap<FunctionAccessKey, ()>,
) { ) {
let mut funt_comp = funt_comp.clone(); let mut funt_comp = funt_comp.clone();
// deal with function dependencies // deal with function dependencies
while let Some(dependency) = funt_comp.dependencies.pop() { while let Some(dependency) = funt_comp.dependencies.pop() {
let mut insert_var_vec = vec![]; 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; continue;
} }
@ -1360,12 +1362,14 @@ pub fn handle_func_deps_ir(
let dep_scope = func_index_map.get(&dependency).unwrap(); 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() { if !depend_comp.args.is_empty() {
funt_comp funt_comp
.dependencies .dependencies
.extend(depend_comp.dependencies.clone()); .extend(depend_comp.dependencies.clone());
}
for (index, ir) in depend_comp.ir.iter().enumerate() { for (index, ir) in depend_comp.ir.iter().enumerate() {
match_ir_for_recursion( match_ir_for_recursion(
@ -1379,8 +1383,7 @@ pub fn handle_func_deps_ir(
index, index,
); );
} }
// we handle zero arg functions and their dependencies in a unique way
if !depend_comp.args.is_empty() {
let mut recursion_ir = depend_comp.ir.clone(); let mut recursion_ir = depend_comp.ir.clone();
for (index, ir) in insert_var_vec.clone() { for (index, ir) in insert_var_vec.clone() {
recursion_ir.insert(index, ir); recursion_ir.insert(index, ir);
@ -1412,8 +1415,13 @@ pub fn handle_func_deps_ir(
temp_ir.append(dep_ir); temp_ir.append(dep_ir);
*dep_ir = temp_ir; *dep_ir = temp_ir;
if get_common_ancestor(dep_scope, func_scope) == func_scope.to_vec() {
defined_functions.insert(dependency, ()); defined_functions.insert(dependency, ());
} }
} }
} else {
// Dependency will need to be defined somewhere in the main body
to_be_defined.insert(dependency, ());
}
} }
} }

View File

@ -86,11 +86,9 @@ impl<'a> CodeGenerator<'a> {
let scope = vec![self.id_gen.next()]; let scope = vec![self.id_gen.next()];
self.build_ir(&body, &mut ir_stack, scope); self.build_ir(&body, &mut ir_stack, scope);
println!("{ir_stack:#?}");
self.define_ir(&mut ir_stack); self.define_ir(&mut ir_stack);
println!("{ir_stack:#?}");
let mut term = self.uplc_code_gen(&mut ir_stack); let mut term = self.uplc_code_gen(&mut ir_stack);
if self.needs_field_access { if self.needs_field_access {
@ -120,7 +118,6 @@ impl<'a> CodeGenerator<'a> {
version: (1, 0, 0), version: (1, 0, 0),
term, term,
}; };
println!("{}", program.to_pretty());
let mut interner = Interner::new(); let mut interner = Interner::new();
@ -1843,6 +1840,8 @@ impl<'a> CodeGenerator<'a> {
); );
let mut final_func_dep_ir = IndexMap::new(); 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() { for func in func_index_map.clone() {
if self.defined_functions.contains_key(&func.0) { if self.defined_functions.contains_key(&func.0) {
continue; continue;
@ -1852,6 +1851,7 @@ impl<'a> CodeGenerator<'a> {
let mut dep_ir = vec![]; let mut dep_ir = vec![];
if !funt_comp.args.is_empty() {
// deal with function dependencies // deal with function dependencies
handle_func_deps_ir( handle_func_deps_ir(
&mut dep_ir, &mut dep_ir,
@ -1860,14 +1860,36 @@ impl<'a> CodeGenerator<'a> {
&mut self.defined_functions, &mut self.defined_functions,
&func_index_map, &func_index_map,
func_scope, func_scope,
&mut to_be_defined,
); );
if !funt_comp.args.is_empty() {
final_func_dep_ir.insert(func.0, dep_ir); final_func_dep_ir.insert(func.0, dep_ir);
} else { } 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; let mut final_zero_arg_ir = dep_ir;
final_zero_arg_ir.extend(funt_comp.ir.clone()); final_zero_arg_ir.extend(funt_comp.ir.clone());
self.zero_arg_functions.insert(func.0, final_zero_arg_ir); 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( fn define_recurse_ir(
&mut self, &mut self,
ir_stack: &mut Vec<Air>, ir_stack: &mut [Air],
func_components: &mut IndexMap<FunctionAccessKey, FuncComponents>, func_components: &mut IndexMap<FunctionAccessKey, FuncComponents>,
func_index_map: &mut IndexMap<FunctionAccessKey, Vec<u64>>, func_index_map: &mut IndexMap<FunctionAccessKey, Vec<u64>>,
mut recursion_func_map: IndexMap<FunctionAccessKey, ()>, mut recursion_func_map: IndexMap<FunctionAccessKey, ()>,
@ -1992,7 +2014,13 @@ impl<'a> CodeGenerator<'a> {
}) })
{ {
skip = true; 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( recursion_func_map_to_add.insert(
FunctionAccessKey { FunctionAccessKey {
module_name: module.clone(), module_name: module.clone(),
@ -2040,7 +2068,7 @@ impl<'a> CodeGenerator<'a> {
fn process_define_ir( fn process_define_ir(
&mut self, &mut self,
ir_stack: &mut Vec<Air>, ir_stack: &mut [Air],
func_components: &mut IndexMap<FunctionAccessKey, FuncComponents>, func_components: &mut IndexMap<FunctionAccessKey, FuncComponents>,
func_index_map: &mut IndexMap<FunctionAccessKey, Vec<u64>>, func_index_map: &mut IndexMap<FunctionAccessKey, Vec<u64>>,
) { ) {
@ -2048,10 +2076,7 @@ impl<'a> CodeGenerator<'a> {
for (index, ir) in ir_stack.to_vec().iter().enumerate().rev() { for (index, ir) in ir_stack.to_vec().iter().enumerate().rev() {
match ir { match ir {
Air::Var { Air::Var {
scope, scope, constructor, ..
constructor,
name: temp_name,
..
} => { } => {
if let ValueConstructorVariant::ModuleFn { if let ValueConstructorVariant::ModuleFn {
name, name,
@ -3565,7 +3590,6 @@ impl<'a> CodeGenerator<'a> {
.into(), .into(),
} }
} else if tipo.is_bool() { } else if tipo.is_bool() {
// let term =
todo!() todo!()
} else if tipo.is_string() { } else if tipo.is_string() {
Term::Apply { Term::Apply {

View File

@ -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_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 // context.transaction.extra_signatories
// |> list.any(fn(vk) { vk == datum.owner }) // |> list.any(fn(vk) { vk == datum.owner })
@ -45,3 +45,8 @@ 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
}