Feat: generic function call tests work

This commit is contained in:
Kasey White 2022-12-11 19:40:28 -05:00 committed by KtorZ
parent e4d9ca4586
commit 15dc202810
No known key found for this signature in database
GPG Key ID: 33173CB6F77F4277
4 changed files with 111 additions and 62 deletions

View File

@ -28,6 +28,7 @@ pub enum Air {
scope: Vec<u64>, scope: Vec<u64>,
constructor: ValueConstructor, constructor: ValueConstructor,
name: String, name: String,
variant_name: String,
}, },
// Fn { // Fn {
@ -88,6 +89,7 @@ pub enum Air {
module_name: String, module_name: String,
params: Vec<String>, params: Vec<String>,
recursive: bool, recursive: bool,
variant_name: String,
}, },
DefineConst { DefineConst {

View File

@ -159,12 +159,7 @@ impl Type {
pub fn is_generic(&self) -> bool { pub fn is_generic(&self) -> bool {
match self { match self {
Type::App { Type::App { args, .. } => {
public,
module,
name,
args,
} => {
let mut is_a_generic = false; let mut is_a_generic = false;
for arg in args { for arg in args {
is_a_generic = is_a_generic || arg.is_generic(); is_a_generic = is_a_generic || arg.is_generic();

View File

@ -50,6 +50,7 @@ pub type ConstrUsageKey = String;
pub struct FunctionAccessKey { pub struct FunctionAccessKey {
pub module_name: String, pub module_name: String,
pub function_name: String, pub function_name: String,
pub variant_name: String,
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -182,6 +183,7 @@ impl<'a> CodeGenerator<'a> {
scope, scope,
constructor: constructor.clone(), constructor: constructor.clone(),
name: name.clone(), name: name.clone(),
variant_name: String::new(),
}); });
} }
} }
@ -194,11 +196,7 @@ impl<'a> CodeGenerator<'a> {
} => { } => {
ir_stack.push(Air::List { ir_stack.push(Air::List {
scope: scope.clone(), scope: scope.clone(),
count: if tail.is_some() { count: elements.len(),
elements.len() + 1
} else {
elements.len()
},
tipo: tipo.clone(), tipo: tipo.clone(),
tail: tail.is_some(), tail: tail.is_some(),
}); });
@ -219,7 +217,7 @@ impl<'a> CodeGenerator<'a> {
TypedExpr::Call { fun, args, .. } => { TypedExpr::Call { fun, args, .. } => {
ir_stack.push(Air::Call { ir_stack.push(Air::Call {
scope: scope.clone(), scope: scope.clone(),
count: args.len() + 1, count: args.len(),
}); });
let mut scope_fun = scope.clone(); let mut scope_fun = scope.clone();
scope_fun.push(self.id_gen.next()); scope_fun.push(self.id_gen.next());
@ -412,6 +410,7 @@ impl<'a> CodeGenerator<'a> {
}, },
), ),
name: constr_var, name: constr_var,
variant_name: String::new(),
}) })
} else { } else {
ir_stack.push(Air::When { ir_stack.push(Air::When {
@ -486,6 +485,7 @@ impl<'a> CodeGenerator<'a> {
let func = self.functions.get(&FunctionAccessKey { let func = self.functions.get(&FunctionAccessKey {
module_name: module_name.clone(), module_name: module_name.clone(),
function_name: name.clone(), function_name: name.clone(),
variant_name: String::new(),
}); });
if let Some(func) = func { if let Some(func) = func {
@ -503,6 +503,7 @@ impl<'a> CodeGenerator<'a> {
}, },
), ),
name: format!("{module}_{name}"), name: format!("{module}_{name}"),
variant_name: String::new(),
}); });
} else { } else {
let type_info = self.module_types.get(module_name).unwrap(); let type_info = self.module_types.get(module_name).unwrap();
@ -590,6 +591,7 @@ impl<'a> CodeGenerator<'a> {
}, },
), ),
name: clause_properties.original_subject_name.clone(), name: clause_properties.original_subject_name.clone(),
variant_name: String::new(),
}); });
pattern_vec.append(values); pattern_vec.append(values);
} }
@ -609,6 +611,7 @@ impl<'a> CodeGenerator<'a> {
}, },
), ),
name: clause_properties.original_subject_name.clone(), name: clause_properties.original_subject_name.clone(),
variant_name: String::new(),
}); });
new_vec.append(values); new_vec.append(values);
@ -706,6 +709,7 @@ impl<'a> CodeGenerator<'a> {
), ),
name: clause_properties.clause_var_name.clone(), name: clause_properties.clause_var_name.clone(),
scope: scope.clone(), scope: scope.clone(),
variant_name: String::new(),
}]; }];
// if only one constructor, no need to check // if only one constructor, no need to check
@ -1171,6 +1175,7 @@ impl<'a> CodeGenerator<'a> {
), ),
name: item_name, name: item_name,
scope: scope.clone(), scope: scope.clone(),
variant_name: String::new(),
}); });
self.pattern_ir( self.pattern_ir(
a, a,
@ -1277,6 +1282,7 @@ impl<'a> CodeGenerator<'a> {
}, },
), ),
name: constr_name.clone(), name: constr_name.clone(),
variant_name: String::new(),
}], }],
tipo, tipo,
scope.clone(), scope.clone(),
@ -1342,6 +1348,7 @@ impl<'a> CodeGenerator<'a> {
}, },
), ),
name: constr_name.clone(), name: constr_name.clone(),
variant_name: String::new(),
}], }],
tipo, tipo,
scope.clone(), scope.clone(),
@ -1404,6 +1411,7 @@ impl<'a> CodeGenerator<'a> {
), ),
name: item_name, name: item_name,
scope: scope.clone(), scope: scope.clone(),
variant_name: String::new(),
}); });
self.pattern_ir( self.pattern_ir(
a, a,
@ -1439,6 +1447,8 @@ impl<'a> CodeGenerator<'a> {
} }
fn gen_uplc(&mut self, ir: Air, arg_stack: &mut Vec<Term<Name>>) { fn gen_uplc(&mut self, ir: Air, arg_stack: &mut Vec<Term<Name>>) {
// println!("IR IS {ir:#?} AND ARG STACK IS {arg_stack:#?}");
match ir { match ir {
Air::Int { value, .. } => { Air::Int { value, .. } => {
let integer = value.parse().unwrap(); let integer = value.parse().unwrap();
@ -1457,7 +1467,10 @@ impl<'a> CodeGenerator<'a> {
arg_stack.push(term); arg_stack.push(term);
} }
Air::Var { Air::Var {
name, constructor, .. name,
constructor,
variant_name,
..
} => { } => {
match constructor.variant { match constructor.variant {
ValueConstructorVariant::LocalVariable { .. } => { ValueConstructorVariant::LocalVariable { .. } => {
@ -1475,10 +1488,11 @@ impl<'a> CodeGenerator<'a> {
.. ..
} => { } => {
let name = if func_name == name { let name = if func_name == name {
format!("{module}_{func_name}") format!("{module}_{func_name}{variant_name}")
} else { } else {
name format!("{func_name}{variant_name}")
}; };
arg_stack.push(Term::Var(Name { arg_stack.push(Term::Var(Name {
text: name, text: name,
unique: 0.into(), unique: 0.into(),
@ -1670,10 +1684,9 @@ impl<'a> CodeGenerator<'a> {
}; };
term = Term::Apply { term = Term::Apply {
function: Term::Apply { function: Term::Apply {
function: Term::Force( function: Term::Builtin(DefaultFunction::MkCons)
Term::Builtin(DefaultFunction::MkCons).force_wrap().into(), .force_wrap()
) .into(),
.into(),
argument: list_item.into(), argument: list_item.into(),
} }
.into(), .into(),
@ -1846,10 +1859,10 @@ impl<'a> CodeGenerator<'a> {
arg_stack.push(term); arg_stack.push(term);
} }
Air::Call { count, .. } => { Air::Call { count, .. } => {
if count >= 2 { if count >= 1 {
let mut term = arg_stack.pop().unwrap(); let mut term = arg_stack.pop().unwrap();
for _ in 0..count - 1 { for _ in 0..count {
let arg = arg_stack.pop().unwrap(); let arg = arg_stack.pop().unwrap();
term = Term::Apply { term = Term::Apply {
@ -1883,7 +1896,6 @@ impl<'a> CodeGenerator<'a> {
DefaultFunction::EqualsData DefaultFunction::EqualsData
}; };
println!("Equals Binop");
let term = match name { let term = match name {
BinOp::And => Term::Apply { BinOp::And => Term::Apply {
function: Term::Apply { function: Term::Apply {
@ -1981,7 +1993,7 @@ impl<'a> CodeGenerator<'a> {
arg_stack.push(term); arg_stack.push(term);
return; return;
} else if tipo.is_tuple() } else if tipo.is_tuple()
&& matches!(dbg!(tipo.clone()).get_uplc_type(), UplcType::Pair(_, _)) && matches!(tipo.clone().get_uplc_type(), UplcType::Pair(_, _))
{ {
let term = Term::Apply { let term = Term::Apply {
function: Term::Apply { function: Term::Apply {
@ -2035,9 +2047,7 @@ impl<'a> CodeGenerator<'a> {
}; };
arg_stack.push(term); arg_stack.push(term);
return; return;
} else if tipo.is_list() } else if tipo.is_list() {
|| matches!(dbg!(tipo.clone()).get_uplc_type(), UplcType::List(_))
{
let term = Term::Apply { let term = Term::Apply {
function: Term::Apply { function: Term::Apply {
function: default_builtin.into(), function: default_builtin.into(),
@ -2048,13 +2058,10 @@ impl<'a> CodeGenerator<'a> {
.into(), .into(),
} }
.into(), .into(),
argument: Term::Apply { argument: Term::Apply {
function: default_builtin.into(), function: DefaultFunction::ListData.into(),
argument: Term::Apply { argument: right.into(),
function: DefaultFunction::ListData.into(),
argument: right.into(),
}
.into(),
} }
.into(), .into(),
}; };
@ -2153,7 +2160,7 @@ impl<'a> CodeGenerator<'a> {
arg_stack.push(term); arg_stack.push(term);
return; return;
} else if tipo.is_tuple() } else if tipo.is_tuple()
&& matches!(dbg!(tipo.clone()).get_uplc_type(), UplcType::Pair(_, _)) && matches!(tipo.clone().get_uplc_type(), UplcType::Pair(_, _))
{ {
// let term = Term::Apply { // let term = Term::Apply {
// function: Term::Apply { // function: Term::Apply {
@ -2205,7 +2212,7 @@ impl<'a> CodeGenerator<'a> {
// return; // return;
todo!() todo!()
} else if tipo.is_list() } else if tipo.is_list()
|| matches!(dbg!(tipo).get_uplc_type(), UplcType::List(_)) || matches!(tipo.get_uplc_type(), UplcType::List(_))
{ {
let term = Term::Apply { let term = Term::Apply {
function: Term::Apply { function: Term::Apply {
@ -2367,12 +2374,13 @@ impl<'a> CodeGenerator<'a> {
params, params,
recursive, recursive,
module_name, module_name,
variant_name,
.. ..
} => { } => {
let func_name = if module_name.is_empty() { let func_name = if module_name.is_empty() {
func_name format!("{func_name}{variant_name}")
} else { } else {
format!("{module_name}_{func_name}") format!("{module_name}_{func_name}{variant_name}")
}; };
let mut func_body = arg_stack.pop().unwrap(); let mut func_body = arg_stack.pop().unwrap();
@ -3276,6 +3284,7 @@ impl<'a> CodeGenerator<'a> {
module_name: dependency.module_name.clone(), module_name: dependency.module_name.clone(),
params: depend_comp.args.clone(), params: depend_comp.args.clone(),
recursive: depend_comp.recursive, recursive: depend_comp.recursive,
variant_name: func.0.variant_name.clone(),
}]; }];
temp_ir.extend(depend_comp.ir.clone()); temp_ir.extend(depend_comp.ir.clone());
@ -3323,29 +3332,24 @@ impl<'a> CodeGenerator<'a> {
module_name: function_access_key.module_name.clone(), module_name: function_access_key.module_name.clone(),
params: func_comp.args.clone(), params: func_comp.args.clone(),
recursive: func_comp.recursive, recursive: func_comp.recursive,
variant_name: function_access_key.variant_name.clone(),
}); });
let mut insert_var_vec = vec![]; let mut insert_var_vec = vec![];
for (index, air) in func_comp.ir.clone().into_iter().enumerate().rev() { for (index, air) in func_comp.ir.clone().into_iter().enumerate().rev() {
if let Air::Var { if let Air::Var {
scope, constructor, .. scope,
constructor,
variant_name,
..
} = air } = air
{ {
println!("found a var at index: {}", index);
if let ValueConstructorVariant::ModuleFn { if let ValueConstructorVariant::ModuleFn {
name: func_name, name: func_name,
module, module,
.. ..
} = constructor.clone().variant } = constructor.clone().variant
{ {
println!(
"Func Name: {func_name}, Dependency Name: {}",
function_access_key.function_name
);
println!(
"Module Name: {module}, Dependency Module: {}",
function_access_key.module_name
);
if func_name.clone() if func_name.clone()
== function_access_key.function_name.clone() == function_access_key.function_name.clone()
&& module == function_access_key.module_name.clone() && module == function_access_key.module_name.clone()
@ -3356,6 +3360,7 @@ impl<'a> CodeGenerator<'a> {
scope: scope.clone(), scope: scope.clone(),
constructor: constructor.clone(), constructor: constructor.clone(),
name: func_name.clone(), name: func_name.clone(),
variant_name,
}, },
)); ));
} }
@ -3392,7 +3397,7 @@ impl<'a> CodeGenerator<'a> {
fn define_recurse_ir( fn define_recurse_ir(
&mut self, &mut self,
ir_stack: &[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>>,
recursion_func_map: IndexMap<FunctionAccessKey, ()>, recursion_func_map: IndexMap<FunctionAccessKey, ()>,
@ -3405,7 +3410,7 @@ impl<'a> CodeGenerator<'a> {
let func = func_index.0; let func = func_index.0;
let function_components = func_components.get(func).unwrap(); let function_components = func_components.get(func).unwrap();
let function_ir = function_components.ir.clone(); let mut function_ir = function_components.ir.clone();
for ir in function_ir.clone() { for ir in function_ir.clone() {
if let Air::Var { if let Air::Var {
@ -3419,12 +3424,14 @@ impl<'a> CodeGenerator<'a> {
}, },
.. ..
}, },
variant_name,
.. ..
} = ir } = ir
{ {
if recursion_func_map.contains_key(&FunctionAccessKey { if recursion_func_map.contains_key(&FunctionAccessKey {
module_name: module.clone(), module_name: module.clone(),
function_name: func_name.clone(), function_name: func_name.clone(),
variant_name: variant_name.clone(),
}) { }) {
return; return;
} else { } else {
@ -3432,6 +3439,7 @@ impl<'a> CodeGenerator<'a> {
FunctionAccessKey { FunctionAccessKey {
module_name: module.clone(), module_name: module.clone(),
function_name: func_name.clone(), function_name: func_name.clone(),
variant_name: variant_name.clone(),
}, },
(), (),
); );
@ -3444,7 +3452,7 @@ impl<'a> CodeGenerator<'a> {
let mut inner_func_index_map = IndexMap::new(); let mut inner_func_index_map = IndexMap::new();
self.define_recurse_ir( self.define_recurse_ir(
&function_ir, &mut function_ir,
&mut inner_func_components, &mut inner_func_components,
&mut inner_func_index_map, &mut inner_func_index_map,
recursion_func_map.clone(), recursion_func_map.clone(),
@ -3469,12 +3477,12 @@ impl<'a> CodeGenerator<'a> {
fn process_define_ir( fn process_define_ir(
&mut self, &mut self,
ir_stack: &[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>>,
) { ) {
let mut to_be_defined_map: IndexMap<FunctionAccessKey, Vec<u64>> = IndexMap::new(); let mut to_be_defined_map: IndexMap<FunctionAccessKey, Vec<u64>> = IndexMap::new();
for ir in ir_stack.iter().rev() { for (index, ir) in ir_stack.to_vec().iter().enumerate().rev() {
match ir { match ir {
Air::Var { Air::Var {
scope, constructor, .. scope, constructor, ..
@ -3490,6 +3498,7 @@ impl<'a> CodeGenerator<'a> {
let mut function_key = FunctionAccessKey { let mut function_key = FunctionAccessKey {
module_name: module.clone(), module_name: module.clone(),
function_name: name.clone(), function_name: name.clone(),
variant_name: String::new(),
}; };
if let Some(scope_prev) = to_be_defined_map.get(&function_key) { if let Some(scope_prev) = to_be_defined_map.get(&function_key) {
@ -3521,21 +3530,19 @@ impl<'a> CodeGenerator<'a> {
} }
} }
let (variant_name, func_ir) = let (variant_name, mut func_ir) =
self.monomorphize(func_ir, param_name_types); self.monomorphize(func_ir, param_name_types);
function_key = FunctionAccessKey { function_key = FunctionAccessKey {
module_name: module.clone(), module_name: module.clone(),
function_name: format!( function_name: function_key.function_name,
"{}_{variant_name}", variant_name: variant_name.clone(),
function_key.function_name
),
}; };
to_be_defined_map.insert(function_key.clone(), scope.to_vec()); to_be_defined_map.insert(function_key.clone(), scope.to_vec());
let mut func_calls = vec![]; let mut func_calls = vec![];
for ir in func_ir.clone() { for (index, ir) in func_ir.clone().into_iter().enumerate() {
if let Air::Var { if let Air::Var {
constructor: constructor:
ValueConstructor { ValueConstructor {
@ -3543,17 +3550,52 @@ impl<'a> CodeGenerator<'a> {
ValueConstructorVariant::ModuleFn { ValueConstructorVariant::ModuleFn {
name: func_name, name: func_name,
module, module,
field_map,
arity,
location,
.. ..
}, },
.. public,
tipo,
}, },
scope,
name,
.. ..
} = ir } = ir
{ {
func_calls.push(FunctionAccessKey { let current_func = FunctionAccessKey {
module_name: module.clone(), module_name: module.clone(),
function_name: format!("{func_name}_{variant_name}"), 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(),
};
if function_key.clone() == current_func_as_variant {
func_ir[index] = Air::Var {
scope,
constructor: ValueConstructor {
public,
variant: ValueConstructorVariant::ModuleFn {
name: func_name,
field_map,
module,
arity,
location,
builtin: None,
},
tipo,
},
name,
variant_name: variant_name.clone(),
};
func_calls.push(current_func_as_variant);
} else {
func_calls.push(current_func);
}
} }
} }
@ -3580,6 +3622,13 @@ impl<'a> CodeGenerator<'a> {
false false
}; };
ir_stack[index] = Air::Var {
scope: scope.clone(),
constructor: constructor.clone(),
name: name.clone(),
variant_name,
};
func_components.insert( func_components.insert(
function_key, function_key,
FuncComponents { FuncComponents {
@ -3641,6 +3690,7 @@ impl<'a> CodeGenerator<'a> {
public, variant, .. public, variant, ..
}, },
name, name,
..
} = ir } = ir
{ {
let exists = param_types.iter().find(|(n, _)| n == &name); let exists = param_types.iter().find(|(n, _)| n == &name);
@ -3656,6 +3706,7 @@ impl<'a> CodeGenerator<'a> {
tipo: t.clone(), tipo: t.clone(),
}, },
name, name,
variant_name: String::new(),
} }
} }
} }
@ -4151,7 +4202,6 @@ fn convert_type_to_data(term: Term<Name>, field_type: &Arc<Type>) -> Term<Name>
.into(), .into(),
} }
} else if field_type.is_tuple() { } else if field_type.is_tuple() {
println!("Type to data");
match field_type.get_uplc_type() { match field_type.get_uplc_type() {
UplcType::List(_) => Term::Apply { UplcType::List(_) => Term::Apply {
function: DefaultFunction::ListData.into(), function: DefaultFunction::ListData.into(),

View File

@ -382,6 +382,7 @@ where
FunctionAccessKey { FunctionAccessKey {
module_name: module.name.clone(), module_name: module.name.clone(),
function_name: func.name.clone(), function_name: func.name.clone(),
variant_name: String::new(),
}, },
func, func,
); );
@ -456,6 +457,7 @@ where
FunctionAccessKey { FunctionAccessKey {
module_name: module.name.clone(), module_name: module.name.clone(),
function_name: func.name.clone(), function_name: func.name.clone(),
variant_name: String::new(),
}, },
func, func,
); );