zero arg functions now work: test 15

This commit is contained in:
Kasey White 2022-12-17 22:01:20 -05:00 committed by Lucas
parent 3a765ddef5
commit 421e7148d0
3 changed files with 189 additions and 114 deletions

View File

@ -1,5 +1,6 @@
use std::{cell::RefCell, collections::HashMap, sync::Arc}; use std::{cell::RefCell, collections::HashMap, sync::Arc};
use indexmap::IndexMap;
use itertools::Itertools; use itertools::Itertools;
use uplc::{ use uplc::{
ast::{Constant as UplcConstant, Name, Term, Type as UplcType}, ast::{Constant as UplcConstant, Name, Term, Type as UplcType},
@ -1195,3 +1196,82 @@ pub fn monomorphize(
(new_name, new_air) (new_name, new_air)
} }
pub fn handle_func_deps_ir(
dep_ir: &mut Vec<Air>,
funt_comp: &FuncComponents,
func_components: &IndexMap<FunctionAccessKey, FuncComponents>,
defined_functions: &mut HashMap<FunctionAccessKey, ()>,
func_index_map: &IndexMap<FunctionAccessKey, Vec<u64>>,
func_scope: &[u64],
) {
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()
{
continue;
}
let depend_comp = func_components.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 !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() {
let mut recursion_ir = depend_comp.ir.clone();
for (index, ir) in insert_var_vec.clone() {
recursion_ir.insert(index, ir);
let current_call = recursion_ir[index - 1].clone();
match current_call {
Air::Call { scope, count } => {
recursion_ir[index - 1] = Air::Call {
scope,
count: count + 1,
}
}
_ => unreachable!(),
}
}
let mut temp_ir = vec![Air::DefineFunc {
scope: func_scope.to_vec(),
func_name: dependency.function_name.clone(),
module_name: dependency.module_name.clone(),
params: depend_comp.args.clone(),
recursive: depend_comp.recursive,
variant_name: dependency.variant_name.clone(),
}];
temp_ir.append(&mut recursion_ir);
temp_ir.append(dep_ir);
*dep_ir = temp_ir;
defined_functions.insert(dependency, ());
}
}
}
}

View File

@ -8,9 +8,10 @@ use uplc::{
self, constr_index_exposer, delayed_if_else, if_else, CONSTR_FIELDS_EXPOSER, self, constr_index_exposer, delayed_if_else, if_else, CONSTR_FIELDS_EXPOSER,
CONSTR_GET_FIELD, CONSTR_GET_FIELD,
}, },
Constant as UplcConstant, Name, Program, Term, Type as UplcType, Constant as UplcConstant, Name, NamedDeBruijn, Program, Term, Type as UplcType,
}, },
builtins::DefaultFunction, builtins::DefaultFunction,
machine::cost_model::ExBudget,
parser::interner::Interner, parser::interner::Interner,
}; };
@ -23,8 +24,8 @@ use crate::{
builder::{ builder::{
check_when_pattern_needs, constants_ir, convert_constants_to_data, convert_data_to_type, check_when_pattern_needs, constants_ir, convert_constants_to_data, convert_data_to_type,
convert_type_to_data, get_common_ancestor, get_generics_and_type, get_variant_name, convert_type_to_data, get_common_ancestor, get_generics_and_type, get_variant_name,
list_access_to_uplc, match_ir_for_recursion, monomorphize, rearrange_clauses, handle_func_deps_ir, list_access_to_uplc, match_ir_for_recursion, monomorphize,
ClauseProperties, DataTypeKey, FuncComponents, FunctionAccessKey, rearrange_clauses, ClauseProperties, DataTypeKey, FuncComponents, FunctionAccessKey,
}, },
expr::TypedExpr, expr::TypedExpr,
tipo::{self, PatternConstructor, Type, TypeInfo, ValueConstructor, ValueConstructorVariant}, tipo::{self, PatternConstructor, Type, TypeInfo, ValueConstructor, ValueConstructorVariant},
@ -41,6 +42,7 @@ pub struct CodeGenerator<'a> {
module_types: &'a HashMap<String, TypeInfo>, module_types: &'a HashMap<String, TypeInfo>,
id_gen: IdGenerator, id_gen: IdGenerator,
needs_field_access: bool, needs_field_access: bool,
zero_arg_functions: HashMap<FunctionAccessKey, Vec<Air>>,
} }
impl<'a> CodeGenerator<'a> { impl<'a> CodeGenerator<'a> {
@ -62,6 +64,7 @@ impl<'a> CodeGenerator<'a> {
module_types, module_types,
id_gen: IdGenerator::new(), id_gen: IdGenerator::new(),
needs_field_access: false, needs_field_access: false,
zero_arg_functions: HashMap::new(),
} }
} }
@ -1470,128 +1473,71 @@ impl<'a> CodeGenerator<'a> {
recursion_func_map, recursion_func_map,
); );
let mut insert_var_vec = vec![];
let mut final_func_dep_ir = IndexMap::new(); let mut final_func_dep_ir = IndexMap::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;
} }
let mut funt_comp = func_components.get(&func.0).unwrap().clone(); let funt_comp = func_components.get(&func.0).unwrap();
let func_scope = func_index_map.get(&func.0).unwrap(); let func_scope = func_index_map.get(&func.0).unwrap();
let mut dep_ir = vec![]; let mut dep_ir = vec![];
// deal with function dependencies // deal with function dependencies
while let Some(dependency) = funt_comp.dependencies.pop() { handle_func_deps_ir(
if self.defined_functions.contains_key(&dependency) &mut dep_ir,
|| func_components.get(&dependency).is_none() funt_comp,
{ &func_components,
continue; &mut self.defined_functions,
} &func_index_map,
func_scope,
let depend_comp = func_components.get(&dependency).unwrap();
let dep_scope = func_index_map.get(&dependency).unwrap();
if get_common_ancestor(dep_scope, func_scope) == func_scope.clone() {
funt_comp
.dependencies
.extend(depend_comp.dependencies.clone());
let mut temp_ir = vec![Air::DefineFunc {
scope: func_scope.clone(),
func_name: dependency.function_name.clone(),
module_name: dependency.module_name.clone(),
params: depend_comp.args.clone(),
recursive: depend_comp.recursive,
variant_name: dependency.variant_name.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,
); );
}
let mut recursion_ir = depend_comp.ir.clone();
for (index, ir) in insert_var_vec.clone() {
recursion_ir.insert(index, ir);
let current_call = recursion_ir[index - 1].clone();
match current_call {
Air::Call { scope, count } => {
recursion_ir[index - 1] = Air::Call {
scope,
count: count + 1,
}
}
_ => unreachable!(),
}
}
temp_ir.append(&mut recursion_ir);
temp_ir.append(&mut dep_ir);
dep_ir = temp_ir;
self.defined_functions.insert(dependency, ());
insert_var_vec = vec![];
}
}
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 {
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 (index, ir) in ir_stack.clone().into_iter().enumerate().rev() { for (index, ir) in ir_stack.clone().into_iter().enumerate().rev() {
{ {
let temp_func_index_map = func_index_map.clone(); let temp_func_index_map = func_index_map.clone();
let to_insert = temp_func_index_map let to_insert = temp_func_index_map
.iter() .into_iter()
.filter(|func| { .filter(|func| {
get_common_ancestor(func.1, &ir.scope()) == ir.scope() get_common_ancestor(&func.1, &ir.scope()) == ir.scope()
&& !self.defined_functions.contains_key(func.0) && !self.defined_functions.contains_key(&func.0)
&& !self.zero_arg_functions.contains_key(&func.0)
}) })
.collect_vec(); .collect_vec();
for (function_access_key, scopes) in to_insert.into_iter() { for (function_access_key, scopes) in to_insert.into_iter() {
func_index_map.remove(function_access_key); let mut insert_var_vec = vec![];
func_index_map.remove(&function_access_key);
self.defined_functions self.defined_functions
.insert(function_access_key.clone(), ()); .insert(function_access_key.clone(), ());
let mut full_func_ir = let mut full_func_ir =
final_func_dep_ir.get(function_access_key).unwrap().clone(); final_func_dep_ir.get(&function_access_key).unwrap().clone();
let mut func_comp = func_components.get(function_access_key).unwrap().clone();
full_func_ir.push(Air::DefineFunc {
scope: scopes.clone(),
func_name: function_access_key.function_name.clone(),
module_name: function_access_key.module_name.clone(),
params: func_comp.args.clone(),
recursive: func_comp.recursive,
variant_name: function_access_key.variant_name.clone(),
});
let mut func_comp = func_components.get(&function_access_key).unwrap().clone();
// zero arg functions are not recursive
if !func_comp.args.is_empty() {
for (index, ir) in func_comp.ir.clone().iter().enumerate().rev() { for (index, ir) in func_comp.ir.clone().iter().enumerate().rev() {
match_ir_for_recursion( match_ir_for_recursion(
ir.clone(), ir.clone(),
&mut insert_var_vec, &mut insert_var_vec,
function_access_key, &function_access_key,
index, index,
); );
} }
for (index, ir) in insert_var_vec { for (index, ir) in insert_var_vec {
func_comp.ir.insert(index, ir); func_comp.ir.insert(index, ir.clone());
let current_call = func_comp.ir[index - 1].clone(); let current_call = func_comp.ir[index - 1].clone();
@ -1605,13 +1551,27 @@ impl<'a> CodeGenerator<'a> {
_ => unreachable!("{current_call:#?}"), _ => unreachable!("{current_call:#?}"),
} }
} }
insert_var_vec = vec![];
full_func_ir.push(Air::DefineFunc {
scope: scopes.clone(),
func_name: function_access_key.function_name.clone(),
module_name: function_access_key.module_name.clone(),
params: func_comp.args.clone(),
recursive: func_comp.recursive,
variant_name: function_access_key.variant_name.clone(),
});
full_func_ir.extend(func_comp.ir.clone()); full_func_ir.extend(func_comp.ir.clone());
for ir in full_func_ir.into_iter().rev() { for ir in full_func_ir.into_iter().rev() {
ir_stack.insert(index, ir); ir_stack.insert(index, ir);
} }
} else {
full_func_ir.extend(func_comp.ir.clone());
self.zero_arg_functions
.insert(function_access_key, full_func_ir);
}
} }
} }
} }
@ -2402,7 +2362,43 @@ impl<'a> CodeGenerator<'a> {
} }
arg_stack.push(term); arg_stack.push(term);
} else { } else {
todo!() let term = arg_stack.pop().unwrap();
let zero_arg_functions = self.zero_arg_functions.clone();
if let Term::Var(Name { text, .. }) = term {
for (
FunctionAccessKey {
module_name,
function_name,
variant_name,
},
ir,
) in zero_arg_functions.into_iter()
{
let name_module =
format!("{module_name}_{function_name}{variant_name}");
let name = format!("{function_name}{variant_name}");
if text == name || text == name_module {
let mut program: Program<Name> = Program {
version: (1, 0, 0),
term: self.uplc_code_gen(&mut ir.clone()),
};
let mut interner = Interner::new();
interner.program(&mut program);
let eval_program: Program<NamedDeBruijn> =
program.try_into().unwrap();
let evaluated_term: Term<NamedDeBruijn> =
eval_program.eval(ExBudget::default()).0.unwrap();
arg_stack.push(evaluated_term.try_into().unwrap());
}
}
}
} }
} }
Air::Builtin { func, tipo, .. } => match func { Air::Builtin { func, tipo, .. } => match func {

View File

@ -6,7 +6,6 @@ pub fn new() {
Map { inner: [] } Map { inner: [] }
} }
// Seems to be an issue with the parser. The TypedExpr body is excluding the Equal binop.
test new_1() { test new_1() {
new() == Map { inner: [] } new() == Map { inner: [] }
} }