forked from libre-chip/fayalite
		
	add Expr<ArrayType<T, Len>>: IntoIterator and Expr<Array<T>>: FromIterator<T>
This commit is contained in:
		
							parent
							
								
									60734cc9d1
								
							
						
					
					
						commit
						50c86e18dc
					
				
					 2 changed files with 159 additions and 24 deletions
				
			
		|  | @ -3,7 +3,7 @@ | ||||||
| 
 | 
 | ||||||
| use crate::{ | use crate::{ | ||||||
|     expr::{ |     expr::{ | ||||||
|         ops::{ArrayIndex, ArrayLiteral, ExprPartialEq}, |         ops::{ArrayLiteral, ExprFromIterator, ExprIntoIterator, ExprPartialEq}, | ||||||
|         CastToBits, Expr, HdlPartialEq, ReduceBits, ToExpr, |         CastToBits, Expr, HdlPartialEq, ReduceBits, ToExpr, | ||||||
|     }, |     }, | ||||||
|     int::{Bool, DynSize, KnownSize, Size, SizeType, DYN_SIZE}, |     int::{Bool, DynSize, KnownSize, Size, SizeType, DYN_SIZE}, | ||||||
|  | @ -15,7 +15,7 @@ use crate::{ | ||||||
|     }, |     }, | ||||||
|     util::ConstUsize, |     util::ConstUsize, | ||||||
| }; | }; | ||||||
| use std::ops::Index; | use std::{iter::FusedIterator, ops::Index}; | ||||||
| 
 | 
 | ||||||
| #[derive(Copy, Clone, PartialEq, Eq, Hash)] | #[derive(Copy, Clone, PartialEq, Eq, Hash)] | ||||||
| pub struct ArrayType<T: Type = CanonicalType, Len: Size = DynSize> { | pub struct ArrayType<T: Type = CanonicalType, Len: Size = DynSize> { | ||||||
|  | @ -151,10 +151,8 @@ impl<T: Type, Len: Size> Type for ArrayType<T, Len> { | ||||||
|         this: Expr<Self>, |         this: Expr<Self>, | ||||||
|         source_location: SourceLocation, |         source_location: SourceLocation, | ||||||
|     ) -> Self::MatchVariantsIter { |     ) -> Self::MatchVariantsIter { | ||||||
|         let base = Expr::as_dyn_array(this); |  | ||||||
|         let base_ty = Expr::ty(base); |  | ||||||
|         let _ = source_location; |         let _ = source_location; | ||||||
|         let retval = Vec::from_iter((0..base_ty.len()).map(|i| ArrayIndex::new(base, i).to_expr())); |         let retval = Vec::from_iter(this); | ||||||
|         std::iter::once(MatchVariantWithoutScope( |         std::iter::once(MatchVariantWithoutScope( | ||||||
|             Len::ArrayMatch::<T>::try_from(retval) |             Len::ArrayMatch::<T>::try_from(retval) | ||||||
|                 .ok() |                 .ok() | ||||||
|  | @ -187,9 +185,7 @@ impl<T: Type, Len: Size> Type for ArrayType<T, Len> { | ||||||
| 
 | 
 | ||||||
| impl<T: Type, Len: Size> TypeWithDeref for ArrayType<T, Len> { | impl<T: Type, Len: Size> TypeWithDeref for ArrayType<T, Len> { | ||||||
|     fn expr_deref(this: &Expr<Self>) -> &Self::MatchVariant { |     fn expr_deref(this: &Expr<Self>) -> &Self::MatchVariant { | ||||||
|         let base = Expr::as_dyn_array(*this); |         let retval = Vec::from_iter(*this); | ||||||
|         let base_ty = Expr::ty(base); |  | ||||||
|         let retval = Vec::from_iter((0..base_ty.len()).map(|i| ArrayIndex::new(base, i).to_expr())); |  | ||||||
|         Interned::into_inner(Intern::intern_sized( |         Interned::into_inner(Intern::intern_sized( | ||||||
|             Len::ArrayMatch::<T>::try_from(retval) |             Len::ArrayMatch::<T>::try_from(retval) | ||||||
|                 .ok() |                 .ok() | ||||||
|  | @ -230,12 +226,10 @@ where | ||||||
|         let lhs_ty = Expr::ty(lhs); |         let lhs_ty = Expr::ty(lhs); | ||||||
|         let rhs_ty = Expr::ty(rhs); |         let rhs_ty = Expr::ty(rhs); | ||||||
|         assert_eq!(lhs_ty.len(), rhs_ty.len()); |         assert_eq!(lhs_ty.len(), rhs_ty.len()); | ||||||
|         ArrayLiteral::<Bool, DynSize>::new( |         lhs.into_iter() | ||||||
|             Bool, |             .zip(rhs) | ||||||
|             (0..lhs_ty.len()) |             .map(|(l, r)| l.cmp_eq(r)) | ||||||
|                 .map(|i| Expr::canonical(lhs[i].cmp_eq(rhs[i]))) |             .collect::<Expr<Array<Bool>>>() | ||||||
|                 .collect(), |  | ||||||
|         ) |  | ||||||
|             .cast_to_bits() |             .cast_to_bits() | ||||||
|             .all_one_bits() |             .all_one_bits() | ||||||
|     } |     } | ||||||
|  | @ -244,13 +238,110 @@ where | ||||||
|         let lhs_ty = Expr::ty(lhs); |         let lhs_ty = Expr::ty(lhs); | ||||||
|         let rhs_ty = Expr::ty(rhs); |         let rhs_ty = Expr::ty(rhs); | ||||||
|         assert_eq!(lhs_ty.len(), rhs_ty.len()); |         assert_eq!(lhs_ty.len(), rhs_ty.len()); | ||||||
|         ArrayLiteral::<Bool, DynSize>::new( |         lhs.into_iter() | ||||||
|             Bool, |             .zip(rhs) | ||||||
|             (0..lhs_ty.len()) |             .map(|(l, r)| l.cmp_ne(r)) | ||||||
|                 .map(|i| Expr::canonical(lhs[i].cmp_ne(rhs[i]))) |             .collect::<Expr<Array<Bool>>>() | ||||||
|                 .collect(), |  | ||||||
|         ) |  | ||||||
|             .cast_to_bits() |             .cast_to_bits() | ||||||
|             .any_one_bits() |             .any_one_bits() | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | impl<T: Type, Len: Size> ExprIntoIterator for ArrayType<T, Len> { | ||||||
|  |     type Item = T; | ||||||
|  |     type ExprIntoIter = ExprArrayIter<T, Len>; | ||||||
|  | 
 | ||||||
|  |     fn expr_into_iter(e: Expr<Self>) -> Self::ExprIntoIter { | ||||||
|  |         ExprArrayIter { | ||||||
|  |             base: e, | ||||||
|  |             indexes: 0..Expr::ty(e).len(), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Clone, Debug)] | ||||||
|  | pub struct ExprArrayIter<T: Type, Len: Size> { | ||||||
|  |     base: Expr<ArrayType<T, Len>>, | ||||||
|  |     indexes: std::ops::Range<usize>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<T: Type, Len: Size> ExprArrayIter<T, Len> { | ||||||
|  |     pub fn base(&self) -> Expr<ArrayType<T, Len>> { | ||||||
|  |         self.base | ||||||
|  |     } | ||||||
|  |     pub fn indexes(&self) -> std::ops::Range<usize> { | ||||||
|  |         self.indexes.clone() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<T: Type, Len: Size> Iterator for ExprArrayIter<T, Len> { | ||||||
|  |     type Item = Expr<T>; | ||||||
|  | 
 | ||||||
|  |     fn next(&mut self) -> Option<Self::Item> { | ||||||
|  |         self.indexes.next().map(|i| self.base[i]) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn size_hint(&self) -> (usize, Option<usize>) { | ||||||
|  |         self.indexes.size_hint() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn count(self) -> usize { | ||||||
|  |         self.indexes.count() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn last(mut self) -> Option<Self::Item> { | ||||||
|  |         self.next_back() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn nth(&mut self, n: usize) -> Option<Self::Item> { | ||||||
|  |         self.indexes.nth(n).map(|i| self.base[i]) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn fold<B, F>(self, init: B, mut f: F) -> B | ||||||
|  |     where | ||||||
|  |         F: FnMut(B, Self::Item) -> B, | ||||||
|  |     { | ||||||
|  |         self.indexes.fold(init, |b, i| f(b, self.base[i])) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<T: Type, Len: Size> DoubleEndedIterator for ExprArrayIter<T, Len> { | ||||||
|  |     fn next_back(&mut self) -> Option<Self::Item> { | ||||||
|  |         self.indexes.next_back().map(|i| self.base[i]) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn nth_back(&mut self, n: usize) -> Option<Self::Item> { | ||||||
|  |         self.indexes.nth_back(n).map(|i| self.base[i]) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn rfold<B, F>(self, init: B, mut f: F) -> B | ||||||
|  |     where | ||||||
|  |         F: FnMut(B, Self::Item) -> B, | ||||||
|  |     { | ||||||
|  |         self.indexes.rfold(init, |b, i| f(b, self.base[i])) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<T: Type, Len: Size> ExactSizeIterator for ExprArrayIter<T, Len> { | ||||||
|  |     fn len(&self) -> usize { | ||||||
|  |         self.indexes.len() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<T: Type, Len: Size> FusedIterator for ExprArrayIter<T, Len> {} | ||||||
|  | 
 | ||||||
|  | impl<A: StaticType> ExprFromIterator<Expr<A>> for Array<A> { | ||||||
|  |     fn expr_from_iter<T: IntoIterator<Item = Expr<A>>>(iter: T) -> Expr<Self> { | ||||||
|  |         ArrayLiteral::new( | ||||||
|  |             A::TYPE, | ||||||
|  |             iter.into_iter().map(|v| Expr::canonical(v)).collect(), | ||||||
|  |         ) | ||||||
|  |         .to_expr() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<'a, A: StaticType> ExprFromIterator<&'a Expr<A>> for Array<A> { | ||||||
|  |     fn expr_from_iter<T: IntoIterator<Item = &'a Expr<A>>>(iter: T) -> Expr<Self> { | ||||||
|  |         iter.into_iter().copied().collect() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -2708,3 +2708,47 @@ impl<T: Type> ToExpr for Uninit<T> { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | pub trait ExprIntoIterator: Type { | ||||||
|  |     type Item: Type; | ||||||
|  |     type ExprIntoIter: Iterator<Item = Expr<Self::Item>>; | ||||||
|  | 
 | ||||||
|  |     fn expr_into_iter(e: Expr<Self>) -> Self::ExprIntoIter; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<T: ExprIntoIterator> IntoIterator for Expr<T> { | ||||||
|  |     type Item = Expr<T::Item>; | ||||||
|  |     type IntoIter = T::ExprIntoIter; | ||||||
|  | 
 | ||||||
|  |     fn into_iter(self) -> Self::IntoIter { | ||||||
|  |         T::expr_into_iter(self) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<T: ExprIntoIterator> IntoIterator for &'_ Expr<T> { | ||||||
|  |     type Item = Expr<T::Item>; | ||||||
|  |     type IntoIter = T::ExprIntoIter; | ||||||
|  | 
 | ||||||
|  |     fn into_iter(self) -> Self::IntoIter { | ||||||
|  |         T::expr_into_iter(*self) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<T: ExprIntoIterator> IntoIterator for &'_ mut Expr<T> { | ||||||
|  |     type Item = Expr<T::Item>; | ||||||
|  |     type IntoIter = T::ExprIntoIter; | ||||||
|  | 
 | ||||||
|  |     fn into_iter(self) -> Self::IntoIter { | ||||||
|  |         T::expr_into_iter(*self) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub trait ExprFromIterator<A>: Type { | ||||||
|  |     fn expr_from_iter<T: IntoIterator<Item = A>>(iter: T) -> Expr<Self>; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<This: ExprFromIterator<A>, A> FromIterator<A> for Expr<This> { | ||||||
|  |     fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self { | ||||||
|  |         This::expr_from_iter(iter) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue