Implement importing of associated functions with types
This commit is contained in:
		
							parent
							
								
									5104555890
								
							
						
					
					
						commit
						dc360ef196
					
				| @ -14,7 +14,7 @@ struct String { | ||||
| impl String { | ||||
|     pub fn new() -> String { | ||||
|         String { | ||||
|             inner: char::alloca(0), | ||||
|             inner: allocate(0), | ||||
|             length: 0, | ||||
|             max_length: 0, | ||||
|             must_be_freed: true, | ||||
|  | ||||
| @ -36,6 +36,7 @@ impl ast::Module { | ||||
|                 ExternFunction(signature) => { | ||||
|                     let def = mir::FunctionDefinition { | ||||
|                         name: signature.name.clone(), | ||||
|                         linkage_name: None, | ||||
|                         is_pub: false, | ||||
|                         is_imported: false, | ||||
|                         return_type: signature | ||||
| @ -149,6 +150,7 @@ impl ast::FunctionDefinition { | ||||
|         ); | ||||
|         mir::FunctionDefinition { | ||||
|             name: signature.name.clone(), | ||||
|             linkage_name: None, | ||||
|             is_pub: *is_pub, | ||||
|             is_imported: false, | ||||
|             return_type: signature | ||||
|  | ||||
| @ -40,6 +40,7 @@ pub fn get_intrinsic_assoc_func(ty: &TypeKind, name: &str) -> Option<FunctionDef | ||||
|     match name { | ||||
|         "sizeof" => Some(FunctionDefinition { | ||||
|             name: "sizeof".to_owned(), | ||||
|             linkage_name: None, | ||||
|             is_pub: true, | ||||
|             is_imported: false, | ||||
|             return_type: TypeKind::U64, | ||||
| @ -48,6 +49,7 @@ pub fn get_intrinsic_assoc_func(ty: &TypeKind, name: &str) -> Option<FunctionDef | ||||
|         }), | ||||
|         "alloca" => Some(FunctionDefinition { | ||||
|             name: "alloca".to_owned(), | ||||
|             linkage_name: None, | ||||
|             is_pub: true, | ||||
|             is_imported: false, | ||||
|             return_type: TypeKind::UserPtr(Box::new(ty.clone())), | ||||
| @ -56,6 +58,7 @@ pub fn get_intrinsic_assoc_func(ty: &TypeKind, name: &str) -> Option<FunctionDef | ||||
|         }), | ||||
|         "null" => Some(FunctionDefinition { | ||||
|             name: "null".to_owned(), | ||||
|             linkage_name: None, | ||||
|             is_pub: true, | ||||
|             is_imported: false, | ||||
|             return_type: TypeKind::UserPtr(Box::new(ty.clone())), | ||||
|  | ||||
| @ -187,7 +187,7 @@ impl mir::Module { | ||||
|             let is_main = self.is_main && function.name == "main"; | ||||
|             let func = match &function.kind { | ||||
|                 mir::FunctionDefinitionKind::Local(_, _) => Some(module.function( | ||||
|                     &function.name, | ||||
|                     &function.linkage_name.clone().unwrap_or(function.name.clone()), | ||||
|                     function.return_type.get_type(&type_values), | ||||
|                     param_types, | ||||
|                     FunctionFlags { | ||||
| @ -198,7 +198,7 @@ impl mir::Module { | ||||
|                     }, | ||||
|                 )), | ||||
|                 mir::FunctionDefinitionKind::Extern(imported) => Some(module.function( | ||||
|                     &function.name, | ||||
|                     &function.linkage_name.clone().unwrap_or(function.name.clone()), | ||||
|                     function.return_type.get_type(&type_values), | ||||
|                     param_types, | ||||
|                     FunctionFlags { | ||||
| @ -238,7 +238,7 @@ impl mir::Module { | ||||
|                     }, | ||||
|                 )), | ||||
|                 mir::FunctionDefinitionKind::Extern(imported) => Some(module.function( | ||||
|                     &function.name, | ||||
|                     &function.linkage_name.clone().unwrap_or(function.name.clone()), | ||||
|                     function.return_type.get_type(&type_values), | ||||
|                     param_types, | ||||
|                     FunctionFlags { | ||||
|  | ||||
| @ -227,7 +227,8 @@ impl<'map> Pass for LinkerPass<'map> { | ||||
|                     } | ||||
| 
 | ||||
|                     importer_module.functions.push(FunctionDefinition { | ||||
|                         name: func_name, | ||||
|                         name: func_name.clone(), | ||||
|                         linkage_name: None, | ||||
|                         is_pub: false, | ||||
|                         is_imported: false, | ||||
|                         return_type, | ||||
| @ -268,6 +269,66 @@ impl<'map> Pass for LinkerPass<'map> { | ||||
|                             FunctionDefinitionKind::Intrinsic(_) => {} | ||||
|                         } | ||||
|                     } | ||||
| 
 | ||||
|                     for (ty, func) in &mut imported.associated_functions { | ||||
|                         if *ty != imported_ty { | ||||
|                             continue; | ||||
|                         } | ||||
| 
 | ||||
|                         let func_name = func.name.clone(); | ||||
|                         dbg!(&func_name); | ||||
| 
 | ||||
|                         if !func.is_pub { | ||||
|                             state.ok::<_, Infallible>( | ||||
|                                 Err(ErrorKind::FunctionIsPrivate(module_name.clone(), func_name.clone())), | ||||
|                                 import.1, | ||||
|                             ); | ||||
|                             continue; | ||||
|                         } | ||||
| 
 | ||||
|                         func.is_imported = true; | ||||
| 
 | ||||
|                         if let Some((_, existing)) = importer_module | ||||
|                             .associated_functions | ||||
|                             .iter() | ||||
|                             .find(|(ty, f)| *ty == imported_ty && f.name == *func_name) | ||||
|                         { | ||||
|                             if let Err(e) = existing.equals_as_imported(func) { | ||||
|                                 state.ok::<_, Infallible>( | ||||
|                                     Err(ErrorKind::FunctionImportIssue( | ||||
|                                         module_name.clone(), | ||||
|                                         func_name.clone(), | ||||
|                                         e, | ||||
|                                     )), | ||||
|                                     import.1, | ||||
|                                 ); | ||||
|                             } | ||||
|                         } | ||||
| 
 | ||||
|                         let types = import_type(&func.return_type, false); | ||||
|                         let return_type = func.return_type.clone(); | ||||
|                         imported_types.extend(types); | ||||
| 
 | ||||
|                         let mut param_tys = Vec::new(); | ||||
|                         for (param_name, param_ty) in &func.parameters { | ||||
|                             let types = import_type(¶m_ty, false); | ||||
|                             imported_types.extend(types); | ||||
|                             param_tys.push((param_name.clone(), param_ty.clone())); | ||||
|                         } | ||||
| 
 | ||||
|                         importer_module.associated_functions.push(( | ||||
|                             ty.clone(), | ||||
|                             FunctionDefinition { | ||||
|                                 name: func_name.clone(), | ||||
|                                 linkage_name: Some(format!("{}::{}", ty, func_name)), | ||||
|                                 is_pub: false, | ||||
|                                 is_imported: false, | ||||
|                                 return_type, | ||||
|                                 parameters: param_tys, | ||||
|                                 kind: super::FunctionDefinitionKind::Extern(true), | ||||
|                             }, | ||||
|                         )); | ||||
|                     } | ||||
|                 } else { | ||||
|                     state.ok::<_, Infallible>( | ||||
|                         Err(ErrorKind::ImportDoesNotExist(module_name.clone(), import_name.clone())), | ||||
| @ -405,8 +466,6 @@ impl<'map> Pass for LinkerPass<'map> { | ||||
|                 super::ExprKind::Deref(..) => {} | ||||
|                 super::ExprKind::CastTo(_, type_kind) => *type_kind = type_kind.update_imported(extern_types, mod_id), | ||||
|                 super::ExprKind::AssociatedFunctionCall(type_kind, _) => { | ||||
|                     dbg!(&type_kind); | ||||
|                     dbg!(extern_types); | ||||
|                     *type_kind = type_kind.update_imported(extern_types, mod_id) | ||||
|                 } | ||||
|                 _ => {} | ||||
|  | ||||
| @ -284,6 +284,7 @@ pub struct FunctionCall { | ||||
| #[derive(Debug)] | ||||
| pub struct FunctionDefinition { | ||||
|     pub name: String, | ||||
|     pub linkage_name: Option<String>, | ||||
|     /// Whether this function is visible to outside modules
 | ||||
|     pub is_pub: bool, | ||||
|     /// Whether this module is from an external module, and has been imported
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user