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::error::Error as STDError; | ||||
| 
 | ||||
| use crate::codegen::intrinsics::form_intrinsic_binops; | ||||
| use crate::error_raporting::ReidError; | ||||
| 
 | ||||
| use super::*; | ||||
| @ -53,12 +54,7 @@ impl<TErr: STDError> State<TErr> { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn or_else<U, T: Into<Metadata> + Clone + Copy>( | ||||
|         &mut self, | ||||
|         result: Result<U, TErr>, | ||||
|         default: U, | ||||
|         meta: T, | ||||
|     ) -> U { | ||||
|     fn or_else<U, T: Into<Metadata> + Clone + Copy>(&mut self, result: Result<U, TErr>, default: U, meta: T) -> U { | ||||
|         match result { | ||||
|             Ok(t) => t, | ||||
|             Err(e) => { | ||||
| @ -71,11 +67,7 @@ impl<TErr: STDError> State<TErr> { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn ok<T: Into<Metadata> + Clone + Copy, U>( | ||||
|         &mut self, | ||||
|         result: Result<U, TErr>, | ||||
|         meta: T, | ||||
|     ) -> Option<U> { | ||||
|     fn ok<T: Into<Metadata> + Clone + Copy, U>(&mut self, result: Result<U, TErr>, meta: T) -> Option<U> { | ||||
|         match result { | ||||
|             Ok(v) => Some(v), | ||||
|             Err(e) => { | ||||
| @ -200,10 +192,10 @@ impl PartialEq for ScopeBinopKey { | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         let operators_eq = 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() | ||||
|             && self.params.1.narrow_into(&other.params.0).is_ok(); | ||||
|         let operators_eq = | ||||
|             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() && self.params.1.narrow_into(&other.params.0).is_ok(); | ||||
| 
 | ||||
|         if self.operator.is_commutative() { | ||||
|             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> { | ||||
|     fn from( | ||||
|         state: &'st mut State<TError>, | ||||
|         scope: &'sc mut Scope<Data>, | ||||
|         module_id: Option<SourceModuleId>, | ||||
|     ) -> Self { | ||||
|     fn from(state: &'st mut State<TError>, scope: &'sc mut Scope<Data>, module_id: Option<SourceModuleId>) -> Self { | ||||
|         PassState { | ||||
|             state, | ||||
|             scope, | ||||
| @ -275,19 +263,11 @@ impl<'st, 'sc, Data: Clone + Default, TError: STDError + Clone> PassState<'st, ' | ||||
|         self.state.or_else(result, default, meta) | ||||
|     } | ||||
| 
 | ||||
|     pub fn ok<TMeta: Into<Metadata> + Clone + Copy, U>( | ||||
|         &mut self, | ||||
|         result: Result<U, TError>, | ||||
|         meta: TMeta, | ||||
|     ) -> Option<U> { | ||||
|     pub fn ok<TMeta: Into<Metadata> + Clone + Copy, U>(&mut self, result: Result<U, TError>, meta: TMeta) -> Option<U> { | ||||
|         self.state.ok(result, meta) | ||||
|     } | ||||
| 
 | ||||
|     pub fn note_errors<TMeta: Into<Metadata> + Clone>( | ||||
|         &mut self, | ||||
|         errors: &Vec<TError>, | ||||
|         meta: TMeta, | ||||
|     ) { | ||||
|     pub fn note_errors<TMeta: Into<Metadata> + Clone>(&mut self, errors: &Vec<TError>, meta: TMeta) { | ||||
|         for error in errors { | ||||
|             self.ok::<_, Infallible>(Err(error.clone()), meta.clone().into()); | ||||
|         } | ||||
| @ -311,18 +291,10 @@ pub trait Pass { | ||||
|     type Data: Clone + Default; | ||||
|     type TError: STDError + Clone; | ||||
| 
 | ||||
|     fn context( | ||||
|         &mut self, | ||||
|         _context: &mut Context, | ||||
|         mut _state: PassState<Self::Data, Self::TError>, | ||||
|     ) -> PassResult { | ||||
|     fn context(&mut self, _context: &mut Context, mut _state: PassState<Self::Data, Self::TError>) -> PassResult { | ||||
|         Ok(()) | ||||
|     } | ||||
|     fn module( | ||||
|         &mut self, | ||||
|         _module: &mut Module, | ||||
|         mut _state: PassState<Self::Data, Self::TError>, | ||||
|     ) -> PassResult { | ||||
|     fn module(&mut self, _module: &mut Module, mut _state: PassState<Self::Data, Self::TError>) -> PassResult { | ||||
|         Ok(()) | ||||
|     } | ||||
|     fn function( | ||||
| @ -332,25 +304,13 @@ pub trait Pass { | ||||
|     ) -> PassResult { | ||||
|         Ok(()) | ||||
|     } | ||||
|     fn block( | ||||
|         &mut self, | ||||
|         _block: &mut Block, | ||||
|         mut _state: PassState<Self::Data, Self::TError>, | ||||
|     ) -> PassResult { | ||||
|     fn block(&mut self, _block: &mut Block, mut _state: PassState<Self::Data, Self::TError>) -> PassResult { | ||||
|         Ok(()) | ||||
|     } | ||||
|     fn stmt( | ||||
|         &mut self, | ||||
|         _stmt: &mut Statement, | ||||
|         mut _state: PassState<Self::Data, Self::TError>, | ||||
|     ) -> PassResult { | ||||
|     fn stmt(&mut self, _stmt: &mut Statement, mut _state: PassState<Self::Data, Self::TError>) -> PassResult { | ||||
|         Ok(()) | ||||
|     } | ||||
|     fn expr( | ||||
|         &mut self, | ||||
|         _expr: &mut Expression, | ||||
|         mut _state: PassState<Self::Data, Self::TError>, | ||||
|     ) -> PassResult { | ||||
|     fn expr(&mut self, _expr: &mut Expression, mut _state: PassState<Self::Data, Self::TError>) -> PassResult { | ||||
|         Ok(()) | ||||
|     } | ||||
| } | ||||
| @ -360,6 +320,24 @@ impl Context { | ||||
|         let mut state = State::new(); | ||||
|         let mut scope = Scope::default(); | ||||
|         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 { | ||||
|             module.pass(pass, &mut state, &mut scope.inner())?; | ||||
|         } | ||||
| @ -368,12 +346,7 @@ impl Context { | ||||
| } | ||||
| 
 | ||||
| impl Module { | ||||
|     fn pass<T: Pass>( | ||||
|         &mut self, | ||||
|         pass: &mut T, | ||||
|         state: &mut State<T::TError>, | ||||
|         scope: &mut Scope<T::Data>, | ||||
|     ) -> PassResult { | ||||
|     fn pass<T: Pass>(&mut self, pass: &mut T, state: &mut State<T::TError>, scope: &mut Scope<T::Data>) -> PassResult { | ||||
|         for typedef in &self.typedefs { | ||||
|             scope | ||||
|                 .types | ||||
|  | ||||
| @ -418,13 +418,13 @@ impl Expression { | ||||
|                 let rhs_type = state.or_else(rhs_res, TypeKind::Vague(Vague::Unknown), rhs.1); | ||||
|                 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()), | ||||
|                     operator: *op, | ||||
|                 }); | ||||
|                 if let Some(binop) = binops | ||||
|                     .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())) | ||||
|                     .next() | ||||
|                 { | ||||
|  | ||||
| @ -119,6 +119,7 @@ impl BinopDefinition { | ||||
|             .fn_kind | ||||
|             .infer_types(state, &scope_hints, Some(self.return_type.clone()))?; | ||||
|         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()); | ||||
|         } | ||||
| 
 | ||||
| @ -296,7 +297,27 @@ impl Expression { | ||||
|                 let mut lhs_ref = lhs.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 { | ||||
|                     let binop = unsafe { binops.get_unchecked(0) }; | ||||
| @ -307,9 +328,15 @@ impl Expression { | ||||
|                         widened_rhs = widened_rhs.widen_into(&binop.hands.1); | ||||
|                     } | ||||
|                     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()); | ||||
|                     rhs_ref.narrow(&type_refs.from_type(&widened_rhs).unwrap()); | ||||
|                     dbg!(&lhs_ref, &rhs_ref); | ||||
|                     *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) | ||||
|                 } else { | ||||
|                     Err(ErrorKind::InvalidBinop( | ||||
|  | ||||
| @ -283,14 +283,14 @@ impl<'outer> ScopeTypeRefs<'outer> { | ||||
|                             match &lhs { | ||||
|                                 TypeKind::Vague(VagueType::TypeRef(idx)) => { | ||||
|                                     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 { | ||||
|                                 TypeKind::Vague(VagueType::TypeRef(idx)) => { | ||||
|                                     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() | ||||
|                 .widen(self.types); | ||||
|             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() { | ||||
|                 match hint1_typeref { | ||||
|                     TypeRefKind::Direct(_) => { | ||||
|                         if *idx == hint2.0 && idx != &hint1.0 { | ||||
|                             *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)) | ||||
|         } | ||||
|     } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user