Add codegen for assoc functions
This commit is contained in:
		
							parent
							
								
									4d7c17a854
								
							
						
					
					
						commit
						24f11a77d2
					
				| @ -15,8 +15,11 @@ use scope::*; | |||||||
| 
 | 
 | ||||||
| use crate::{ | use crate::{ | ||||||
|     mir::{ |     mir::{ | ||||||
|         self, implement::TypeCategory, pass::BinopKey, CustomTypeKey, FunctionDefinitionKind, NamedVariableRef, |         self, | ||||||
|         SourceModuleId, StructField, StructType, TypeDefinition, TypeDefinitionKind, TypeKind, WhileStatement, |         implement::TypeCategory, | ||||||
|  |         pass::{AssociatedFunctionKey, BinopKey}, | ||||||
|  |         CustomTypeKey, FunctionDefinitionKind, NamedVariableRef, SourceModuleId, StructField, StructType, | ||||||
|  |         TypeDefinition, TypeDefinitionKind, TypeKind, WhileStatement, | ||||||
|     }, |     }, | ||||||
|     util::try_all, |     util::try_all, | ||||||
| }; | }; | ||||||
| @ -212,6 +215,46 @@ impl mir::Module { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         let mut associated_functions = HashMap::new(); | ||||||
|  | 
 | ||||||
|  |         for (ty, function) in &self.associated_functions { | ||||||
|  |             let param_types: Vec<Type> = function | ||||||
|  |                 .parameters | ||||||
|  |                 .iter() | ||||||
|  |                 .map(|(_, p)| p.get_type(&type_values)) | ||||||
|  |                 .collect(); | ||||||
|  | 
 | ||||||
|  |             let is_main = self.is_main && function.name == "main"; | ||||||
|  |             let func = match &function.kind { | ||||||
|  |                 mir::FunctionDefinitionKind::Local(_, _) => Some(module.function( | ||||||
|  |                     &format!("{}::{}", ty, function.name), | ||||||
|  |                     function.return_type.get_type(&type_values), | ||||||
|  |                     param_types, | ||||||
|  |                     FunctionFlags { | ||||||
|  |                         is_pub: function.is_pub || is_main, | ||||||
|  |                         is_main, | ||||||
|  |                         is_imported: function.is_imported, | ||||||
|  |                         ..FunctionFlags::default() | ||||||
|  |                     }, | ||||||
|  |                 )), | ||||||
|  |                 mir::FunctionDefinitionKind::Extern(imported) => Some(module.function( | ||||||
|  |                     &function.name, | ||||||
|  |                     function.return_type.get_type(&type_values), | ||||||
|  |                     param_types, | ||||||
|  |                     FunctionFlags { | ||||||
|  |                         is_extern: true, | ||||||
|  |                         is_imported: *imported, | ||||||
|  |                         ..FunctionFlags::default() | ||||||
|  |                     }, | ||||||
|  |                 )), | ||||||
|  |                 mir::FunctionDefinitionKind::Intrinsic(_) => None, | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             if let Some(func) = func { | ||||||
|  |                 associated_functions.insert(AssociatedFunctionKey(ty.clone(), function.name.clone()), func); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         let mut binops = HashMap::new(); |         let mut binops = HashMap::new(); | ||||||
|         for binop in &self.binop_defs { |         for binop in &self.binop_defs { | ||||||
|             let binop_fn_name = format!( |             let binop_fn_name = format!( | ||||||
| @ -258,6 +301,7 @@ impl mir::Module { | |||||||
|                                 module_id: self.module_id, |                                 module_id: self.module_id, | ||||||
|                                 function: &ir_function, |                                 function: &ir_function, | ||||||
|                                 block: entry, |                                 block: entry, | ||||||
|  |                                 assoc_functions: &associated_functions, | ||||||
|                                 functions: &functions, |                                 functions: &functions, | ||||||
|                                 types: &types, |                                 types: &types, | ||||||
|                                 type_values: &type_values, |                                 type_values: &type_values, | ||||||
| @ -331,6 +375,62 @@ impl mir::Module { | |||||||
|                 module_id: self.module_id, |                 module_id: self.module_id, | ||||||
|                 function, |                 function, | ||||||
|                 block: entry, |                 block: entry, | ||||||
|  |                 assoc_functions: &associated_functions, | ||||||
|  |                 functions: &functions, | ||||||
|  |                 types: &types, | ||||||
|  |                 type_values: &type_values, | ||||||
|  |                 stack_values: HashMap::new(), | ||||||
|  |                 debug: Some(Debug { | ||||||
|  |                     info: &debug, | ||||||
|  |                     scope: compile_unit, | ||||||
|  |                     types: &debug_types, | ||||||
|  |                 }), | ||||||
|  |                 binops: &binops, | ||||||
|  |                 allocator: Rc::new(RefCell::new(allocator)), | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             mir_function | ||||||
|  |                 .kind | ||||||
|  |                 .codegen( | ||||||
|  |                     mir_function.name.clone(), | ||||||
|  |                     mir_function.is_pub, | ||||||
|  |                     &mut scope, | ||||||
|  |                     &mir_function.parameters, | ||||||
|  |                     &mir_function.return_type, | ||||||
|  |                     &function, | ||||||
|  |                     match &mir_function.kind { | ||||||
|  |                         FunctionDefinitionKind::Local(..) => mir_function.signature().into_debug(tokens, compile_unit), | ||||||
|  |                         FunctionDefinitionKind::Extern(_) => None, | ||||||
|  |                         FunctionDefinitionKind::Intrinsic(_) => None, | ||||||
|  |                     }, | ||||||
|  |                 ) | ||||||
|  |                 .unwrap(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         for (ty, mir_function) in &self.associated_functions { | ||||||
|  |             let function = associated_functions | ||||||
|  |                 .get(&AssociatedFunctionKey(ty.clone(), mir_function.name.clone())) | ||||||
|  |                 .unwrap(); | ||||||
|  |             let mut entry = function.block("entry"); | ||||||
|  | 
 | ||||||
|  |             let allocator = Allocator::from( | ||||||
|  |                 &mir_function.kind, | ||||||
|  |                 &mir_function.parameters, | ||||||
|  |                 &mut AllocatorScope { | ||||||
|  |                     block: &mut entry, | ||||||
|  |                     type_values: &type_values, | ||||||
|  |                 }, | ||||||
|  |             ); | ||||||
|  | 
 | ||||||
|  |             let mut scope = Scope { | ||||||
|  |                 context, | ||||||
|  |                 modules: &modules, | ||||||
|  |                 tokens, | ||||||
|  |                 module: &module, | ||||||
|  |                 module_id: self.module_id, | ||||||
|  |                 function, | ||||||
|  |                 block: entry, | ||||||
|  |                 assoc_functions: &associated_functions, | ||||||
|                 functions: &functions, |                 functions: &functions, | ||||||
|                 types: &types, |                 types: &types, | ||||||
|                 type_values: &type_values, |                 type_values: &type_values, | ||||||
| @ -1215,7 +1315,76 @@ impl mir::Expression { | |||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             mir::ExprKind::AssociatedFunctionCall(..) => todo!(), |             mir::ExprKind::AssociatedFunctionCall(ty, call) => { | ||||||
|  |                 let ret_type_kind = call.return_type.known().expect("function return type unknown"); | ||||||
|  |                 let call_name = format!("{}::{}", ty, call.name); | ||||||
|  | 
 | ||||||
|  |                 let ret_type = ret_type_kind.get_type(scope.type_values); | ||||||
|  | 
 | ||||||
|  |                 let params = try_all( | ||||||
|  |                     call.parameters | ||||||
|  |                         .iter() | ||||||
|  |                         .map(|e| e.codegen(scope, state)) | ||||||
|  |                         .collect::<Vec<_>>(), | ||||||
|  |                 ) | ||||||
|  |                 .map_err(|e| e.first().cloned().unwrap())? | ||||||
|  |                 .into_iter() | ||||||
|  |                 .map(|v| v.unwrap()) | ||||||
|  |                 .collect::<Vec<_>>(); | ||||||
|  | 
 | ||||||
|  |                 let param_instrs = params.iter().map(|e| e.instr()).collect(); | ||||||
|  |                 let callee = scope | ||||||
|  |                     .assoc_functions | ||||||
|  |                     .get(&AssociatedFunctionKey(ty.clone(), call.name.clone())) | ||||||
|  |                     .expect("function not found!"); | ||||||
|  | 
 | ||||||
|  |                 let val = scope | ||||||
|  |                     .block | ||||||
|  |                     .build_named(&call_name, Instr::FunctionCall(callee.value(), param_instrs)) | ||||||
|  |                     .unwrap(); | ||||||
|  | 
 | ||||||
|  |                 if let Some(debug) = &scope.debug { | ||||||
|  |                     let location = call.meta.into_debug(scope.tokens, debug.scope).unwrap(); | ||||||
|  |                     let location_val = debug.info.location(&debug.scope, location); | ||||||
|  |                     val.with_location(&mut scope.block, location_val); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 let ptr = if ret_type_kind != TypeKind::Void { | ||||||
|  |                     let ptr = scope | ||||||
|  |                         .block | ||||||
|  |                         .build_named(&call_name, Instr::Alloca(ret_type.clone())) | ||||||
|  |                         .unwrap(); | ||||||
|  |                     scope | ||||||
|  |                         .block | ||||||
|  |                         .build_named(format!("{}.store", call_name), Instr::Store(ptr, val)) | ||||||
|  |                         .unwrap(); | ||||||
|  | 
 | ||||||
|  |                     Some(ptr) | ||||||
|  |                 } else { | ||||||
|  |                     None | ||||||
|  |                 }; | ||||||
|  | 
 | ||||||
|  |                 if let Some(ptr) = ptr { | ||||||
|  |                     if state.should_load { | ||||||
|  |                         Some(StackValue( | ||||||
|  |                             StackValueKind::Immutable( | ||||||
|  |                                 scope | ||||||
|  |                                     .block | ||||||
|  |                                     .build_named(call.name.clone(), Instr::Load(ptr, ret_type)) | ||||||
|  |                                     .unwrap(), | ||||||
|  |                             ), | ||||||
|  |                             ret_type_kind, | ||||||
|  |                         )) | ||||||
|  |                     } else { | ||||||
|  |                         Some(StackValue( | ||||||
|  |                             StackValueKind::Immutable(ptr), | ||||||
|  |                             TypeKind::CodegenPtr(Box::new(ret_type_kind)), | ||||||
|  |                         )) | ||||||
|  |                     } | ||||||
|  |                 } else { | ||||||
|  |                     None | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|         }; |         }; | ||||||
|         if let Some(value) = &value { |         if let Some(value) = &value { | ||||||
|             value.instr().maybe_location(&mut scope.block, location); |             value.instr().maybe_location(&mut scope.block, location); | ||||||
|  | |||||||
| @ -8,7 +8,10 @@ use reid_lib::{ | |||||||
| 
 | 
 | ||||||
| use crate::{ | use crate::{ | ||||||
|     lexer::FullToken, |     lexer::FullToken, | ||||||
|     mir::{pass::BinopKey, CustomTypeKey, SourceModuleId, TypeDefinition, TypeKind}, |     mir::{ | ||||||
|  |         pass::{AssociatedFunctionKey, BinopKey}, | ||||||
|  |         CustomTypeKey, SourceModuleId, TypeDefinition, TypeKind, | ||||||
|  |     }, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| use super::{allocator::Allocator, ErrorKind, IntrinsicFunction, ModuleCodegen}; | use super::{allocator::Allocator, ErrorKind, IntrinsicFunction, ModuleCodegen}; | ||||||
| @ -23,6 +26,7 @@ pub struct Scope<'ctx, 'scope> { | |||||||
|     pub(super) block: Block<'ctx>, |     pub(super) block: Block<'ctx>, | ||||||
|     pub(super) types: &'scope HashMap<TypeValue, TypeDefinition>, |     pub(super) types: &'scope HashMap<TypeValue, TypeDefinition>, | ||||||
|     pub(super) type_values: &'scope HashMap<CustomTypeKey, TypeValue>, |     pub(super) type_values: &'scope HashMap<CustomTypeKey, TypeValue>, | ||||||
|  |     pub(super) assoc_functions: &'scope HashMap<AssociatedFunctionKey, Function<'ctx>>, | ||||||
|     pub(super) functions: &'scope HashMap<String, Function<'ctx>>, |     pub(super) functions: &'scope HashMap<String, Function<'ctx>>, | ||||||
|     pub(super) binops: &'scope HashMap<BinopKey, StackBinopDefinition<'ctx>>, |     pub(super) binops: &'scope HashMap<BinopKey, StackBinopDefinition<'ctx>>, | ||||||
|     pub(super) stack_values: HashMap<String, StackValue>, |     pub(super) stack_values: HashMap<String, StackValue>, | ||||||
| @ -40,6 +44,7 @@ impl<'ctx, 'a> Scope<'ctx, 'a> { | |||||||
|             context: self.context, |             context: self.context, | ||||||
|             module: self.module, |             module: self.module, | ||||||
|             module_id: self.module_id, |             module_id: self.module_id, | ||||||
|  |             assoc_functions: self.assoc_functions, | ||||||
|             functions: self.functions, |             functions: self.functions, | ||||||
|             types: self.types, |             types: self.types, | ||||||
|             type_values: self.type_values, |             type_values: self.type_values, | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user