support generics

This commit is contained in:
Kasey White 2022-12-11 14:09:20 -05:00 committed by KtorZ
parent 16fbf5bbcd
commit e4d9ca4586
No known key found for this signature in database
GPG Key ID: 33173CB6F77F4277
2 changed files with 151 additions and 74 deletions

View File

@ -157,6 +157,33 @@ impl Type {
matches!(self, Self::Tuple { .. }) matches!(self, Self::Tuple { .. })
} }
pub fn is_generic(&self) -> bool {
match self {
Type::App {
public,
module,
name,
args,
} => {
let mut is_a_generic = false;
for arg in args {
is_a_generic = is_a_generic || arg.is_generic();
}
is_a_generic
}
Type::Var { tipo } => tipo.borrow().is_generic(),
Type::Tuple { elems } => {
let mut is_a_generic = false;
for elem in elems {
is_a_generic = is_a_generic || elem.is_generic();
}
is_a_generic
}
_ => todo!(),
}
}
pub fn get_inner_type(&self) -> Vec<Arc<Type>> { pub fn get_inner_type(&self) -> Vec<Arc<Type>> {
if self.is_list() { if self.is_list() {
match self { match self {
@ -381,6 +408,14 @@ impl TypeVar {
} }
} }
pub fn is_generic(&self) -> bool {
match self {
TypeVar::Generic { .. } => true,
TypeVar::Link { tipo } => tipo.is_generic(),
_ => false,
}
}
pub fn get_inner_type(&self) -> Vec<Arc<Type>> { pub fn get_inner_type(&self) -> Vec<Arc<Type>> {
match self { match self {
Self::Link { tipo } => tipo.get_inner_type(), Self::Link { tipo } => tipo.get_inner_type(),

View File

@ -3277,65 +3277,8 @@ impl<'a> CodeGenerator<'a> {
params: depend_comp.args.clone(), params: depend_comp.args.clone(),
recursive: depend_comp.recursive, recursive: depend_comp.recursive,
}]; }];
let mut new_ir = depend_comp.ir.clone();
if depend_comp.recursive { temp_ir.extend(depend_comp.ir.clone());
let mut insert_var_vec = vec![];
println!("FOund HERE");
for (index, air) in depend_comp.ir.clone().into_iter().enumerate().rev() {
if let Air::Var {
scope,
constructor,
name,
} = air
{
println!("found a var at index: {}", index);
if let ValueConstructorVariant::ModuleFn {
name: func_name,
module,
..
} = constructor.clone().variant
{
println!(
"Func Name: {func_name}, Dependency Name: {}",
dependency.function_name
);
println!(
"Module Name: {module}, Dependency Module: {}",
dependency.module_name
);
if func_name.clone() == dependency.function_name.clone()
&& module == dependency.module_name.clone()
{
insert_var_vec.push((
index,
Air::Var {
scope: scope.clone(),
constructor: constructor.clone(),
name: func_name.clone(),
},
));
}
}
}
}
for (index, ir) in insert_var_vec {
new_ir.insert(index, ir);
let current_call = new_ir[index - 1].clone();
match current_call {
Air::Call { scope, count } => {
new_ir[index - 1] = Air::Call {
scope,
count: count + 1,
}
}
_ => unreachable!(),
}
}
}
temp_ir.extend(new_ir);
temp_ir.append(&mut dep_ir); temp_ir.append(&mut dep_ir);
@ -3374,8 +3317,6 @@ impl<'a> CodeGenerator<'a> {
let mut func_comp = let mut func_comp =
func_components.get(function_access_key).unwrap().clone(); func_components.get(function_access_key).unwrap().clone();
dbg!(&func_comp);
full_func_ir.push(Air::DefineFunc { full_func_ir.push(Air::DefineFunc {
scope: scopes.clone(), scope: scopes.clone(),
func_name: function_access_key.function_name.clone(), func_name: function_access_key.function_name.clone(),
@ -3385,13 +3326,9 @@ impl<'a> CodeGenerator<'a> {
}); });
let mut insert_var_vec = vec![]; let mut insert_var_vec = vec![];
println!("FOund HERE");
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, scope, constructor, ..
constructor,
name,
} = air } = air
{ {
println!("found a var at index: {}", index); println!("found a var at index: {}", index);
@ -3550,7 +3487,7 @@ impl<'a> CodeGenerator<'a> {
} = &constructor.variant } = &constructor.variant
{ {
if builtin.is_none() { if builtin.is_none() {
let function_key = FunctionAccessKey { let mut function_key = FunctionAccessKey {
module_name: module.clone(), module_name: module.clone(),
function_name: name.clone(), function_name: name.clone(),
}; };
@ -3568,6 +3505,33 @@ impl<'a> CodeGenerator<'a> {
self.build_ir(&function.body, &mut func_ir, scope.to_vec()); self.build_ir(&function.body, &mut func_ir, scope.to_vec());
let (param_types, _) = constructor.tipo.function_types().unwrap();
let mut param_name_types = vec![];
for (index, arg) in function.arguments.iter().enumerate() {
if arg.tipo.is_generic() {
param_name_types.push((
arg.arg_name
.get_variable_name()
.unwrap_or_default()
.to_string(),
param_types[index].clone(),
));
}
}
let (variant_name, func_ir) =
self.monomorphize(func_ir, param_name_types);
function_key = FunctionAccessKey {
module_name: module.clone(),
function_name: format!(
"{}_{variant_name}",
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![];
@ -3588,8 +3552,8 @@ impl<'a> CodeGenerator<'a> {
{ {
func_calls.push(FunctionAccessKey { func_calls.push(FunctionAccessKey {
module_name: module.clone(), module_name: module.clone(),
function_name: func_name.clone(), function_name: format!("{func_name}_{variant_name}"),
}) });
} }
} }
@ -3604,9 +3568,13 @@ impl<'a> CodeGenerator<'a> {
_ => {} _ => {}
} }
} }
let recursive = let recursive = if let Ok(index) =
if let Ok(index) = func_calls.binary_search(&function_key) { func_calls.binary_search(&function_key)
{
func_calls.remove(index); func_calls.remove(index);
while let Ok(index) = func_calls.binary_search(&function_key) {
func_calls.remove(index);
}
true true
} else { } else {
false false
@ -3656,6 +3624,80 @@ impl<'a> CodeGenerator<'a> {
func_index_map.insert(func.0.clone(), get_common_ancestor(func.1, index_scope)); func_index_map.insert(func.0.clone(), get_common_ancestor(func.1, index_scope));
} }
} }
fn monomorphize(
&mut self,
ir: Vec<Air>,
param_types: Vec<(String, Arc<Type>)>,
) -> (String, Vec<Air>) {
let mut used_param_to_type = vec![];
let mut new_air = ir.clone();
for (index, ir) in ir.into_iter().enumerate() {
if let Air::Var {
scope,
constructor:
ValueConstructor {
public, variant, ..
},
name,
} = ir
{
let exists = param_types.iter().find(|(n, _)| n == &name);
if let Some((n, t)) = exists {
used_param_to_type.push((n.clone(), t.clone()));
new_air[index] = Air::Var {
scope,
constructor: ValueConstructor {
public,
variant,
tipo: t.clone(),
},
name,
}
}
}
}
let mut new_name = String::new();
for (_, t) in used_param_to_type {
get_variant_name(&mut new_name, t);
}
(new_name, new_air)
}
}
fn get_variant_name(new_name: &mut String, t: Arc<Type>) {
new_name.push_str(&format!(
"_{}",
if t.is_string() {
"string".to_string()
} else if t.is_int() {
"int".to_string()
} else if t.is_bool() {
"bool".to_string()
} else if t.is_map() {
let mut full_type = "map".to_string();
let pair_type = &t.get_inner_type()[0];
let fst_type = &pair_type.get_inner_type()[0];
let snd_type = &pair_type.get_inner_type()[1];
get_variant_name(&mut full_type, fst_type.clone());
get_variant_name(&mut full_type, snd_type.clone());
full_type
} else if t.is_list() {
let mut full_type = "list".to_string();
let list_type = &t.get_inner_type()[0];
get_variant_name(&mut full_type, list_type.clone());
full_type
} else {
"data".to_string()
}
));
} }
fn convert_constants_to_data(constants: Vec<UplcConstant>) -> Vec<UplcConstant> { fn convert_constants_to_data(constants: Vec<UplcConstant>) -> Vec<UplcConstant> {