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> { | ||||
|     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 | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -95,11 +95,11 @@ impl TypeKind { | ||||
| 
 | ||||
|     /// Return the type that is the result of a binary operator between two
 | ||||
|     /// values of this type
 | ||||
|     pub fn simple_binop_type(&self, op: &BinaryOperator) -> TypeKind { | ||||
|         // TODO make some type of mechanism that allows to binop two values of
 | ||||
|         // differing types..
 | ||||
|         // TODO Return None for arrays later
 | ||||
|         match op { | ||||
|     pub fn simple_binop_type(&self, op: &BinaryOperator) -> Option<TypeKind> { | ||||
|         if !self.category().is_simple_maths() { | ||||
|             return None; | ||||
|         } | ||||
|         Some(match op { | ||||
|             BinaryOperator::Add => self.clone(), | ||||
|             BinaryOperator::Minus => self.clone(), | ||||
|             BinaryOperator::Mult => self.clone(), | ||||
| @ -107,7 +107,7 @@ impl TypeKind { | ||||
|             BinaryOperator::Cmp(_) => TypeKind::Bool, | ||||
|             BinaryOperator::Div => self.clone(), | ||||
|             BinaryOperator::Mod => self.clone(), | ||||
|         } | ||||
|         }) | ||||
|     } | ||||
| 
 | ||||
|     pub fn binop_type( | ||||
| @ -127,6 +127,9 @@ impl TypeKind { | ||||
|     /// 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.
 | ||||
|     pub fn simple_binop_hint(&self, op: &BinaryOperator) -> Option<TypeKind> { | ||||
|         if !self.category().is_simple_maths() { | ||||
|             return None; | ||||
|         } | ||||
|         match op { | ||||
|             BinaryOperator::Add | ||||
|             | BinaryOperator::Minus | ||||
| @ -275,7 +278,7 @@ impl TypeKind { | ||||
|             | TypeKind::F80 | ||||
|             | TypeKind::F128PPC => TypeCategory::Real, | ||||
|             TypeKind::Void => TypeCategory::Other, | ||||
|             TypeKind::Bool => TypeCategory::Other, | ||||
|             TypeKind::Bool => TypeCategory::Bool, | ||||
|             TypeKind::Array(_, _) => TypeCategory::Other, | ||||
|             TypeKind::CustomType(..) => TypeCategory::Other, | ||||
|             TypeKind::Borrow(_, _) => TypeCategory::Other, | ||||
| @ -329,10 +332,23 @@ impl BinaryOperator { | ||||
| pub enum TypeCategory { | ||||
|     Integer, | ||||
|     Real, | ||||
|     Bool, | ||||
|     Other, | ||||
|     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 { | ||||
|     pub fn get_field_ty(&self, name: &String) -> Option<&TypeKind> { | ||||
|         self.0 | ||||
|  | ||||
| @ -64,14 +64,16 @@ pub enum ErrorKind { | ||||
|     ImpossibleMutableBorrow(String), | ||||
|     #[error("Cannot declare variable {0} as mutable, when it's type is immutable")] | ||||
|     ImpossibleMutLet(String), | ||||
|     #[error("Cannot produce a negative unsigned value of type {0}!")] | ||||
|     #[error("Cannot produce a negative unsigned value of type {0}")] | ||||
|     NegativeUnsignedValue(TypeKind), | ||||
|     #[error("Cannot cast type {0} into type {1}!")] | ||||
|     #[error("Cannot cast type {0} into type {1}")] | ||||
|     NotCastableTo(TypeKind, TypeKind), | ||||
|     #[error("Cannot divide by zero")] | ||||
|     DivideZero, | ||||
|     #[error("Binary operation between {0} and {1} is already defined!")] | ||||
|     BinaryOpAlreadyDefined(TypeKind, TypeKind), | ||||
|     #[error("Binary operation {0} between {1} and {2} is already defined")] | ||||
|     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
 | ||||
| @ -580,7 +582,9 @@ impl Expression { | ||||
|                         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) => { | ||||
|  | ||||
| @ -65,9 +65,12 @@ impl<'t> Pass for TypeInference<'t> { | ||||
|                 params: (binop.lhs.1.clone(), binop.rhs.1.clone()), | ||||
|                 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( | ||||
|                     &vec![ErrorKind::BinaryOpAlreadyDefined( | ||||
|                         binop.op, | ||||
|                         binop.lhs.1.clone(), | ||||
|                         binop.rhs.1.clone(), | ||||
|                     )], | ||||
| @ -323,7 +326,17 @@ impl Expression { | ||||
|                 } else { | ||||
|                     let typeref = lhs_ref.narrow(&rhs_ref).unwrap(); | ||||
|                     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()) | ||||
|                 } | ||||
|             } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user