feat: change define_ir_processor to handle code_gen_functions

Also flattened out that function by using let else
This commit is contained in:
Kasey White 2023-04-06 13:30:45 -04:00 committed by Kasey
parent bc7b07c1d9
commit 4ff0504d58
2 changed files with 227 additions and 215 deletions

View File

@ -125,10 +125,6 @@ impl<'a> CodeGenerator<'a> {
let other_term = self.uplc_code_gen(&mut other_ir_stack); let other_term = self.uplc_code_gen(&mut other_ir_stack);
let other_term = other_term.final_wrapper();
let other_term = self.wrap_validator_args(other_term, &other.arguments, true);
let (spend, mint) = if other.arguments.len() > fun.arguments.len() { let (spend, mint) = if other.arguments.len() > fun.arguments.len() {
(other_term, term) (other_term, term)
} else { } else {
@ -2972,244 +2968,237 @@ impl<'a> CodeGenerator<'a> {
) { ) {
let mut to_be_defined_map: IndexMap<FunctionAccessKey, Scope> = IndexMap::new(); let mut to_be_defined_map: IndexMap<FunctionAccessKey, Scope> = IndexMap::new();
for (index, ir) in ir_stack.to_vec().iter().enumerate().rev() { for (index, ir) in ir_stack.to_vec().iter().enumerate().rev() {
match ir { // I tried putting the 2 let else together, but then formatting stopped working
Air::Var { #[rustfmt::skip]
scope, constructor, .. let Air::Var {
} => { scope, constructor, ..
if let ValueConstructorVariant::ModuleFn { } = ir else {
name, let scope = ir.scope();
module,
builtin: None, process_scope_updates(&mut to_be_defined_map, scope, func_index_map);
.. continue;
} = &constructor.variant };
{
let non_variant_function_key = FunctionAccessKey { #[rustfmt::skip]
let ValueConstructorVariant::ModuleFn {name, module, builtin: None, ..} = &constructor.variant else {
let scope = ir.scope();
process_scope_updates(&mut to_be_defined_map, scope, func_index_map);
continue;
};
let non_variant_function_key = FunctionAccessKey {
module_name: module.clone(),
function_name: name.clone(),
variant_name: String::new(),
};
if let Some(function) = self.functions.get(&non_variant_function_key).cloned() {
let mut func_stack = AirStack::with_scope(self.id_gen.clone(), scope.clone());
self.build(&function.body, &mut func_stack);
let func_ir = func_stack.complete();
let param_types = constructor.tipo.arg_types().unwrap();
let mut mono_types: IndexMap<u64, Arc<Type>> = IndexMap::new();
let mut map = mono_types.into_iter().collect_vec();
for (index, arg) in function.arguments.iter().enumerate() {
if arg.tipo.is_generic() {
let param_type = &param_types[index];
map.append(&mut builder::get_generic_id_and_type(&arg.tipo, param_type));
}
}
if function.return_type.is_generic() {
if let Type::Fn { ret, .. } = &*constructor.tipo {
map.append(&mut builder::get_generic_id_and_type(
&function.return_type,
ret,
))
}
}
mono_types = map.into_iter().collect();
let (variant_name, func_ir) =
builder::monomorphize(func_ir, mono_types, &constructor.tipo);
let function_key = FunctionAccessKey {
module_name: module.clone(),
function_name: non_variant_function_key.function_name,
variant_name: variant_name.clone(),
};
ir_stack[index] = Air::Var {
scope: scope.clone(),
constructor: constructor.clone(),
name: name.clone(),
variant_name: variant_name.clone(),
};
if let Some(scope_prev) = to_be_defined_map.get(&function_key) {
let new_scope = scope.common_ancestor(scope_prev);
to_be_defined_map.insert(function_key, new_scope);
} else if func_components.get(&function_key).is_some() {
to_be_defined_map.insert(function_key.clone(), scope.clone());
} else {
to_be_defined_map.insert(function_key.clone(), scope.clone());
let mut func_calls = IndexMap::new();
for ir in func_ir.clone().into_iter() {
let Air::Var { constructor, ..} = ir else {
continue;
};
let ValueConstructorVariant::ModuleFn {
name : func_name, module, builtin: None, ..
} = &constructor.variant
else {
continue;
};
let current_func = FunctionAccessKey {
module_name: module.clone(), module_name: module.clone(),
function_name: name.clone(), function_name: func_name.clone(),
variant_name: String::new(), variant_name: String::new(),
}; };
let function = *self.functions.get(&non_variant_function_key).unwrap(); let current_func_as_variant = FunctionAccessKey {
let mut func_stack =
AirStack::with_scope(self.id_gen.clone(), scope.clone());
self.build(&function.body, &mut func_stack);
let func_ir = func_stack.complete();
let param_types = constructor.tipo.arg_types().unwrap();
let mut mono_types: IndexMap<u64, Arc<Type>> = IndexMap::new();
let mut map = mono_types.into_iter().collect_vec();
for (index, arg) in function.arguments.iter().enumerate() {
if arg.tipo.is_generic() {
let param_type = &param_types[index];
map.append(&mut builder::get_generic_id_and_type(
&arg.tipo, param_type,
));
}
}
if function.return_type.is_generic() {
if let Type::Fn { ret, .. } = &*constructor.tipo {
map.append(&mut builder::get_generic_id_and_type(
&function.return_type,
ret,
))
}
}
mono_types = map.into_iter().collect();
let (variant_name, func_ir) =
builder::monomorphize(func_ir, mono_types, &constructor.tipo);
let function_key = FunctionAccessKey {
module_name: module.clone(), module_name: module.clone(),
function_name: non_variant_function_key.function_name, function_name: func_name.clone(),
variant_name: variant_name.clone(), variant_name: variant_name.clone(),
}; };
ir_stack[index] = Air::Var { let function = self.functions.get(&current_func);
scope: scope.clone(), if function_key.clone() == current_func_as_variant {
constructor: constructor.clone(), func_calls.insert(current_func_as_variant, ());
name: name.clone(), } else if let (Some(function), Type::Fn { .. }) =
variant_name: variant_name.clone(), (function, &*constructor.tipo)
}; {
let param_types = constructor.tipo.arg_types().unwrap();
if let Some(scope_prev) = to_be_defined_map.get(&function_key) { let mut mono_types: IndexMap<u64, Arc<Type>> = IndexMap::new();
let new_scope = scope.common_ancestor(scope_prev); let mut map = mono_types.into_iter().collect_vec();
to_be_defined_map.insert(function_key, new_scope); for (index, arg) in function.arguments.iter().enumerate() {
} else if func_components.get(&function_key).is_some() { if arg.tipo.is_generic() {
to_be_defined_map.insert(function_key.clone(), scope.clone()); let param_type = &param_types[index];
} else {
to_be_defined_map.insert(function_key.clone(), scope.clone());
let mut func_calls = IndexMap::new();
for ir in func_ir.clone().into_iter() { map.append(&mut builder::get_generic_id_and_type(
if let Air::Var { &arg.tipo, param_type,
constructor: ));
ValueConstructor {
variant:
ValueConstructorVariant::ModuleFn {
name: func_name,
module,
..
},
tipo,
..
},
..
} = ir
{
let current_func = FunctionAccessKey {
module_name: module.clone(),
function_name: func_name.clone(),
variant_name: String::new(),
};
let current_func_as_variant = FunctionAccessKey {
module_name: module.clone(),
function_name: func_name.clone(),
variant_name: variant_name.clone(),
};
let function = self.functions.get(&current_func);
if function_key.clone() == current_func_as_variant {
func_calls.insert(current_func_as_variant, ());
} else if let (Some(function), Type::Fn { .. }) =
(function, &*tipo)
{
let param_types = tipo.arg_types().unwrap();
let mut mono_types: IndexMap<u64, Arc<Type>> =
IndexMap::new();
let mut map = mono_types.into_iter().collect_vec();
for (index, arg) in function.arguments.iter().enumerate() {
if arg.tipo.is_generic() {
let param_type = &param_types[index];
map.append(&mut builder::get_generic_id_and_type(
&arg.tipo, param_type,
));
}
}
if function.return_type.is_generic() {
if let Type::Fn { ret, .. } = &*constructor.tipo {
map.append(&mut builder::get_generic_id_and_type(
&function.return_type,
ret,
))
}
}
mono_types = map.into_iter().collect();
let mut func_stack = AirStack::with_scope(
self.id_gen.clone(),
scope.clone(),
);
self.build(&function.body, &mut func_stack);
let temp_ir = func_stack.complete();
let (variant_name, _) =
builder::monomorphize(temp_ir, mono_types, &tipo);
func_calls.insert(
FunctionAccessKey {
module_name: current_func.module_name,
function_name: current_func.function_name,
variant_name,
},
(),
);
} else {
func_calls.insert(current_func, ());
}
} }
} }
let mut args = vec![]; if function.return_type.is_generic() {
if let Type::Fn { ret, .. } = &*constructor.tipo {
for arg in function.arguments.iter() { map.append(&mut builder::get_generic_id_and_type(
match &arg.arg_name { &function.return_type,
ArgName::Named { name, .. } => { ret,
args.push(name.clone()); ))
}
_ => {
args.push("_".to_string());
}
} }
} }
let recursive = if func_calls.get(&function_key).is_some() { mono_types = map.into_iter().collect();
func_calls.remove(&function_key); let mut func_stack =
true AirStack::with_scope(self.id_gen.clone(), scope.clone());
} else {
false
};
func_components.insert( self.build(&function.body, &mut func_stack);
function_key,
FuncComponents { let temp_ir = func_stack.complete();
ir: func_ir,
dependencies: func_calls.keys().cloned().collect_vec(), let (variant_name, _) =
recursive, builder::monomorphize(temp_ir, mono_types, &constructor.tipo);
args,
defined_by_zero_arg: in_zero_arg_func, func_calls.insert(
FunctionAccessKey {
module_name: current_func.module_name,
function_name: current_func.function_name,
variant_name,
}, },
(),
); );
} } else {
} else { func_calls.insert(current_func, ());
for func in to_be_defined_map.clone().iter() {
if scope.common_ancestor(func.1) == scope.clone() {
if let Some(index_scope) = func_index_map.get(func.0) {
if index_scope.common_ancestor(func.1) == scope.clone() {
func_index_map.insert(func.0.clone(), scope.clone());
to_be_defined_map.shift_remove(func.0);
} else {
to_be_defined_map.insert(
func.0.clone(),
index_scope.common_ancestor(func.1),
);
}
} else {
func_index_map.insert(func.0.clone(), scope.clone());
to_be_defined_map.shift_remove(func.0);
}
}
} }
} }
}
a => {
let scope = a.scope();
for func in to_be_defined_map.clone().iter() { let mut args = vec![];
if scope.common_ancestor(func.1) == scope.clone() {
if let Some(index_scope) = func_index_map.get(func.0) { for arg in function.arguments.iter() {
if index_scope.common_ancestor(func.1) == scope.clone() { match &arg.arg_name {
func_index_map.insert(func.0.clone(), scope.clone()); ArgName::Named { name, .. } => {
to_be_defined_map.shift_remove(func.0); args.push(name.clone());
} else { }
to_be_defined_map.insert( _ => {
func.0.clone(), args.push("_".to_string());
index_scope.common_ancestor(func.1),
);
}
} else {
func_index_map.insert(func.0.clone(), scope.clone());
to_be_defined_map.shift_remove(func.0);
} }
} }
} }
let recursive = if func_calls.get(&function_key).is_some() {
func_calls.remove(&function_key);
true
} else {
false
};
func_components.insert(
function_key,
FuncComponents {
ir: func_ir,
dependencies: func_calls.keys().cloned().collect_vec(),
recursive,
args,
defined_by_zero_arg: in_zero_arg_func,
is_code_gen_func: false,
},
);
} }
} else if let Some(code_gen_func) = self.code_gen_functions.get(name).cloned() {
// Get actual code gen func if link
let (func_ir, dependencies) = match code_gen_func {
CodeGenFunction::Function(func_ir, dependencies) => (func_ir, dependencies),
CodeGenFunction::Link(func) => {
if let Some(CodeGenFunction::Function(func_ir, dependencies)) =
self.code_gen_functions.get(&func).cloned()
{
(func_ir, dependencies)
} else {
unreachable!("Link must resolve to a code gen function.");
}
}
};
func_components.insert(
FunctionAccessKey {
module_name: "".to_string(),
function_name: name.to_string(),
variant_name: "".to_string(),
},
FuncComponents {
ir: func_ir,
dependencies: dependencies
.into_iter()
.map(|item| FunctionAccessKey {
module_name: "".to_string(),
function_name: item,
variant_name: "".to_string(),
})
.collect_vec(),
recursive: false,
args: vec![],
defined_by_zero_arg: in_zero_arg_func,
is_code_gen_func: true,
},
);
} else {
unreachable!("We found a function with no definitions");
} }
} }
@ -4978,3 +4967,25 @@ impl<'a> CodeGenerator<'a> {
term term
} }
} }
fn process_scope_updates(
to_be_defined_map: &mut IndexMap<FunctionAccessKey, Scope>,
scope: Scope,
func_index_map: &mut IndexMap<FunctionAccessKey, Scope>,
) {
for func in to_be_defined_map.clone().iter() {
if scope.common_ancestor(func.1) == scope.clone() {
if let Some(index_scope) = func_index_map.get(func.0) {
if index_scope.common_ancestor(func.1) == scope.clone() {
func_index_map.insert(func.0.clone(), scope.clone());
to_be_defined_map.shift_remove(func.0);
} else {
to_be_defined_map.insert(func.0.clone(), index_scope.common_ancestor(func.1));
}
} else {
func_index_map.insert(func.0.clone(), scope.clone());
to_be_defined_map.shift_remove(func.0);
}
}
}
}

View File

@ -32,6 +32,7 @@ pub struct FuncComponents {
pub args: Vec<String>, pub args: Vec<String>,
pub recursive: bool, pub recursive: bool,
pub defined_by_zero_arg: bool, pub defined_by_zero_arg: bool,
pub is_code_gen_func: bool,
} }
#[derive(Clone, Eq, Debug, PartialEq, Hash)] #[derive(Clone, Eq, Debug, PartialEq, Hash)]