Embrace having megaintrinsic binops
This commit is contained in:
		
							parent
							
								
									ccdefe7033
								
							
						
					
					
						commit
						f6425fc37e
					
				
							
								
								
									
										0
									
								
								.rustfmt.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								.rustfmt.toml
									
									
									
									
									
										Normal file
									
								
							| @ -47,42 +47,6 @@ pub fn form_intrinsics() -> Vec<FunctionDefinition> { | |||||||
| pub fn form_intrinsic_binops() -> Vec<BinopDefinition> { | pub fn form_intrinsic_binops() -> Vec<BinopDefinition> { | ||||||
|     let mut intrinsics = Vec::new(); |     let mut intrinsics = Vec::new(); | ||||||
| 
 | 
 | ||||||
|     intrinsics.push(intrinsic_binop( |  | ||||||
|         BinaryOperator::Add, |  | ||||||
|         TypeKind::U8, |  | ||||||
|         TypeKind::U8, |  | ||||||
|         TypeKind::U8, |  | ||||||
|         IntrinsicIAdd(TypeKind::U8), |  | ||||||
|     )); |  | ||||||
|     intrinsics.push(intrinsic_binop( |  | ||||||
|         BinaryOperator::Add, |  | ||||||
|         TypeKind::U32, |  | ||||||
|         TypeKind::U32, |  | ||||||
|         TypeKind::U32, |  | ||||||
|         IntrinsicIAdd(TypeKind::U32), |  | ||||||
|     )); |  | ||||||
|     intrinsics.push(intrinsic_binop( |  | ||||||
|         BinaryOperator::Add, |  | ||||||
|         TypeKind::U16, |  | ||||||
|         TypeKind::U16, |  | ||||||
|         TypeKind::U16, |  | ||||||
|         IntrinsicIAdd(TypeKind::U16), |  | ||||||
|     )); |  | ||||||
|     intrinsics.push(intrinsic_binop( |  | ||||||
|         BinaryOperator::Div, |  | ||||||
|         TypeKind::U16, |  | ||||||
|         TypeKind::U16, |  | ||||||
|         TypeKind::U16, |  | ||||||
|         IntrinsicUDiv(TypeKind::U16), |  | ||||||
|     )); |  | ||||||
|     intrinsics.push(intrinsic_binop( |  | ||||||
|         BinaryOperator::Mod, |  | ||||||
|         TypeKind::U16, |  | ||||||
|         TypeKind::U16, |  | ||||||
|         TypeKind::U16, |  | ||||||
|         IntrinsicUMod(TypeKind::U16), |  | ||||||
|     )); |  | ||||||
| 
 |  | ||||||
|     intrinsics |     intrinsics | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -95,11 +95,11 @@ impl TypeKind { | |||||||
| 
 | 
 | ||||||
|     /// Return the type that is the result of a binary operator between two
 |     /// Return the type that is the result of a binary operator between two
 | ||||||
|     /// values of this type
 |     /// values of this type
 | ||||||
|     pub fn simple_binop_type(&self, op: &BinaryOperator) -> TypeKind { |     pub fn simple_binop_type(&self, op: &BinaryOperator) -> Option<TypeKind> { | ||||||
|         // TODO make some type of mechanism that allows to binop two values of
 |         if !self.category().is_simple_maths() { | ||||||
|         // differing types..
 |             return None; | ||||||
|         // TODO Return None for arrays later
 |         } | ||||||
|         match op { |         Some(match op { | ||||||
|             BinaryOperator::Add => self.clone(), |             BinaryOperator::Add => self.clone(), | ||||||
|             BinaryOperator::Minus => self.clone(), |             BinaryOperator::Minus => self.clone(), | ||||||
|             BinaryOperator::Mult => self.clone(), |             BinaryOperator::Mult => self.clone(), | ||||||
| @ -107,7 +107,7 @@ impl TypeKind { | |||||||
|             BinaryOperator::Cmp(_) => TypeKind::Bool, |             BinaryOperator::Cmp(_) => TypeKind::Bool, | ||||||
|             BinaryOperator::Div => self.clone(), |             BinaryOperator::Div => self.clone(), | ||||||
|             BinaryOperator::Mod => self.clone(), |             BinaryOperator::Mod => self.clone(), | ||||||
|         } |         }) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn binop_type( |     pub fn binop_type( | ||||||
| @ -127,6 +127,9 @@ impl TypeKind { | |||||||
|     /// Reverse of binop_type, where the given hint is the known required output
 |     /// Reverse of binop_type, where the given hint is the known required output
 | ||||||
|     /// type of the binop, and the output is the hint for the lhs/rhs type.
 |     /// type of the binop, and the output is the hint for the lhs/rhs type.
 | ||||||
|     pub fn simple_binop_hint(&self, op: &BinaryOperator) -> Option<TypeKind> { |     pub fn simple_binop_hint(&self, op: &BinaryOperator) -> Option<TypeKind> { | ||||||
|  |         if !self.category().is_simple_maths() { | ||||||
|  |             return None; | ||||||
|  |         } | ||||||
|         match op { |         match op { | ||||||
|             BinaryOperator::Add |             BinaryOperator::Add | ||||||
|             | BinaryOperator::Minus |             | BinaryOperator::Minus | ||||||
| @ -275,7 +278,7 @@ impl TypeKind { | |||||||
|             | TypeKind::F80 |             | TypeKind::F80 | ||||||
|             | TypeKind::F128PPC => TypeCategory::Real, |             | TypeKind::F128PPC => TypeCategory::Real, | ||||||
|             TypeKind::Void => TypeCategory::Other, |             TypeKind::Void => TypeCategory::Other, | ||||||
|             TypeKind::Bool => TypeCategory::Other, |             TypeKind::Bool => TypeCategory::Bool, | ||||||
|             TypeKind::Array(_, _) => TypeCategory::Other, |             TypeKind::Array(_, _) => TypeCategory::Other, | ||||||
|             TypeKind::CustomType(..) => TypeCategory::Other, |             TypeKind::CustomType(..) => TypeCategory::Other, | ||||||
|             TypeKind::Borrow(_, _) => TypeCategory::Other, |             TypeKind::Borrow(_, _) => TypeCategory::Other, | ||||||
| @ -329,10 +332,23 @@ impl BinaryOperator { | |||||||
| pub enum TypeCategory { | pub enum TypeCategory { | ||||||
|     Integer, |     Integer, | ||||||
|     Real, |     Real, | ||||||
|  |     Bool, | ||||||
|     Other, |     Other, | ||||||
|     TypeRef, |     TypeRef, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | impl TypeCategory { | ||||||
|  |     pub fn is_simple_maths(&self) -> bool { | ||||||
|  |         match self { | ||||||
|  |             TypeCategory::Integer => true, | ||||||
|  |             TypeCategory::Real => true, | ||||||
|  |             TypeCategory::Other => false, | ||||||
|  |             TypeCategory::TypeRef => false, | ||||||
|  |             TypeCategory::Bool => true, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| impl StructType { | impl StructType { | ||||||
|     pub fn get_field_ty(&self, name: &String) -> Option<&TypeKind> { |     pub fn get_field_ty(&self, name: &String) -> Option<&TypeKind> { | ||||||
|         self.0 |         self.0 | ||||||
|  | |||||||
| @ -64,14 +64,16 @@ pub enum ErrorKind { | |||||||
|     ImpossibleMutableBorrow(String), |     ImpossibleMutableBorrow(String), | ||||||
|     #[error("Cannot declare variable {0} as mutable, when it's type is immutable")] |     #[error("Cannot declare variable {0} as mutable, when it's type is immutable")] | ||||||
|     ImpossibleMutLet(String), |     ImpossibleMutLet(String), | ||||||
|     #[error("Cannot produce a negative unsigned value of type {0}!")] |     #[error("Cannot produce a negative unsigned value of type {0}")] | ||||||
|     NegativeUnsignedValue(TypeKind), |     NegativeUnsignedValue(TypeKind), | ||||||
|     #[error("Cannot cast type {0} into type {1}!")] |     #[error("Cannot cast type {0} into type {1}")] | ||||||
|     NotCastableTo(TypeKind, TypeKind), |     NotCastableTo(TypeKind, TypeKind), | ||||||
|     #[error("Cannot divide by zero")] |     #[error("Cannot divide by zero")] | ||||||
|     DivideZero, |     DivideZero, | ||||||
|     #[error("Binary operation between {0} and {1} is already defined!")] |     #[error("Binary operation {0} between {1} and {2} is already defined")] | ||||||
|     BinaryOpAlreadyDefined(TypeKind, TypeKind), |     BinaryOpAlreadyDefined(BinaryOperator, TypeKind, TypeKind), | ||||||
|  |     #[error("Binary operation {0} between {1} and {2} is not defined")] | ||||||
|  |     InvalidBinop(BinaryOperator, TypeKind, TypeKind), | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Struct used to implement a type-checking pass that can be performed on the
 | /// Struct used to implement a type-checking pass that can be performed on the
 | ||||||
| @ -580,7 +582,9 @@ impl Expression { | |||||||
|                         rhs.typecheck(state, &typerefs, Some(&collapsed)).ok(); |                         rhs.typecheck(state, &typerefs, Some(&collapsed)).ok(); | ||||||
|                     } |                     } | ||||||
| 
 | 
 | ||||||
|                     Ok(both_t.simple_binop_type(op)) |                     both_t | ||||||
|  |                         .simple_binop_type(op) | ||||||
|  |                         .ok_or(ErrorKind::InvalidBinop(*op, lhs_type, rhs_type)) | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             ExprKind::FunctionCall(function_call) => { |             ExprKind::FunctionCall(function_call) => { | ||||||
|  | |||||||
| @ -65,9 +65,12 @@ impl<'t> Pass for TypeInference<'t> { | |||||||
|                 params: (binop.lhs.1.clone(), binop.rhs.1.clone()), |                 params: (binop.lhs.1.clone(), binop.rhs.1.clone()), | ||||||
|                 operator: binop.op, |                 operator: binop.op, | ||||||
|             }; |             }; | ||||||
|             if seen_binops.contains(&binop_key) { |             if seen_binops.contains(&binop_key) | ||||||
|  |                 || (binop.lhs == binop.rhs && binop.lhs.1.category().is_simple_maths()) | ||||||
|  |             { | ||||||
|                 state.note_errors( |                 state.note_errors( | ||||||
|                     &vec![ErrorKind::BinaryOpAlreadyDefined( |                     &vec![ErrorKind::BinaryOpAlreadyDefined( | ||||||
|  |                         binop.op, | ||||||
|                         binop.lhs.1.clone(), |                         binop.lhs.1.clone(), | ||||||
|                         binop.rhs.1.clone(), |                         binop.rhs.1.clone(), | ||||||
|                     )], |                     )], | ||||||
| @ -323,7 +326,17 @@ impl Expression { | |||||||
|                 } else { |                 } else { | ||||||
|                     let typeref = lhs_ref.narrow(&rhs_ref).unwrap(); |                     let typeref = lhs_ref.narrow(&rhs_ref).unwrap(); | ||||||
|                     Ok(type_refs |                     Ok(type_refs | ||||||
|                         .from_type(&typeref.resolve_deep().unwrap().simple_binop_type(op)) |                         .from_type( | ||||||
|  |                             &typeref | ||||||
|  |                                 .resolve_deep() | ||||||
|  |                                 .unwrap() | ||||||
|  |                                 .simple_binop_type(op) | ||||||
|  |                                 .ok_or(ErrorKind::InvalidBinop( | ||||||
|  |                                     *op, | ||||||
|  |                                     lhs_ref.resolve_deep().unwrap(), | ||||||
|  |                                     rhs_ref.resolve_deep().unwrap(), | ||||||
|  |                                 ))?, | ||||||
|  |                         ) | ||||||
|                         .unwrap()) |                         .unwrap()) | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user