Import binops while importing types as well
This commit is contained in:
		
							parent
							
								
									58cc633f98
								
							
						
					
					
						commit
						0196fb53ed
					
				| @ -14,6 +14,6 @@ fn otus(param: &mut String) { | |||||||
| fn main() -> u8 { | fn main() -> u8 { | ||||||
|     let mut otus = from_str("hello"); |     let mut otus = from_str("hello"); | ||||||
|     otus(&mut otus); |     otus(&mut otus); | ||||||
|     print(otus); |     print(otus + " beep"); | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
| @ -5,9 +5,7 @@ | |||||||
| use std::{fmt::Debug, marker::PhantomData}; | use std::{fmt::Debug, marker::PhantomData}; | ||||||
| 
 | 
 | ||||||
| use builder::{BlockValue, Builder, FunctionValue, InstructionValue, ModuleValue, TypeValue}; | use builder::{BlockValue, Builder, FunctionValue, InstructionValue, ModuleValue, TypeValue}; | ||||||
| use debug_information::{ | use debug_information::{DebugFileData, DebugInformation, DebugLocationValue, DebugMetadataValue, DebugProgramValue}; | ||||||
|     DebugFileData, DebugInformation, DebugLocationValue, DebugMetadataValue, DebugProgramValue, |  | ||||||
| }; |  | ||||||
| use fmt::PrintableModule; | use fmt::PrintableModule; | ||||||
| 
 | 
 | ||||||
| pub mod builder; | pub mod builder; | ||||||
| @ -66,13 +64,7 @@ pub struct Module<'ctx> { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl<'ctx> Module<'ctx> { | impl<'ctx> Module<'ctx> { | ||||||
|     pub fn function( |     pub fn function(&self, name: &str, ret: Type, params: Vec<Type>, flags: FunctionFlags) -> Function<'ctx> { | ||||||
|         &self, |  | ||||||
|         name: &str, |  | ||||||
|         ret: Type, |  | ||||||
|         params: Vec<Type>, |  | ||||||
|         flags: FunctionFlags, |  | ||||||
|     ) -> Function<'ctx> { |  | ||||||
|         unsafe { |         unsafe { | ||||||
|             Function { |             Function { | ||||||
|                 phantom: PhantomData, |                 phantom: PhantomData, | ||||||
| @ -111,10 +103,7 @@ impl<'ctx> Module<'ctx> { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn create_debug_info( |     pub fn create_debug_info(&mut self, file: DebugFileData) -> (DebugInformation, DebugProgramValue) { | ||||||
|         &mut self, |  | ||||||
|         file: DebugFileData, |  | ||||||
|     ) -> (DebugInformation, DebugProgramValue) { |  | ||||||
|         let (debug_info, program_value) = DebugInformation::from_file(file); |         let (debug_info, program_value) = DebugInformation::from_file(file); | ||||||
|         self.debug_info = Some(debug_info.clone()); |         self.debug_info = Some(debug_info.clone()); | ||||||
|         (debug_info, program_value) |         (debug_info, program_value) | ||||||
| @ -144,10 +133,17 @@ pub struct FunctionData { | |||||||
| 
 | 
 | ||||||
| #[derive(Debug, Clone, Copy, Hash)] | #[derive(Debug, Clone, Copy, Hash)] | ||||||
| pub struct FunctionFlags { | pub struct FunctionFlags { | ||||||
|  |     /// True in the destination module of the import, false in the source module.
 | ||||||
|     pub is_extern: bool, |     pub is_extern: bool, | ||||||
|  |     /// Whether this function is the main function of the module, that should be
 | ||||||
|  |     /// executed (and linked externally also).
 | ||||||
|     pub is_main: bool, |     pub is_main: bool, | ||||||
|  |     /// Whether this function should be available externally always.
 | ||||||
|     pub is_pub: bool, |     pub is_pub: bool, | ||||||
|  |     /// If this function is an imported function (either in the source or
 | ||||||
|  |     /// destination module)
 | ||||||
|     pub is_imported: bool, |     pub is_imported: bool, | ||||||
|  |     /// Whether this function should add "alwaysinline"-attribute.
 | ||||||
|     pub inline: bool, |     pub inline: bool, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -260,11 +256,7 @@ impl Instr { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl<'builder> Block<'builder> { | impl<'builder> Block<'builder> { | ||||||
|     pub fn build_named<T: Into<String>>( |     pub fn build_named<T: Into<String>>(&mut self, name: T, instruction: Instr) -> CompileResult<InstructionValue> { | ||||||
|         &mut self, |  | ||||||
|         name: T, |  | ||||||
|         instruction: Instr, |  | ||||||
|     ) -> CompileResult<InstructionValue> { |  | ||||||
|         unsafe { |         unsafe { | ||||||
|             self.builder.add_instruction( |             self.builder.add_instruction( | ||||||
|                 &self.value, |                 &self.value, | ||||||
| @ -295,15 +287,13 @@ impl<'builder> Block<'builder> { | |||||||
| 
 | 
 | ||||||
|     pub fn set_instr_location(&self, instruction: InstructionValue, location: DebugLocationValue) { |     pub fn set_instr_location(&self, instruction: InstructionValue, location: DebugLocationValue) { | ||||||
|         unsafe { |         unsafe { | ||||||
|             self.builder |             self.builder.add_instruction_location(&instruction, location); | ||||||
|                 .add_instruction_location(&instruction, location); |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn set_instr_metadata(&self, instruction: InstructionValue, location: DebugMetadataValue) { |     pub fn set_instr_metadata(&self, instruction: InstructionValue, location: DebugMetadataValue) { | ||||||
|         unsafe { |         unsafe { | ||||||
|             self.builder |             self.builder.add_instruction_metadata(&instruction, location); | ||||||
|                 .add_instruction_metadata(&instruction, location); |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -610,16 +600,10 @@ impl Type { | |||||||
|             | Type::U32 |             | Type::U32 | ||||||
|             | Type::U64 |             | Type::U64 | ||||||
|             | Type::U128 => TypeCategory::Integer, |             | Type::U128 => TypeCategory::Integer, | ||||||
|             Type::F16 |             Type::F16 | Type::F32B | Type::F32 | Type::F64 | Type::F80 | Type::F128 | Type::F128PPC => { | ||||||
|             | Type::F32B |                 TypeCategory::Real | ||||||
|             | Type::F32 |  | ||||||
|             | Type::F64 |  | ||||||
|             | Type::F80 |  | ||||||
|             | Type::F128 |  | ||||||
|             | Type::F128PPC => TypeCategory::Real, |  | ||||||
|             Type::Bool | Type::Void | Type::CustomType(_) | Type::Array(_, _) | Type::Ptr(_) => { |  | ||||||
|                 TypeCategory::Other |  | ||||||
|             } |             } | ||||||
|  |             Type::Bool | Type::Void | Type::CustomType(_) | Type::Array(_, _) | Type::Ptr(_) => TypeCategory::Other, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -630,23 +614,15 @@ impl Type { | |||||||
|             (I16, I32 | I64 | I128) => Some(Instr::SExt(value, other.clone())), |             (I16, I32 | I64 | I128) => Some(Instr::SExt(value, other.clone())), | ||||||
|             (I32, I64 | I128) => Some(Instr::SExt(value, other.clone())), |             (I32, I64 | I128) => Some(Instr::SExt(value, other.clone())), | ||||||
|             (I64, I128) => Some(Instr::SExt(value, other.clone())), |             (I64, I128) => Some(Instr::SExt(value, other.clone())), | ||||||
|             (I128 | U128, I64 | U64 | I32 | U32 | I16 | U16 | I8 | U8) => { |             (I128 | U128, I64 | U64 | I32 | U32 | I16 | U16 | I8 | U8) => Some(Instr::Trunc(value, other.clone())), | ||||||
|                 Some(Instr::Trunc(value, other.clone())) |             (I64 | U64, I32 | U32 | I16 | U16 | I8 | U8) => Some(Instr::Trunc(value, other.clone())), | ||||||
|             } |  | ||||||
|             (I64 | U64, I32 | U32 | I16 | U16 | I8 | U8) => { |  | ||||||
|                 Some(Instr::Trunc(value, other.clone())) |  | ||||||
|             } |  | ||||||
|             (I32 | U32, I16 | U16 | I8 | U8) => Some(Instr::Trunc(value, other.clone())), |             (I32 | U32, I16 | U16 | I8 | U8) => Some(Instr::Trunc(value, other.clone())), | ||||||
|             (I16 | U16, I8 | U8) => Some(Instr::Trunc(value, other.clone())), |             (I16 | U16, I8 | U8) => Some(Instr::Trunc(value, other.clone())), | ||||||
|             (U8 | I8, U8 | I8 | U16 | I16 | U32 | I32 | U64 | I64 | U128 | I128) => { |             (U8 | I8, U8 | I8 | U16 | I16 | U32 | I32 | U64 | I64 | U128 | I128) => { | ||||||
|                 Some(Instr::ZExt(value, other.clone())) |                 Some(Instr::ZExt(value, other.clone())) | ||||||
|             } |             } | ||||||
|             (U16 | I16, U16 | I16 | U32 | I32 | U64 | I64 | U128 | I128) => { |             (U16 | I16, U16 | I16 | U32 | I32 | U64 | I64 | U128 | I128) => Some(Instr::ZExt(value, other.clone())), | ||||||
|                 Some(Instr::ZExt(value, other.clone())) |             (U32 | I32, U32 | I32 | U64 | I64 | U128 | I128) => Some(Instr::ZExt(value, other.clone())), | ||||||
|             } |  | ||||||
|             (U32 | I32, U32 | I32 | U64 | I64 | U128 | I128) => { |  | ||||||
|                 Some(Instr::ZExt(value, other.clone())) |  | ||||||
|             } |  | ||||||
|             (U64 | I64, U64 | I64 | U128 | I128) => Some(Instr::ZExt(value, other.clone())), |             (U64 | I64, U64 | I64 | U128 | I128) => Some(Instr::ZExt(value, other.clone())), | ||||||
|             (U128 | I128, U128 | I128) => Some(Instr::ZExt(value, other.clone())), |             (U128 | I128, U128 | I128) => Some(Instr::ZExt(value, other.clone())), | ||||||
|             (U8 | U16 | U32 | U64 | U128, F16 | F32 | F32B | F64 | F80 | F128 | F128PPC) => { |             (U8 | U16 | U32 | U64 | U128, F16 | F32 | F32B | F64 | F80 | F128 | F128PPC) => { | ||||||
| @ -667,15 +643,11 @@ impl Type { | |||||||
|             (Ptr(_), I128 | U128 | I64 | U64 | I32 | U32 | I16 | U16 | I8 | U8) => { |             (Ptr(_), I128 | U128 | I64 | U64 | I32 | U32 | I16 | U16 | I8 | U8) => { | ||||||
|                 Some(Instr::PtrToInt(value, other.clone())) |                 Some(Instr::PtrToInt(value, other.clone())) | ||||||
|             } |             } | ||||||
|             (F16, F32 | F32B | F64 | F80 | F128 | F128PPC) => { |             (F16, F32 | F32B | F64 | F80 | F128 | F128PPC) => Some(Instr::FPExt(value, other.clone())), | ||||||
|                 Some(Instr::FPExt(value, other.clone())) |  | ||||||
|             } |  | ||||||
|             (F32 | F32B, F64 | F80 | F128 | F128PPC) => Some(Instr::FPExt(value, other.clone())), |             (F32 | F32B, F64 | F80 | F128 | F128PPC) => Some(Instr::FPExt(value, other.clone())), | ||||||
|             (F64, F80 | F128 | F128PPC) => Some(Instr::FPExt(value, other.clone())), |             (F64, F80 | F128 | F128PPC) => Some(Instr::FPExt(value, other.clone())), | ||||||
|             (F80, F128 | F128PPC) => Some(Instr::FPExt(value, other.clone())), |             (F80, F128 | F128PPC) => Some(Instr::FPExt(value, other.clone())), | ||||||
|             (F128PPC | F128, F80 | F64 | F32B | F32 | F16) => { |             (F128PPC | F128, F80 | F64 | F32B | F32 | F16) => Some(Instr::FPTrunc(value, other.clone())), | ||||||
|                 Some(Instr::FPTrunc(value, other.clone())) |  | ||||||
|             } |  | ||||||
|             (F80, F64 | F32B | F32 | F16) => Some(Instr::FPTrunc(value, other.clone())), |             (F80, F64 | F32B | F32 | F16) => Some(Instr::FPTrunc(value, other.clone())), | ||||||
|             (F64, F32B | F32 | F16) => Some(Instr::FPTrunc(value, other.clone())), |             (F64, F32B | F32 | F16) => Some(Instr::FPTrunc(value, other.clone())), | ||||||
|             (F32B | F32, F16) => Some(Instr::FPTrunc(value, other.clone())), |             (F32B | F32, F16) => Some(Instr::FPTrunc(value, other.clone())), | ||||||
|  | |||||||
| @ -4,6 +4,21 @@ extern fn malloc(size: u64) -> *u8; | |||||||
| extern fn free(ptr: *u8); | extern fn free(ptr: *u8); | ||||||
| extern fn div(numerator: i32, denominator: i32) -> div_t; | extern fn div(numerator: i32, denominator: i32) -> div_t; | ||||||
| 
 | 
 | ||||||
|  | struct String { | ||||||
|  |     inner: *char, | ||||||
|  |     length: u64, | ||||||
|  |     max_length: u64, | ||||||
|  |     must_be_freed: bool, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl binop (lhs: String) + (rhs: *char) -> String { | ||||||
|  |     let mut new = lhs; | ||||||
|  |     let added = from_str(rhs); | ||||||
|  |     concat_strings(&mut new, added); | ||||||
|  |     free_string(&added); | ||||||
|  |     return lhs; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| struct div_t { | struct div_t { | ||||||
|     quotient: i32, |     quotient: i32, | ||||||
|     remainder: i32, |     remainder: i32, | ||||||
| @ -21,13 +36,6 @@ pub fn allocate(size: u64) -> *u8 { | |||||||
|     malloc(size) |     malloc(size) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct String { |  | ||||||
|     inner: *char, |  | ||||||
|     length: u64, |  | ||||||
|     max_length: u64, |  | ||||||
|     must_be_freed: bool, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub fn new_string() -> String { | pub fn new_string() -> String { | ||||||
|     String { |     String { | ||||||
|         inner: allocate(0), |         inner: allocate(0), | ||||||
|  | |||||||
| @ -117,6 +117,7 @@ impl ast::Module { | |||||||
|                             block.2.as_meta(module_id), |                             block.2.as_meta(module_id), | ||||||
|                         ), |                         ), | ||||||
|                         meta: signature_range.as_meta(module_id), |                         meta: signature_range.as_meta(module_id), | ||||||
|  |                         exported: false, | ||||||
|                     }); |                     }); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  | |||||||
| @ -49,6 +49,7 @@ where | |||||||
|         return_type: ty.clone(), |         return_type: ty.clone(), | ||||||
|         fn_kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicSimpleInstr(fun))), |         fn_kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicSimpleInstr(fun))), | ||||||
|         meta: Default::default(), |         meta: Default::default(), | ||||||
|  |         exported: false, | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -63,6 +64,7 @@ where | |||||||
|         return_type: TypeKind::Bool, |         return_type: TypeKind::Bool, | ||||||
|         fn_kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicBooleanInstr(fun))), |         fn_kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicBooleanInstr(fun))), | ||||||
|         meta: Default::default(), |         meta: Default::default(), | ||||||
|  |         exported: false, | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -15,7 +15,7 @@ use scope::*; | |||||||
| 
 | 
 | ||||||
| use crate::{ | use crate::{ | ||||||
|     mir::{ |     mir::{ | ||||||
|         self, implement::TypeCategory, pass::ScopeBinopKey, CustomTypeKey, FunctionDefinitionKind, NamedVariableRef, |         self, implement::TypeCategory, pass::BinopKey, CustomTypeKey, FunctionDefinitionKind, NamedVariableRef, | ||||||
|         SourceModuleId, StructField, StructType, TypeDefinition, TypeDefinitionKind, TypeKind, WhileStatement, |         SourceModuleId, StructField, StructType, TypeDefinition, TypeDefinitionKind, TypeKind, WhileStatement, | ||||||
|     }, |     }, | ||||||
|     util::try_all, |     util::try_all, | ||||||
| @ -214,8 +214,12 @@ impl mir::Module { | |||||||
| 
 | 
 | ||||||
|         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!( | ||||||
|  |                 "binop.{}.{:?}.{}.{}", | ||||||
|  |                 binop.lhs.1, binop.op, binop.rhs.1, binop.return_type | ||||||
|  |             ); | ||||||
|             binops.insert( |             binops.insert( | ||||||
|                 ScopeBinopKey { |                 BinopKey { | ||||||
|                     params: (binop.lhs.1.clone(), binop.rhs.1.clone()), |                     params: (binop.lhs.1.clone(), binop.rhs.1.clone()), | ||||||
|                     operator: binop.op, |                     operator: binop.op, | ||||||
|                 }, |                 }, | ||||||
| @ -224,16 +228,14 @@ impl mir::Module { | |||||||
|                     return_ty: binop.return_type.clone(), |                     return_ty: binop.return_type.clone(), | ||||||
|                     kind: match &binop.fn_kind { |                     kind: match &binop.fn_kind { | ||||||
|                         FunctionDefinitionKind::Local(block, metadata) => { |                         FunctionDefinitionKind::Local(block, metadata) => { | ||||||
|                             let binop_fn_name = format!( |  | ||||||
|                                 "binop.{}.{:?}.{}.{}", |  | ||||||
|                                 binop.lhs.1, binop.op, binop.rhs.1, binop.return_type |  | ||||||
|                             ); |  | ||||||
|                             let ir_function = module.function( |                             let ir_function = module.function( | ||||||
|                                 &binop_fn_name, |                                 &binop_fn_name, | ||||||
|                                 binop.return_type.get_type(&type_values), |                                 binop.return_type.get_type(&type_values), | ||||||
|                                 vec![binop.lhs.1.get_type(&type_values), binop.rhs.1.get_type(&type_values)], |                                 vec![binop.lhs.1.get_type(&type_values), binop.rhs.1.get_type(&type_values)], | ||||||
|                                 FunctionFlags { |                                 FunctionFlags { | ||||||
|                                     inline: true, |                                     inline: true, | ||||||
|  |                                     is_pub: binop.exported, | ||||||
|  |                                     is_imported: binop.exported, | ||||||
|                                     ..Default::default() |                                     ..Default::default() | ||||||
|                                 }, |                                 }, | ||||||
|                             ); |                             ); | ||||||
| @ -289,7 +291,18 @@ impl mir::Module { | |||||||
| 
 | 
 | ||||||
|                             StackBinopFunctionKind::UserGenerated(ir_function) |                             StackBinopFunctionKind::UserGenerated(ir_function) | ||||||
|                         } |                         } | ||||||
|                         FunctionDefinitionKind::Extern(_) => todo!(), |                         FunctionDefinitionKind::Extern(imported) => { | ||||||
|  |                             StackBinopFunctionKind::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)], | ||||||
|  |                                 FunctionFlags { | ||||||
|  |                                     is_extern: true, | ||||||
|  |                                     is_imported: *imported, | ||||||
|  |                                     ..FunctionFlags::default() | ||||||
|  |                                 }, | ||||||
|  |                             )) | ||||||
|  |                         } | ||||||
|                         FunctionDefinitionKind::Intrinsic(intrinsic_function) => { |                         FunctionDefinitionKind::Intrinsic(intrinsic_function) => { | ||||||
|                             StackBinopFunctionKind::Intrinsic(intrinsic_function) |                             StackBinopFunctionKind::Intrinsic(intrinsic_function) | ||||||
|                         } |                         } | ||||||
| @ -704,7 +717,7 @@ impl mir::Expression { | |||||||
|                 let lhs = lhs_val.instr(); |                 let lhs = lhs_val.instr(); | ||||||
|                 let rhs = rhs_val.instr(); |                 let rhs = rhs_val.instr(); | ||||||
| 
 | 
 | ||||||
|                 let operation = scope.binops.get(&ScopeBinopKey { |                 let operation = scope.binops.get(&BinopKey { | ||||||
|                     params: (lhs_val.1.clone(), rhs_val.1.clone()), |                     params: (lhs_val.1.clone(), rhs_val.1.clone()), | ||||||
|                     operator: *binop, |                     operator: *binop, | ||||||
|                 }); |                 }); | ||||||
|  | |||||||
| @ -8,7 +8,7 @@ use reid_lib::{ | |||||||
| 
 | 
 | ||||||
| use crate::{ | use crate::{ | ||||||
|     lexer::FullToken, |     lexer::FullToken, | ||||||
|     mir::{pass::ScopeBinopKey, CustomTypeKey, SourceModuleId, TypeDefinition, TypeKind}, |     mir::{pass::BinopKey, CustomTypeKey, SourceModuleId, TypeDefinition, TypeKind}, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| use super::{allocator::Allocator, ErrorKind, IntrinsicFunction, ModuleCodegen}; | use super::{allocator::Allocator, ErrorKind, IntrinsicFunction, ModuleCodegen}; | ||||||
| @ -24,7 +24,7 @@ pub struct Scope<'ctx, 'scope> { | |||||||
|     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) functions: &'scope HashMap<String, Function<'ctx>>, |     pub(super) functions: &'scope HashMap<String, Function<'ctx>>, | ||||||
|     pub(super) binops: &'scope HashMap<ScopeBinopKey, StackBinopDefinition<'ctx>>, |     pub(super) binops: &'scope HashMap<BinopKey, StackBinopDefinition<'ctx>>, | ||||||
|     pub(super) stack_values: HashMap<String, StackValue>, |     pub(super) stack_values: HashMap<String, StackValue>, | ||||||
|     pub(super) debug: Option<Debug<'ctx>>, |     pub(super) debug: Option<Debug<'ctx>>, | ||||||
|     pub(super) allocator: Rc<RefCell<Allocator>>, |     pub(super) allocator: Rc<RefCell<Allocator>>, | ||||||
| @ -150,15 +150,9 @@ impl<'ctx> StackBinopDefinition<'ctx> { | |||||||
|             StackBinopFunctionKind::UserGenerated(ir) => { |             StackBinopFunctionKind::UserGenerated(ir) => { | ||||||
|                 let instr = scope |                 let instr = scope | ||||||
|                     .block |                     .block | ||||||
|                     .build(Instr::FunctionCall( |                     .build(Instr::FunctionCall(ir.value(), vec![lhs.instr(), rhs.instr()])) | ||||||
|                         ir.value(), |  | ||||||
|                         vec![lhs.instr(), rhs.instr()], |  | ||||||
|                     )) |  | ||||||
|                     .unwrap(); |                     .unwrap(); | ||||||
|                 Ok(StackValue( |                 Ok(StackValue(StackValueKind::Immutable(instr), self.return_ty.clone())) | ||||||
|                     StackValueKind::Immutable(instr), |  | ||||||
|                     self.return_ty.clone(), |  | ||||||
|                 )) |  | ||||||
|             } |             } | ||||||
|             StackBinopFunctionKind::Intrinsic(fun) => fun.codegen(scope, &[&lhs, &rhs]), |             StackBinopFunctionKind::Intrinsic(fun) => fun.codegen(scope, &[&lhs, &rhs]), | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -130,7 +130,7 @@ pub fn perform_all_passes<'map>( | |||||||
|         for intrinsic in form_intrinsic_binops() { |         for intrinsic in form_intrinsic_binops() { | ||||||
|             binops |             binops | ||||||
|                 .set( |                 .set( | ||||||
|                     mir::pass::ScopeBinopKey { |                     mir::pass::BinopKey { | ||||||
|                         params: (intrinsic.lhs.1.clone(), intrinsic.rhs.1.clone()), |                         params: (intrinsic.lhs.1.clone(), intrinsic.rhs.1.clone()), | ||||||
|                         operator: intrinsic.op, |                         operator: intrinsic.op, | ||||||
|                     }, |                     }, | ||||||
|  | |||||||
| @ -66,8 +66,14 @@ impl Display for BinopDefinition { | |||||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||||
|         write!( |         write!( | ||||||
|             f, |             f, | ||||||
|             "impl binop ({}: {:#}) {} ({}: {:#}) -> {:#} ", |             "{}impl binop ({}: {:#}) {} ({}: {:#}) -> {:#} ", | ||||||
|             self.lhs.0, self.lhs.1, self.op, self.rhs.0, self.rhs.1, self.return_type |             if self.exported { "exported " } else { "" }, | ||||||
|  |             self.lhs.0, | ||||||
|  |             self.lhs.1, | ||||||
|  |             self.op, | ||||||
|  |             self.rhs.0, | ||||||
|  |             self.rhs.1, | ||||||
|  |             self.return_type | ||||||
|         )?; |         )?; | ||||||
|         Display::fmt(&self.fn_kind, f) |         Display::fmt(&self.fn_kind, f) | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -11,7 +11,10 @@ use crate::{ | |||||||
|     codegen::scope, |     codegen::scope, | ||||||
|     compile_module, |     compile_module, | ||||||
|     error_raporting::{ErrorModules, ReidError}, |     error_raporting::{ErrorModules, ReidError}, | ||||||
|     mir::{CustomTypeKey, FunctionDefinitionKind, SourceModuleId, TypeDefinition, TypeKind}, |     mir::{ | ||||||
|  |         pass::BinopKey, BinopDefinition, CustomTypeKey, FunctionDefinitionKind, SourceModuleId, TypeDefinition, | ||||||
|  |         TypeKind, | ||||||
|  |     }, | ||||||
|     parse_module, |     parse_module, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| @ -110,6 +113,7 @@ impl<'map> Pass for LinkerPass<'map> { | |||||||
|         let mut modules_to_process: Vec<Rc<RefCell<_>>> = modules.values().cloned().collect(); |         let mut modules_to_process: Vec<Rc<RefCell<_>>> = modules.values().cloned().collect(); | ||||||
| 
 | 
 | ||||||
|         let mut already_imported_types = HashSet::<CustomTypeKey>::new(); |         let mut already_imported_types = HashSet::<CustomTypeKey>::new(); | ||||||
|  |         let mut already_imported_binops = HashSet::<BinopKey>::new(); | ||||||
| 
 | 
 | ||||||
|         while let Some(module) = modules_to_process.pop() { |         while let Some(module) = modules_to_process.pop() { | ||||||
|             let mut extern_types = HashMap::new(); |             let mut extern_types = HashMap::new(); | ||||||
| @ -232,10 +236,39 @@ impl<'map> Pass for LinkerPass<'map> { | |||||||
|                         kind: super::FunctionDefinitionKind::Extern(true), |                         kind: super::FunctionDefinitionKind::Extern(true), | ||||||
|                     }); |                     }); | ||||||
|                 } else if let Some(ty) = imported.typedefs.iter_mut().find(|f| f.name == *import_name) { |                 } else if let Some(ty) = imported.typedefs.iter_mut().find(|f| f.name == *import_name) { | ||||||
|                     dbg!("hello??"); |  | ||||||
|                     let external_key = CustomTypeKey(ty.name.clone(), ty.source_module); |                     let external_key = CustomTypeKey(ty.name.clone(), ty.source_module); | ||||||
|  |                     let imported_ty = TypeKind::CustomType(external_key.clone()); | ||||||
|                     imported_types.push((external_key, true)); |                     imported_types.push((external_key, true)); | ||||||
|                     dbg!(&imported_types); | 
 | ||||||
|  |                     for binop in &mut imported.binop_defs { | ||||||
|  |                         if binop.lhs.1 != imported_ty && binop.rhs.1 != imported_ty { | ||||||
|  |                             continue; | ||||||
|  |                         } | ||||||
|  |                         let binop_key = BinopKey { | ||||||
|  |                             params: (binop.lhs.1.clone(), binop.rhs.1.clone()), | ||||||
|  |                             operator: binop.op, | ||||||
|  |                         }; | ||||||
|  |                         if already_imported_binops.contains(&binop_key) { | ||||||
|  |                             continue; | ||||||
|  |                         } | ||||||
|  |                         binop.exported = true; | ||||||
|  |                         already_imported_binops.insert(binop_key); | ||||||
|  |                         match &binop.fn_kind { | ||||||
|  |                             FunctionDefinitionKind::Local(block, metadata) => { | ||||||
|  |                                 importer_module.binop_defs.push(BinopDefinition { | ||||||
|  |                                     lhs: binop.lhs.clone(), | ||||||
|  |                                     op: binop.op, | ||||||
|  |                                     rhs: binop.rhs.clone(), | ||||||
|  |                                     return_type: binop.return_type.clone(), | ||||||
|  |                                     fn_kind: FunctionDefinitionKind::Extern(true), | ||||||
|  |                                     meta: binop.meta.clone(), | ||||||
|  |                                     exported: false, | ||||||
|  |                                 }); | ||||||
|  |                             } | ||||||
|  |                             FunctionDefinitionKind::Extern(_) => {} | ||||||
|  |                             FunctionDefinitionKind::Intrinsic(_) => {} | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|                 } else { |                 } else { | ||||||
|                     state.ok::<_, Infallible>( |                     state.ok::<_, Infallible>( | ||||||
|                         Err(ErrorKind::ImportDoesNotExist(module_name.clone(), import_name.clone())), |                         Err(ErrorKind::ImportDoesNotExist(module_name.clone(), import_name.clone())), | ||||||
|  | |||||||
| @ -370,6 +370,8 @@ pub struct BinopDefinition { | |||||||
|     pub return_type: TypeKind, |     pub return_type: TypeKind, | ||||||
|     pub fn_kind: FunctionDefinitionKind, |     pub fn_kind: FunctionDefinitionKind, | ||||||
|     pub meta: Metadata, |     pub meta: Metadata, | ||||||
|  |     // Wether this binop definition has been imported into another module.
 | ||||||
|  |     pub exported: bool, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl BinopDefinition { | impl BinopDefinition { | ||||||
|  | |||||||
| @ -117,7 +117,7 @@ impl<Key: std::hash::Hash + Eq, T: Clone + std::fmt::Debug> Storage<Key, T> { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub type BinopMap = Storage<ScopeBinopKey, ScopeBinopDef>; | pub type BinopMap = Storage<BinopKey, ScopeBinopDef>; | ||||||
| 
 | 
 | ||||||
| #[derive(Clone, Default, Debug)] | #[derive(Clone, Default, Debug)] | ||||||
| pub struct Scope<Data: Clone + Default> { | pub struct Scope<Data: Clone + Default> { | ||||||
| @ -182,7 +182,7 @@ pub struct ScopeVariable { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Clone, Debug, Eq)] | #[derive(Clone, Debug, Eq)] | ||||||
| pub struct ScopeBinopKey { | pub struct BinopKey { | ||||||
|     pub params: (TypeKind, TypeKind), |     pub params: (TypeKind, TypeKind), | ||||||
|     pub operator: BinaryOperator, |     pub operator: BinaryOperator, | ||||||
| } | } | ||||||
| @ -194,7 +194,7 @@ pub enum CommutativeKind { | |||||||
|     Any, |     Any, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl PartialEq for ScopeBinopKey { | impl PartialEq for BinopKey { | ||||||
|     fn eq(&self, other: &Self) -> bool { |     fn eq(&self, other: &Self) -> bool { | ||||||
|         if self.operator != other.operator { |         if self.operator != other.operator { | ||||||
|             return false; |             return false; | ||||||
| @ -216,7 +216,7 @@ impl PartialEq for ScopeBinopKey { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl std::hash::Hash for ScopeBinopKey { | impl std::hash::Hash for BinopKey { | ||||||
|     fn hash<H: std::hash::Hasher>(&self, state: &mut H) { |     fn hash<H: std::hash::Hasher>(&self, state: &mut H) { | ||||||
|         if self.operator.is_commutative() { |         if self.operator.is_commutative() { | ||||||
|             let mut sorted = vec![&self.params.0, &self.params.1]; |             let mut sorted = vec![&self.params.0, &self.params.1]; | ||||||
| @ -336,7 +336,7 @@ impl Context { | |||||||
|             scope |             scope | ||||||
|                 .binops |                 .binops | ||||||
|                 .set( |                 .set( | ||||||
|                     ScopeBinopKey { |                     BinopKey { | ||||||
|                         params: (intrinsic.lhs.1.clone(), intrinsic.rhs.1.clone()), |                         params: (intrinsic.lhs.1.clone(), intrinsic.rhs.1.clone()), | ||||||
|                         operator: intrinsic.op, |                         operator: intrinsic.op, | ||||||
|                     }, |                     }, | ||||||
| @ -374,7 +374,7 @@ impl Module { | |||||||
|             scope |             scope | ||||||
|                 .binops |                 .binops | ||||||
|                 .set( |                 .set( | ||||||
|                     ScopeBinopKey { |                     BinopKey { | ||||||
|                         params: (binop.lhs.1.clone(), binop.rhs.1.clone()), |                         params: (binop.lhs.1.clone(), binop.rhs.1.clone()), | ||||||
|                         operator: binop.op, |                         operator: binop.op, | ||||||
|                     }, |                     }, | ||||||
|  | |||||||
| @ -422,7 +422,7 @@ impl Expression { | |||||||
|                     ); |                     ); | ||||||
|                 }; |                 }; | ||||||
| 
 | 
 | ||||||
|                 let binops = state.scope.binops.filter(&pass::ScopeBinopKey { |                 let binops = state.scope.binops.filter(&pass::BinopKey { | ||||||
|                     params: (lhs_type.clone(), rhs_type.clone()), |                     params: (lhs_type.clone(), rhs_type.clone()), | ||||||
|                     operator: *op, |                     operator: *op, | ||||||
|                 }); |                 }); | ||||||
|  | |||||||
| @ -20,7 +20,7 @@ use crate::{ | |||||||
| 
 | 
 | ||||||
| use super::{ | use super::{ | ||||||
|     super::{ |     super::{ | ||||||
|         pass::{Pass, PassResult, PassState, ScopeBinopKey}, |         pass::{BinopKey, Pass, PassResult, PassState}, | ||||||
|         TypeKind::*, |         TypeKind::*, | ||||||
|         VagueType::*, |         VagueType::*, | ||||||
|     }, |     }, | ||||||
| @ -62,7 +62,7 @@ impl<'t> Pass for TypeInference<'t> { | |||||||
| 
 | 
 | ||||||
|         let mut seen_binops = HashSet::new(); |         let mut seen_binops = HashSet::new(); | ||||||
|         for binop in &module.binop_defs { |         for binop in &module.binop_defs { | ||||||
|             let binop_key = ScopeBinopKey { |             let binop_key = BinopKey { | ||||||
|                 params: (binop.lhs.1.clone(), binop.rhs.1.clone()), |                 params: (binop.lhs.1.clone(), binop.rhs.1.clone()), | ||||||
|                 operator: binop.op, |                 operator: binop.op, | ||||||
|             }; |             }; | ||||||
|  | |||||||
| @ -10,7 +10,7 @@ use crate::{ | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| use super::{ | use super::{ | ||||||
|     super::pass::{ScopeBinopDef, ScopeBinopKey, Storage}, |     super::pass::{BinopKey, ScopeBinopDef, Storage}, | ||||||
|     ErrorKind, |     ErrorKind, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user