support generics
This commit is contained in:
		
							parent
							
								
									16fbf5bbcd
								
							
						
					
					
						commit
						e4d9ca4586
					
				|  | @ -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(), | ||||||
|  |  | ||||||
|  | @ -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> { | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Kasey White
						Kasey White