Fix intrinsic binops
This commit is contained in:
		
							parent
							
								
									307137d0d9
								
							
						
					
					
						commit
						5149ef8727
					
				| @ -5,6 +5,7 @@ use std::collections::HashMap; | |||||||
| use std::convert::Infallible; | use std::convert::Infallible; | ||||||
| use std::error::Error as STDError; | use std::error::Error as STDError; | ||||||
| 
 | 
 | ||||||
|  | use crate::codegen::intrinsics::form_intrinsic_binops; | ||||||
| use crate::error_raporting::ReidError; | use crate::error_raporting::ReidError; | ||||||
| 
 | 
 | ||||||
| use super::*; | use super::*; | ||||||
| @ -53,12 +54,7 @@ impl<TErr: STDError> State<TErr> { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn or_else<U, T: Into<Metadata> + Clone + Copy>( |     fn or_else<U, T: Into<Metadata> + Clone + Copy>(&mut self, result: Result<U, TErr>, default: U, meta: T) -> U { | ||||||
|         &mut self, |  | ||||||
|         result: Result<U, TErr>, |  | ||||||
|         default: U, |  | ||||||
|         meta: T, |  | ||||||
|     ) -> U { |  | ||||||
|         match result { |         match result { | ||||||
|             Ok(t) => t, |             Ok(t) => t, | ||||||
|             Err(e) => { |             Err(e) => { | ||||||
| @ -71,11 +67,7 @@ impl<TErr: STDError> State<TErr> { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn ok<T: Into<Metadata> + Clone + Copy, U>( |     fn ok<T: Into<Metadata> + Clone + Copy, U>(&mut self, result: Result<U, TErr>, meta: T) -> Option<U> { | ||||||
|         &mut self, |  | ||||||
|         result: Result<U, TErr>, |  | ||||||
|         meta: T, |  | ||||||
|     ) -> Option<U> { |  | ||||||
|         match result { |         match result { | ||||||
|             Ok(v) => Some(v), |             Ok(v) => Some(v), | ||||||
|             Err(e) => { |             Err(e) => { | ||||||
| @ -200,10 +192,10 @@ impl PartialEq for ScopeBinopKey { | |||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         let operators_eq = self.params.0.narrow_into(&other.params.0).is_ok() |         let operators_eq = | ||||||
|             && self.params.1.narrow_into(&other.params.1).is_ok(); |             self.params.0.narrow_into(&other.params.0).is_ok() && self.params.1.narrow_into(&other.params.1).is_ok(); | ||||||
|         let swapped_ops_eq = self.params.0.narrow_into(&other.params.1).is_ok() |         let swapped_ops_eq = | ||||||
|             && self.params.1.narrow_into(&other.params.0).is_ok(); |             self.params.0.narrow_into(&other.params.1).is_ok() && self.params.1.narrow_into(&other.params.0).is_ok(); | ||||||
| 
 | 
 | ||||||
|         if self.operator.is_commutative() { |         if self.operator.is_commutative() { | ||||||
|             operators_eq || swapped_ops_eq |             operators_eq || swapped_ops_eq | ||||||
| @ -253,11 +245,7 @@ pub struct PassState<'st, 'sc, Data: Clone + Default, TError: STDError + Clone> | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl<'st, 'sc, Data: Clone + Default, TError: STDError + Clone> PassState<'st, 'sc, Data, TError> { | impl<'st, 'sc, Data: Clone + Default, TError: STDError + Clone> PassState<'st, 'sc, Data, TError> { | ||||||
|     fn from( |     fn from(state: &'st mut State<TError>, scope: &'sc mut Scope<Data>, module_id: Option<SourceModuleId>) -> Self { | ||||||
|         state: &'st mut State<TError>, |  | ||||||
|         scope: &'sc mut Scope<Data>, |  | ||||||
|         module_id: Option<SourceModuleId>, |  | ||||||
|     ) -> Self { |  | ||||||
|         PassState { |         PassState { | ||||||
|             state, |             state, | ||||||
|             scope, |             scope, | ||||||
| @ -275,19 +263,11 @@ impl<'st, 'sc, Data: Clone + Default, TError: STDError + Clone> PassState<'st, ' | |||||||
|         self.state.or_else(result, default, meta) |         self.state.or_else(result, default, meta) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn ok<TMeta: Into<Metadata> + Clone + Copy, U>( |     pub fn ok<TMeta: Into<Metadata> + Clone + Copy, U>(&mut self, result: Result<U, TError>, meta: TMeta) -> Option<U> { | ||||||
|         &mut self, |  | ||||||
|         result: Result<U, TError>, |  | ||||||
|         meta: TMeta, |  | ||||||
|     ) -> Option<U> { |  | ||||||
|         self.state.ok(result, meta) |         self.state.ok(result, meta) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn note_errors<TMeta: Into<Metadata> + Clone>( |     pub fn note_errors<TMeta: Into<Metadata> + Clone>(&mut self, errors: &Vec<TError>, meta: TMeta) { | ||||||
|         &mut self, |  | ||||||
|         errors: &Vec<TError>, |  | ||||||
|         meta: TMeta, |  | ||||||
|     ) { |  | ||||||
|         for error in errors { |         for error in errors { | ||||||
|             self.ok::<_, Infallible>(Err(error.clone()), meta.clone().into()); |             self.ok::<_, Infallible>(Err(error.clone()), meta.clone().into()); | ||||||
|         } |         } | ||||||
| @ -311,18 +291,10 @@ pub trait Pass { | |||||||
|     type Data: Clone + Default; |     type Data: Clone + Default; | ||||||
|     type TError: STDError + Clone; |     type TError: STDError + Clone; | ||||||
| 
 | 
 | ||||||
|     fn context( |     fn context(&mut self, _context: &mut Context, mut _state: PassState<Self::Data, Self::TError>) -> PassResult { | ||||||
|         &mut self, |  | ||||||
|         _context: &mut Context, |  | ||||||
|         mut _state: PassState<Self::Data, Self::TError>, |  | ||||||
|     ) -> PassResult { |  | ||||||
|         Ok(()) |         Ok(()) | ||||||
|     } |     } | ||||||
|     fn module( |     fn module(&mut self, _module: &mut Module, mut _state: PassState<Self::Data, Self::TError>) -> PassResult { | ||||||
|         &mut self, |  | ||||||
|         _module: &mut Module, |  | ||||||
|         mut _state: PassState<Self::Data, Self::TError>, |  | ||||||
|     ) -> PassResult { |  | ||||||
|         Ok(()) |         Ok(()) | ||||||
|     } |     } | ||||||
|     fn function( |     fn function( | ||||||
| @ -332,25 +304,13 @@ pub trait Pass { | |||||||
|     ) -> PassResult { |     ) -> PassResult { | ||||||
|         Ok(()) |         Ok(()) | ||||||
|     } |     } | ||||||
|     fn block( |     fn block(&mut self, _block: &mut Block, mut _state: PassState<Self::Data, Self::TError>) -> PassResult { | ||||||
|         &mut self, |  | ||||||
|         _block: &mut Block, |  | ||||||
|         mut _state: PassState<Self::Data, Self::TError>, |  | ||||||
|     ) -> PassResult { |  | ||||||
|         Ok(()) |         Ok(()) | ||||||
|     } |     } | ||||||
|     fn stmt( |     fn stmt(&mut self, _stmt: &mut Statement, mut _state: PassState<Self::Data, Self::TError>) -> PassResult { | ||||||
|         &mut self, |  | ||||||
|         _stmt: &mut Statement, |  | ||||||
|         mut _state: PassState<Self::Data, Self::TError>, |  | ||||||
|     ) -> PassResult { |  | ||||||
|         Ok(()) |         Ok(()) | ||||||
|     } |     } | ||||||
|     fn expr( |     fn expr(&mut self, _expr: &mut Expression, mut _state: PassState<Self::Data, Self::TError>) -> PassResult { | ||||||
|         &mut self, |  | ||||||
|         _expr: &mut Expression, |  | ||||||
|         mut _state: PassState<Self::Data, Self::TError>, |  | ||||||
|     ) -> PassResult { |  | ||||||
|         Ok(()) |         Ok(()) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -360,6 +320,24 @@ impl Context { | |||||||
|         let mut state = State::new(); |         let mut state = State::new(); | ||||||
|         let mut scope = Scope::default(); |         let mut scope = Scope::default(); | ||||||
|         pass.context(self, PassState::from(&mut state, &mut scope, None))?; |         pass.context(self, PassState::from(&mut state, &mut scope, None))?; | ||||||
|  | 
 | ||||||
|  |         for intrinsic in form_intrinsic_binops() { | ||||||
|  |             scope | ||||||
|  |                 .binops | ||||||
|  |                 .set( | ||||||
|  |                     ScopeBinopKey { | ||||||
|  |                         params: (intrinsic.lhs.1.clone(), intrinsic.rhs.1.clone()), | ||||||
|  |                         operator: intrinsic.op, | ||||||
|  |                     }, | ||||||
|  |                     ScopeBinopDef { | ||||||
|  |                         hands: (intrinsic.lhs.1.clone(), intrinsic.rhs.1.clone()), | ||||||
|  |                         operator: intrinsic.op, | ||||||
|  |                         return_ty: intrinsic.return_type.clone(), | ||||||
|  |                     }, | ||||||
|  |                 ) | ||||||
|  |                 .ok(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         for (_, module) in &mut self.modules { |         for (_, module) in &mut self.modules { | ||||||
|             module.pass(pass, &mut state, &mut scope.inner())?; |             module.pass(pass, &mut state, &mut scope.inner())?; | ||||||
|         } |         } | ||||||
| @ -368,12 +346,7 @@ impl Context { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Module { | impl Module { | ||||||
|     fn pass<T: Pass>( |     fn pass<T: Pass>(&mut self, pass: &mut T, state: &mut State<T::TError>, scope: &mut Scope<T::Data>) -> PassResult { | ||||||
|         &mut self, |  | ||||||
|         pass: &mut T, |  | ||||||
|         state: &mut State<T::TError>, |  | ||||||
|         scope: &mut Scope<T::Data>, |  | ||||||
|     ) -> PassResult { |  | ||||||
|         for typedef in &self.typedefs { |         for typedef in &self.typedefs { | ||||||
|             scope |             scope | ||||||
|                 .types |                 .types | ||||||
|  | |||||||
| @ -418,13 +418,13 @@ impl Expression { | |||||||
|                 let rhs_type = state.or_else(rhs_res, TypeKind::Vague(Vague::Unknown), rhs.1); |                 let rhs_type = state.or_else(rhs_res, TypeKind::Vague(Vague::Unknown), rhs.1); | ||||||
|                 let expected_return_ty = ret_ty.resolve_ref(typerefs); |                 let expected_return_ty = ret_ty.resolve_ref(typerefs); | ||||||
| 
 | 
 | ||||||
|                 let binops = typerefs.binop_types.filter(&pass::ScopeBinopKey { |                 let binops = state.scope.binops.filter(&pass::ScopeBinopKey { | ||||||
|                     params: (lhs_type.clone(), rhs_type.clone()), |                     params: (lhs_type.clone(), rhs_type.clone()), | ||||||
|                     operator: *op, |                     operator: *op, | ||||||
|                 }); |                 }); | ||||||
|                 if let Some(binop) = binops |                 if let Some(binop) = binops | ||||||
|                     .iter() |                     .iter() | ||||||
|                     .filter(|f| f.1.return_ty == expected_return_ty) |                     .filter(|f| f.1.return_ty.narrow_into(&expected_return_ty).is_ok()) | ||||||
|                     .map(|v| (v.1.clone())) |                     .map(|v| (v.1.clone())) | ||||||
|                     .next() |                     .next() | ||||||
|                 { |                 { | ||||||
|  | |||||||
| @ -119,6 +119,7 @@ impl BinopDefinition { | |||||||
|             .fn_kind |             .fn_kind | ||||||
|             .infer_types(state, &scope_hints, Some(self.return_type.clone()))?; |             .infer_types(state, &scope_hints, Some(self.return_type.clone()))?; | ||||||
|         if let Some(mut ret_ty) = ret_ty { |         if let Some(mut ret_ty) = ret_ty { | ||||||
|  |             dbg!(&ret_ty, &self.return_type); | ||||||
|             ret_ty.narrow(&scope_hints.from_type(&self.return_type).unwrap()); |             ret_ty.narrow(&scope_hints.from_type(&self.return_type).unwrap()); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| @ -296,7 +297,27 @@ impl Expression { | |||||||
|                 let mut lhs_ref = lhs.infer_types(state, type_refs)?; |                 let mut lhs_ref = lhs.infer_types(state, type_refs)?; | ||||||
|                 let mut rhs_ref = rhs.infer_types(state, type_refs)?; |                 let mut rhs_ref = rhs.infer_types(state, type_refs)?; | ||||||
| 
 | 
 | ||||||
|                 let binops = type_refs.available_binops(op, &mut lhs_ref, &mut rhs_ref); |                 let binops = if let (Some(lhs_ty), Some(rhs_ty)) = (lhs_ref.resolve_deep(), rhs_ref.resolve_deep()) { | ||||||
|  |                     let mut applying_binops = Vec::new(); | ||||||
|  |                     for (_, binop) in state.scope.binops.iter() { | ||||||
|  |                         if binop.operator != *op { | ||||||
|  |                             continue; | ||||||
|  |                         } | ||||||
|  |                         if let Some(_) = binop.narrow(&lhs_ty, &rhs_ty) { | ||||||
|  |                             applying_binops.push(binop.clone()); | ||||||
|  |                             continue; | ||||||
|  |                         } | ||||||
|  |                         if binop.operator.is_commutative() { | ||||||
|  |                             if let Some(_) = binop.narrow(&lhs_ty, &rhs_ty) { | ||||||
|  |                                 applying_binops.push(binop.clone()); | ||||||
|  |                                 continue; | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     applying_binops | ||||||
|  |                 } else { | ||||||
|  |                     Vec::new() | ||||||
|  |                 }; | ||||||
| 
 | 
 | ||||||
|                 if binops.len() > 0 { |                 if binops.len() > 0 { | ||||||
|                     let binop = unsafe { binops.get_unchecked(0) }; |                     let binop = unsafe { binops.get_unchecked(0) }; | ||||||
| @ -307,9 +328,15 @@ 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!(&type_refs.types.type_refs); | ||||||
|  |                     dbg!(&type_refs.types.hints); | ||||||
|                     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()); | ||||||
|  |                     dbg!(&lhs_ref, &rhs_ref); | ||||||
|                     *return_ty = binop_res.as_type(); |                     *return_ty = binop_res.as_type(); | ||||||
|  |                     dbg!(&type_refs.types.hints, &type_refs.types.type_refs); | ||||||
|  |                     dbg!(&return_ty); | ||||||
|  |                     dbg!(&type_refs.from_type(&return_ty)); | ||||||
|                     Ok(binop_res) |                     Ok(binop_res) | ||||||
|                 } else { |                 } else { | ||||||
|                     Err(ErrorKind::InvalidBinop( |                     Err(ErrorKind::InvalidBinop( | ||||||
|  | |||||||
| @ -283,14 +283,14 @@ impl<'outer> ScopeTypeRefs<'outer> { | |||||||
|                             match &lhs { |                             match &lhs { | ||||||
|                                 TypeKind::Vague(VagueType::TypeRef(idx)) => { |                                 TypeKind::Vague(VagueType::TypeRef(idx)) => { | ||||||
|                                     let mut lhs_ref = TypeRef(Rc::new(RefCell::new(*idx)), self); |                                     let mut lhs_ref = TypeRef(Rc::new(RefCell::new(*idx)), self); | ||||||
|                                     let narrowed = self.narrow_to_type(&mut lhs_ref, &lhs_narrow).unwrap_or(lhs_ref); |                                     self.narrow_to_type(&mut lhs_ref, &lhs_narrow).unwrap_or(lhs_ref); | ||||||
|                                 } |                                 } | ||||||
|                                 _ => {} |                                 _ => {} | ||||||
|                             }; |                             }; | ||||||
|                             match &rhs { |                             match &rhs { | ||||||
|                                 TypeKind::Vague(VagueType::TypeRef(idx)) => { |                                 TypeKind::Vague(VagueType::TypeRef(idx)) => { | ||||||
|                                     let mut rhs_ref = TypeRef(Rc::new(RefCell::new(*idx)), self); |                                     let mut rhs_ref = TypeRef(Rc::new(RefCell::new(*idx)), self); | ||||||
|                                     let narrowed = self.narrow_to_type(&mut rhs_ref, &rhs_narrow).unwrap_or(rhs_ref); |                                     self.narrow_to_type(&mut rhs_ref, &rhs_narrow).unwrap_or(rhs_ref); | ||||||
|                                 } |                                 } | ||||||
|                                 _ => {} |                                 _ => {} | ||||||
|                             } |                             } | ||||||
| @ -312,11 +312,22 @@ impl<'outer> ScopeTypeRefs<'outer> { | |||||||
|                 .clone() |                 .clone() | ||||||
|                 .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(); | ||||||
|             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 { | ||||||
|  |                     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(_, _, _) => { | ||||||
|  |                         // 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