Add intrinsic associated functions
This commit is contained in:
		
							parent
							
								
									0613fc5c53
								
							
						
					
					
						commit
						537167fe4f
					
				| @ -22,6 +22,7 @@ fn main() -> u32 { | ||||
|     let otus = Otus { field: 17 }; | ||||
|     print(from_str("otus: ") + Otus::test(&otus) as u64); | ||||
|     print(from_str("i32: ") + i32::test(54) as u64); | ||||
|     print(from_str("sizeof i32: ") + i32::sizeof()); | ||||
| 
 | ||||
|     return Otus::test(&otus); | ||||
| } | ||||
|  | ||||
| @ -36,6 +36,20 @@ pub fn form_intrinsics() -> Vec<FunctionDefinition> { | ||||
|     intrinsics | ||||
| } | ||||
| 
 | ||||
| pub fn get_intrinsic_assoc_func(ty: &TypeKind, name: &str) -> Option<FunctionDefinition> { | ||||
|     match name { | ||||
|         "sizeof" => Some(FunctionDefinition { | ||||
|             name: "sizeof".to_owned(), | ||||
|             is_pub: true, | ||||
|             is_imported: false, | ||||
|             return_type: TypeKind::U64, | ||||
|             parameters: Vec::new(), | ||||
|             kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicSizeOf(ty.clone()))), | ||||
|         }), | ||||
|         _ => None, | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn simple_binop_def<T: Clone + 'static>(op: BinaryOperator, ty: &TypeKind, fun: T) -> BinopDefinition | ||||
| where | ||||
|     T: FnOnce(&mut Scope, InstructionValue, InstructionValue) -> InstructionValue, | ||||
| @ -167,28 +181,33 @@ pub fn form_intrinsic_binops() -> Vec<BinopDefinition> { | ||||
| } | ||||
| 
 | ||||
| pub trait IntrinsicFunction: std::fmt::Debug { | ||||
|     fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, params: &[&StackValue]) -> Result<StackValue, ErrorKind>; | ||||
|     fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, params: &[StackValue]) -> Result<StackValue, ErrorKind>; | ||||
| } | ||||
| 
 | ||||
| macro_rules! intrinsic_debug { | ||||
|     ($kind:ty, $name:literal) => { | ||||
|         impl<T> std::fmt::Debug for $kind | ||||
|         where | ||||
|             T: FnOnce(&mut Scope, InstructionValue, InstructionValue) -> InstructionValue, | ||||
|         { | ||||
|             fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||
|                 f.debug_tuple($name).finish() | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone)] | ||||
| pub struct IntrinsicSimpleInstr<T>(T) | ||||
| where | ||||
|     T: FnOnce(&mut Scope, InstructionValue, InstructionValue) -> InstructionValue; | ||||
| 
 | ||||
| impl<T> std::fmt::Debug for IntrinsicSimpleInstr<T> | ||||
| where | ||||
|     T: FnOnce(&mut Scope, InstructionValue, InstructionValue) -> InstructionValue, | ||||
| { | ||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||
|         f.debug_tuple("IntrinsicSimpleInstr").finish() | ||||
|     } | ||||
| } | ||||
| intrinsic_debug!(IntrinsicSimpleInstr<T>, "IntrinsicSimpleInstr"); | ||||
| 
 | ||||
| impl<T: Clone> IntrinsicFunction for IntrinsicSimpleInstr<T> | ||||
| where | ||||
|     T: FnOnce(&mut Scope, InstructionValue, InstructionValue) -> InstructionValue, | ||||
| { | ||||
|     fn codegen<'b, 'c>(&self, scope: &mut Scope<'b, 'c>, params: &[&StackValue]) -> Result<StackValue, ErrorKind> { | ||||
|     fn codegen<'b, 'c>(&self, scope: &mut Scope<'b, 'c>, params: &[StackValue]) -> Result<StackValue, ErrorKind> { | ||||
|         let lhs = params.get(0).unwrap(); | ||||
|         let rhs = params.get(1).unwrap(); | ||||
|         let instr = self.clone().0(scope, lhs.instr(), rhs.instr()); | ||||
| @ -200,21 +219,13 @@ where | ||||
| pub struct IntrinsicBooleanInstr<T>(T) | ||||
| where | ||||
|     T: FnOnce(&mut Scope, InstructionValue, InstructionValue) -> InstructionValue; | ||||
| 
 | ||||
| impl<T> std::fmt::Debug for IntrinsicBooleanInstr<T> | ||||
| where | ||||
|     T: FnOnce(&mut Scope, InstructionValue, InstructionValue) -> InstructionValue, | ||||
| { | ||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||
|         f.debug_tuple("IntrinsicBooleanInstr").finish() | ||||
|     } | ||||
| } | ||||
| intrinsic_debug!(IntrinsicBooleanInstr<T>, "IntrinsicBooleanInstr"); | ||||
| 
 | ||||
| impl<T: Clone> IntrinsicFunction for IntrinsicBooleanInstr<T> | ||||
| where | ||||
|     T: FnOnce(&mut Scope, InstructionValue, InstructionValue) -> InstructionValue, | ||||
| { | ||||
|     fn codegen<'b, 'c>(&self, scope: &mut Scope<'b, 'c>, params: &[&StackValue]) -> Result<StackValue, ErrorKind> { | ||||
|     fn codegen<'b, 'c>(&self, scope: &mut Scope<'b, 'c>, params: &[StackValue]) -> Result<StackValue, ErrorKind> { | ||||
|         let lhs = params.get(0).unwrap(); | ||||
|         let rhs = params.get(1).unwrap(); | ||||
|         let instr = self.clone().0(scope, lhs.instr(), rhs.instr()); | ||||
| @ -222,6 +233,24 @@ where | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone)] | ||||
| pub struct IntrinsicSizeOf(TypeKind); | ||||
| impl std::fmt::Debug for IntrinsicSizeOf { | ||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||
|         f.debug_tuple("IntrinsicSizeOf").finish() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl IntrinsicFunction for IntrinsicSizeOf { | ||||
|     fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, _: &[StackValue]) -> Result<StackValue, ErrorKind> { | ||||
|         let instr = scope | ||||
|             .block | ||||
|             .build(Instr::Constant(reid_lib::ConstValue::U64(self.0.size_of()))) | ||||
|             .unwrap(); | ||||
|         Ok(StackValue(StackValueKind::Literal(instr), self.0.clone())) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // impl IntrinsicFunction for IntrinsicIAdd {
 | ||||
| //     fn codegen<'ctx, 'a>(
 | ||||
| //         &self,
 | ||||
|  | ||||
| @ -211,7 +211,7 @@ impl mir::Module { | ||||
|             }; | ||||
| 
 | ||||
|             if let Some(func) = func { | ||||
|                 functions.insert(function.name.clone(), func); | ||||
|                 functions.insert(function.name.clone(), ScopeFunctionKind::UserGenerated(func)); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| @ -251,7 +251,10 @@ impl mir::Module { | ||||
|             }; | ||||
| 
 | ||||
|             if let Some(func) = func { | ||||
|                 associated_functions.insert(AssociatedFunctionKey(ty.clone(), function.name.clone()), func); | ||||
|                 associated_functions.insert( | ||||
|                     AssociatedFunctionKey(ty.clone(), function.name.clone()), | ||||
|                     ScopeFunctionKind::UserGenerated(func), | ||||
|                 ); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| @ -332,10 +335,9 @@ impl mir::Module { | ||||
|                                 ) | ||||
|                                 .unwrap(); | ||||
| 
 | ||||
|                             StackBinopFunctionKind::UserGenerated(ir_function) | ||||
|                             ScopeFunctionKind::UserGenerated(ir_function) | ||||
|                         } | ||||
|                         FunctionDefinitionKind::Extern(imported) => { | ||||
|                             StackBinopFunctionKind::UserGenerated(module.function( | ||||
|                         FunctionDefinitionKind::Extern(imported) => ScopeFunctionKind::UserGenerated(module.function( | ||||
|                             &binop_fn_name, | ||||
|                             binop.return_type.get_type(&type_values), | ||||
|                             vec![binop.lhs.1.get_type(&type_values), binop.rhs.1.get_type(&type_values)], | ||||
| @ -344,10 +346,9 @@ impl mir::Module { | ||||
|                                 is_imported: *imported, | ||||
|                                 ..FunctionFlags::default() | ||||
|                             }, | ||||
|                             )) | ||||
|                         } | ||||
|                         )), | ||||
|                         FunctionDefinitionKind::Intrinsic(intrinsic_function) => { | ||||
|                             StackBinopFunctionKind::Intrinsic(intrinsic_function) | ||||
|                             ScopeFunctionKind::Intrinsic(intrinsic_function) | ||||
|                         } | ||||
|                     }, | ||||
|                 }, | ||||
| @ -355,7 +356,7 @@ impl mir::Module { | ||||
|         } | ||||
| 
 | ||||
|         for mir_function in &self.functions { | ||||
|             let function = functions.get(&mir_function.name).unwrap(); | ||||
|             if let ScopeFunctionKind::UserGenerated(function) = functions.get(&mir_function.name).unwrap() { | ||||
|                 let mut entry = function.block("entry"); | ||||
| 
 | ||||
|                 let allocator = Allocator::from( | ||||
| @ -399,18 +400,22 @@ impl mir::Module { | ||||
|                         &mir_function.return_type, | ||||
|                         &function, | ||||
|                         match &mir_function.kind { | ||||
|                         FunctionDefinitionKind::Local(..) => mir_function.signature().into_debug(tokens, compile_unit), | ||||
|                             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 | ||||
|             if let ScopeFunctionKind::UserGenerated(function) = associated_functions | ||||
|                 .get(&AssociatedFunctionKey(ty.clone(), mir_function.name.clone())) | ||||
|                 .unwrap(); | ||||
|                 .unwrap() | ||||
|             { | ||||
|                 let mut entry = function.block("entry"); | ||||
| 
 | ||||
|                 let allocator = Allocator::from( | ||||
| @ -454,13 +459,16 @@ impl mir::Module { | ||||
|                         &mir_function.return_type, | ||||
|                         &function, | ||||
|                         match &mir_function.kind { | ||||
|                         FunctionDefinitionKind::Local(..) => mir_function.signature().into_debug(tokens, compile_unit), | ||||
|                             FunctionDefinitionKind::Local(..) => { | ||||
|                                 mir_function.signature().into_debug(tokens, compile_unit) | ||||
|                             } | ||||
|                             FunctionDefinitionKind::Extern(_) => None, | ||||
|                             FunctionDefinitionKind::Intrinsic(_) => None, | ||||
|                         }, | ||||
|                     ) | ||||
|                     .unwrap(); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         Ok(ModuleCodegen { module }) | ||||
|     } | ||||
| @ -821,7 +829,7 @@ impl mir::Expression { | ||||
|                 }); | ||||
| 
 | ||||
|                 if let Some(operation) = operation { | ||||
|                     let a = operation.codegen(&lhs_val, &rhs_val, scope)?; | ||||
|                     let a = operation.codegen(lhs_val.clone(), rhs_val.clone(), scope)?; | ||||
|                     Some(a) | ||||
|                 } else { | ||||
|                     let lhs_type = lhs_exp.return_type(&Default::default(), scope.module_id).unwrap().1; | ||||
| @ -906,19 +914,19 @@ impl mir::Expression { | ||||
|                 .map(|v| v.unwrap()) | ||||
|                 .collect::<Vec<_>>(); | ||||
| 
 | ||||
|                 let param_instrs = params.iter().map(|e| e.instr()).collect(); | ||||
|                 let callee = scope.functions.get(&call.name).expect("function not found!"); | ||||
| 
 | ||||
|                 let val = scope | ||||
|                     .block | ||||
|                     .build_named(call.name.clone(), Instr::FunctionCall(callee.value(), param_instrs)) | ||||
|                     .unwrap(); | ||||
| 
 | ||||
|                 let val = callee.codegen( | ||||
|                     &call.name, | ||||
|                     params.as_slice(), | ||||
|                     &call.return_type, | ||||
|                     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); | ||||
|                 } | ||||
|                         call.meta.into_debug(scope.tokens, debug.scope) | ||||
|                     } else { | ||||
|                         None | ||||
|                     }, | ||||
|                     scope, | ||||
|                 )?; | ||||
| 
 | ||||
|                 let ptr = if ret_type_kind != TypeKind::Void { | ||||
|                     let ptr = scope | ||||
| @ -927,7 +935,7 @@ impl mir::Expression { | ||||
|                         .unwrap(); | ||||
|                     scope | ||||
|                         .block | ||||
|                         .build_named(format!("{}.store", call.name), Instr::Store(ptr, val)) | ||||
|                         .build_named(format!("{}.store", call.name), Instr::Store(ptr, val.instr())) | ||||
|                         .unwrap(); | ||||
| 
 | ||||
|                     Some(ptr) | ||||
| @ -1332,31 +1340,38 @@ impl mir::Expression { | ||||
|                 .map(|v| v.unwrap()) | ||||
|                 .collect::<Vec<_>>(); | ||||
| 
 | ||||
|                 let param_instrs = params.iter().map(|e| e.instr()).collect(); | ||||
|                 let assoc_key = AssociatedFunctionKey(ty.clone(), call.name.clone()); | ||||
|                 let intrinsic = get_intrinsic_assoc_func(&ty, &call.name); | ||||
|                 let intrinsic_owned = intrinsic.map(|func_def| { | ||||
|                     let FunctionDefinitionKind::Intrinsic(intrinsic) = func_def.kind else { | ||||
|                         panic!(); | ||||
|                     }; | ||||
|                     ScopeFunctionKind::IntrinsicOwned(intrinsic) | ||||
|                 }); | ||||
|                 let callee = scope | ||||
|                     .assoc_functions | ||||
|                     .get(&AssociatedFunctionKey(ty.clone(), call.name.clone())) | ||||
|                     .expect("function not found!"); | ||||
|                     .get(&assoc_key) | ||||
|                     .or(intrinsic_owned.as_ref()) | ||||
|                     .expect(&format!("Function {} does not exist!", call_name)); | ||||
| 
 | ||||
|                 let val = scope | ||||
|                     .block | ||||
|                     .build_named(&call_name, Instr::FunctionCall(callee.value(), param_instrs)) | ||||
|                 let location = if let Some(debug) = &scope.debug { | ||||
|                     call.meta.into_debug(scope.tokens, debug.scope) | ||||
|                 } else { | ||||
|                     None | ||||
|                 }; | ||||
| 
 | ||||
|                 let val = callee | ||||
|                     .codegen(&call_name, params.as_slice(), &call.return_type, location, scope) | ||||
|                     .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())) | ||||
|                         .build_named(&call.name, Instr::Alloca(ret_type.clone())) | ||||
|                         .unwrap(); | ||||
|                     scope | ||||
|                         .block | ||||
|                         .build_named(format!("{}.store", call_name), Instr::Store(ptr, val)) | ||||
|                         .build_named(format!("{}.store", call_name), Instr::Store(ptr, val.instr())) | ||||
|                         .unwrap(); | ||||
| 
 | ||||
|                     Some(ptr) | ||||
|  | ||||
| @ -2,7 +2,7 @@ use std::{cell::RefCell, collections::HashMap, mem, rc::Rc}; | ||||
| 
 | ||||
| use reid_lib::{ | ||||
|     builder::{InstructionValue, TypeValue}, | ||||
|     debug_information::{DebugInformation, DebugProgramValue, DebugTypeValue}, | ||||
|     debug_information::{DebugInformation, DebugLocation, DebugProgramValue, DebugTypeValue}, | ||||
|     Block, Context, Function, Instr, Module, | ||||
| }; | ||||
| 
 | ||||
| @ -26,8 +26,8 @@ pub struct Scope<'ctx, 'scope> { | ||||
|     pub(super) block: Block<'ctx>, | ||||
|     pub(super) types: &'scope HashMap<TypeValue, TypeDefinition>, | ||||
|     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) assoc_functions: &'scope HashMap<AssociatedFunctionKey, ScopeFunctionKind<'ctx>>, | ||||
|     pub(super) functions: &'scope HashMap<String, ScopeFunctionKind<'ctx>>, | ||||
|     pub(super) binops: &'scope HashMap<BinopKey, StackBinopDefinition<'ctx>>, | ||||
|     pub(super) stack_values: HashMap<String, StackValue>, | ||||
|     pub(super) debug: Option<Debug<'ctx>>, | ||||
| @ -131,19 +131,20 @@ impl StackValueKind { | ||||
| pub struct StackBinopDefinition<'ctx> { | ||||
|     pub(super) parameters: ((String, TypeKind), (String, TypeKind)), | ||||
|     pub(super) return_ty: TypeKind, | ||||
|     pub(super) kind: StackBinopFunctionKind<'ctx>, | ||||
|     pub(super) kind: ScopeFunctionKind<'ctx>, | ||||
| } | ||||
| 
 | ||||
| pub enum StackBinopFunctionKind<'ctx> { | ||||
| pub enum ScopeFunctionKind<'ctx> { | ||||
|     UserGenerated(Function<'ctx>), | ||||
|     Intrinsic(&'ctx Box<dyn IntrinsicFunction>), | ||||
|     IntrinsicOwned(Box<dyn IntrinsicFunction>), | ||||
| } | ||||
| 
 | ||||
| impl<'ctx> StackBinopDefinition<'ctx> { | ||||
|     pub fn codegen<'a>( | ||||
|         &self, | ||||
|         lhs: &StackValue, | ||||
|         rhs: &StackValue, | ||||
|         lhs: StackValue, | ||||
|         rhs: StackValue, | ||||
|         scope: &mut Scope<'ctx, 'a>, | ||||
|     ) -> Result<StackValue, ErrorKind> { | ||||
|         let (lhs, rhs) = if lhs.1 == self.parameters.0 .1 && rhs.1 == self.parameters.1 .1 { | ||||
| @ -151,15 +152,43 @@ impl<'ctx> StackBinopDefinition<'ctx> { | ||||
|         } else { | ||||
|             (rhs, lhs) | ||||
|         }; | ||||
|         match &self.kind { | ||||
|             StackBinopFunctionKind::UserGenerated(ir) => { | ||||
|                 let instr = scope | ||||
|         let name = format!( | ||||
|             "binop.{}.{}.{}.call", | ||||
|             self.parameters.0 .1, self.parameters.1 .1, self.return_ty | ||||
|         ); | ||||
|         self.kind.codegen(&name, &[lhs, rhs], &self.return_ty, None, scope) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'ctx> ScopeFunctionKind<'ctx> { | ||||
|     pub fn codegen<'a>( | ||||
|         &self, | ||||
|         name: &str, | ||||
|         params: &[StackValue], | ||||
|         return_ty: &TypeKind, | ||||
|         location: Option<DebugLocation>, | ||||
|         scope: &mut Scope<'ctx, 'a>, | ||||
|     ) -> Result<StackValue, ErrorKind> { | ||||
|         match self { | ||||
|             ScopeFunctionKind::UserGenerated(function) => { | ||||
|                 let val = scope | ||||
|                     .block | ||||
|                     .build(Instr::FunctionCall(ir.value(), vec![lhs.instr(), rhs.instr()])) | ||||
|                     .build_named( | ||||
|                         name, | ||||
|                         Instr::FunctionCall(function.value(), params.iter().map(|p| p.instr()).collect()), | ||||
|                     ) | ||||
|                     .unwrap(); | ||||
|                 Ok(StackValue(StackValueKind::Immutable(instr), self.return_ty.clone())) | ||||
| 
 | ||||
|                 if let Some(debug) = &scope.debug { | ||||
|                     if let Some(location) = location { | ||||
|                         let location_val = debug.info.location(&debug.scope, location); | ||||
|                         val.with_location(&mut scope.block, location_val); | ||||
|                     } | ||||
|             StackBinopFunctionKind::Intrinsic(fun) => fun.codegen(scope, &[&lhs, &rhs]), | ||||
|                 } | ||||
|                 Ok(StackValue(StackValueKind::Immutable(val), return_ty.clone())) | ||||
|             } | ||||
|             ScopeFunctionKind::Intrinsic(fun) => fun.codegen(scope, params), | ||||
|             ScopeFunctionKind::IntrinsicOwned(fun) => fun.codegen(scope, params), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -5,7 +5,7 @@ use std::collections::HashMap; | ||||
| use std::convert::Infallible; | ||||
| use std::error::Error as STDError; | ||||
| 
 | ||||
| use crate::codegen::intrinsics::form_intrinsic_binops; | ||||
| use crate::codegen::intrinsics::{form_intrinsic_binops, get_intrinsic_assoc_func}; | ||||
| use crate::error_raporting::ReidError; | ||||
| 
 | ||||
| use super::*; | ||||
| @ -169,6 +169,24 @@ impl<Data: Clone + Default> Scope<Data> { | ||||
|             .find(|(key, def)| key.0 == typekey.0 && def.importer == Some(typekey.1)) | ||||
|             .map(|(_, v)| v)) | ||||
|     } | ||||
| 
 | ||||
|     pub fn get_associated_function(&mut self, key: &AssociatedFunctionKey) -> Option<ScopeFunction> { | ||||
|         let func = self.associated_functions.get(key); | ||||
|         if let Some(func) = func { | ||||
|             Some(func.clone()) | ||||
|         } else if let Some(func) = get_intrinsic_assoc_func(&key.0, &key.1) { | ||||
|             self.associated_functions.set( | ||||
|                 key.clone(), | ||||
|                 ScopeFunction { | ||||
|                     ret: func.return_type, | ||||
|                     params: func.parameters.iter().map(|(_, p)| p.clone()).collect(), | ||||
|                 }, | ||||
|             ); | ||||
|             self.associated_functions.get(key).cloned() | ||||
|         } else { | ||||
|             None | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone, Debug)] | ||||
|  | ||||
| @ -732,12 +732,10 @@ impl Expression { | ||||
|             ExprKind::AssociatedFunctionCall(type_kind, function_call) => { | ||||
|                 let true_function = state | ||||
|                     .scope | ||||
|                     .associated_functions | ||||
|                     .get(&pass::AssociatedFunctionKey( | ||||
|                     .get_associated_function(&pass::AssociatedFunctionKey( | ||||
|                         type_kind.clone(), | ||||
|                         function_call.name.clone(), | ||||
|                     )) | ||||
|                     .cloned() | ||||
|                     .ok_or(ErrorKind::FunctionNotDefined(function_call.name.clone())); | ||||
| 
 | ||||
|                 if let Some(f) = state.ok(true_function, self.1) { | ||||
|  | ||||
| @ -598,8 +598,7 @@ impl Expression { | ||||
|                 // Get function definition and types
 | ||||
|                 let fn_call = state | ||||
|                     .scope | ||||
|                     .associated_functions | ||||
|                     .get(&AssociatedFunctionKey(type_kind.clone(), function_call.name.clone())) | ||||
|                     .get_associated_function(&AssociatedFunctionKey(type_kind.clone(), function_call.name.clone())) | ||||
|                     .ok_or(ErrorKind::AssocFunctionNotDefined( | ||||
|                         function_call.name.clone(), | ||||
|                         type_kind.clone(), | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user