Compare commits
	
		
			1 commit
		
	
	
		
			50c86e18dc
			...
			25ddc837c1
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 25ddc837c1 | 
					 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