Improve type inferrence for binops
This commit is contained in:
		
							parent
							
								
									2709eb8749
								
							
						
					
					
						commit
						469ce3ce77
					
				| @ -1,17 +1,6 @@ | |||||||
| // Arithmetic, function calls and imports! | // Arithmetic, function calls and imports! | ||||||
| 
 | 
 | ||||||
| import std::print; |  | ||||||
| import std::from_str; |  | ||||||
| import std::add_num_to_str; |  | ||||||
| import std::free_string; |  | ||||||
| 
 |  | ||||||
| fn main() -> u32 { | fn main() -> u32 { | ||||||
|   for i in 0 .. 15 { |  | ||||||
|     let mut text = from_str("num: "); |  | ||||||
|     add_num_to_str(&mut text, i); |  | ||||||
|     print(text); |  | ||||||
|     free_string(&text); |  | ||||||
|   } |  | ||||||
| 
 | 
 | ||||||
|   let mut num = 0; |   let mut num = 0; | ||||||
|   while num < 10 { |   while num < 10 { | ||||||
|  | |||||||
| @ -2,9 +2,9 @@ | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| fn main() -> bool { | fn main() -> bool { | ||||||
|   let bwand = (0xffu32 & 0xf0) >> 4; |   let bwand = (0xff & 0xf0) >> 4; | ||||||
|   let bwor = (0x0fu32 | 0x00) << 4; |   let bwor = (0x0fu32 | 0x00) << 4; | ||||||
|   let bwxor = (0xf0u32 | 0x0f); |   let bwxor = (0xf0 | 0x0f); | ||||||
| 
 | 
 | ||||||
|   return (bwxor == 255) && ((bwand == 15) || false) && (bwor == 240); |   return (bwxor == 255) && ((bwand == 15) || false) && (bwor == 240); | ||||||
| } | } | ||||||
| @ -431,7 +431,7 @@ impl Expression { | |||||||
|                     params: (lhs_type.clone(), rhs_type.clone()), |                     params: (lhs_type.clone(), rhs_type.clone()), | ||||||
|                     operator: *op, |                     operator: *op, | ||||||
|                 }); |                 }); | ||||||
|                 dbg!(&binops, &expected_return_ty); |                 // dbg!(&lhs_type, &rhs_type, &binops, &ret_ty, &expected_return_ty);
 | ||||||
|                 if let Some(binop) = binops |                 if let Some(binop) = binops | ||||||
|                     .iter() |                     .iter() | ||||||
|                     .filter(|f| f.1.return_ty.narrow_into(&expected_return_ty).is_ok()) |                     .filter(|f| f.1.return_ty.narrow_into(&expected_return_ty).is_ok()) | ||||||
|  | |||||||
| @ -390,6 +390,9 @@ impl Expression { | |||||||
|                         widened_rhs = widened_rhs.widen_into(&binop.hands.1); |                         widened_rhs = widened_rhs.widen_into(&binop.hands.1); | ||||||
|                     } |                     } | ||||||
|                     let binop_res = type_refs.from_binop(*op, &lhs_ref, &rhs_ref); |                     let binop_res = type_refs.from_binop(*op, &lhs_ref, &rhs_ref); | ||||||
|  |                     // dbg!(&return_ty);
 | ||||||
|  |                     // dbg!(&binop_res);
 | ||||||
|  |                     // dbg!(&lhs_ref, &rhs_ref, &binops, &widened_lhs, &widened_rhs);
 | ||||||
|                     lhs_ref.narrow(&type_refs.from_type(&widened_lhs).unwrap()); |                     lhs_ref.narrow(&type_refs.from_type(&widened_lhs).unwrap()); | ||||||
|                     rhs_ref.narrow(&type_refs.from_type(&widened_rhs).unwrap()); |                     rhs_ref.narrow(&type_refs.from_type(&widened_rhs).unwrap()); | ||||||
|                     *return_ty = binop_res.as_type(); |                     *return_ty = binop_res.as_type(); | ||||||
|  | |||||||
| @ -332,21 +332,56 @@ impl<'outer> ScopeTypeRefs<'outer> { | |||||||
|                 .widen(self.types); |                 .widen(self.types); | ||||||
|             self.narrow_to_type(&hint1, &ty)?; |             self.narrow_to_type(&hint1, &ty)?; | ||||||
|             let hint1_typeref = self.types.retrieve_typeref(*hint1.0.borrow()).unwrap(); |             let hint1_typeref = self.types.retrieve_typeref(*hint1.0.borrow()).unwrap(); | ||||||
|  |             let hint2_typeref = self.types.retrieve_typeref(*hint2.0.borrow()).unwrap(); | ||||||
|  | 
 | ||||||
|  |             match (&hint1_typeref, &hint2_typeref) { | ||||||
|  |                 (TypeRefKind::Direct(ret_ty), TypeRefKind::BinOp(op, lhs, rhs)) => { | ||||||
|  |                     let mut lhs_ref = self.from_type(&lhs).unwrap(); | ||||||
|  |                     let mut rhs_ref = self.from_type(&rhs).unwrap(); | ||||||
|  |                     let binops = self.available_binops(op, &mut lhs_ref, &mut rhs_ref); | ||||||
|  |                     let mut binops = binops | ||||||
|  |                         .iter() | ||||||
|  |                         .filter(|b| b.return_ty.narrow_into(ret_ty).is_ok()) | ||||||
|  |                         .into_iter(); | ||||||
|  | 
 | ||||||
|  |                     if let Some(binop) = binops.next() { | ||||||
|  |                         let mut lhs_widened = binop.hands.0.clone(); | ||||||
|  |                         let mut rhs_widened = binop.hands.1.clone(); | ||||||
|  |                         while let Some(binop) = binops.next() { | ||||||
|  |                             lhs_widened = lhs_widened.widen_into(&binop.hands.0); | ||||||
|  |                             rhs_widened = rhs_widened.widen_into(&binop.hands.1); | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         lhs_ref.narrow(&self.from_type(&lhs_widened).unwrap()); | ||||||
|  |                         rhs_ref.narrow(&self.from_type(&rhs_widened).unwrap()); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 _ => {} | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|             for idx in self.types.type_refs.borrow_mut().iter_mut() { |             for idx in self.types.type_refs.borrow_mut().iter_mut() { | ||||||
|                 match hint1_typeref { |                 match (&hint1_typeref, &hint2_typeref) { | ||||||
|                     TypeRefKind::Direct(_) => { |                     (TypeRefKind::Direct(_), TypeRefKind::Direct(_)) => { | ||||||
|                         if *idx == hint2.0 && idx != &hint1.0 { |                         if *idx == hint2.0 && idx != &hint1.0 { | ||||||
|                             *idx.borrow_mut() = *hint1.0.borrow(); |                             *idx.borrow_mut() = *hint1.0.borrow(); | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|                     TypeRefKind::BinOp(_, _, _) => { |                     (TypeRefKind::Direct(_), TypeRefKind::BinOp(..)) => {} | ||||||
|  |                     (TypeRefKind::BinOp(..), TypeRefKind::Direct(..)) => { | ||||||
|                         // TODO may not be good ?
 |                         // TODO may not be good ?
 | ||||||
|                         // if *idx == hint2.0 && idx != &hint1.0 {
 |                         // if *idx == hint2.0 && idx != &hint1.0 {
 | ||||||
|                         //     *idx.borrow_mut() = *hint1.0.borrow();
 |                         //     *idx.borrow_mut() = *hint1.0.borrow();
 | ||||||
|                         // }
 |                         // }
 | ||||||
|                     } |                     } | ||||||
|  |                     (TypeRefKind::BinOp(..), TypeRefKind::BinOp(..)) => { | ||||||
|  |                         // TODO may not be good ?
 | ||||||
|  |                         if *idx == hint2.0 && idx != &hint1.0 { | ||||||
|  |                             *idx.borrow_mut() = *hint1.0.borrow(); | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|             Some(TypeRef(hint1.0.clone(), self)) |             Some(TypeRef(hint1.0.clone(), self)) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user