diff --git a/crates/fayalite/src/expr/ops.rs b/crates/fayalite/src/expr/ops.rs index 4814d2d..e5d3d9b 100644 --- a/crates/fayalite/src/expr/ops.rs +++ b/crates/fayalite/src/expr/ops.rs @@ -1236,10 +1236,11 @@ macro_rules! impl_dyn_shl { } } - impl_binary_op_trait! { - #[generics(LhsWidth: Size, RhsWidth: Size)] - fn Shl::shl(lhs: $ty, rhs: UIntType) -> $ty { - $name::new(Expr::as_dyn_int(lhs), Expr::as_dyn_int(rhs)).to_expr() + impl Shl>> for Expr<$ty> { + type Output = Expr<$ty>; + + fn shl(self, rhs: Expr>) -> Self::Output { + $name::new(Expr::as_dyn_int(self), Expr::as_dyn_int(rhs)).to_expr() } } }; @@ -1308,10 +1309,11 @@ macro_rules! impl_dyn_shr { } } - impl_binary_op_trait! { - #[generics(LhsWidth: Size, RhsWidth: Size)] - fn Shr::shr(lhs: $ty, rhs: UIntType) -> $ty { - $name::new(lhs, Expr::as_dyn_int(rhs)).to_expr() + impl Shr>> for Expr<$ty> { + type Output = Expr<$ty>; + + fn shr(self, rhs: Expr>) -> Self::Output { + $name::new(self, Expr::as_dyn_int(rhs)).to_expr() } } }; diff --git a/crates/fayalite/src/int.rs b/crates/fayalite/src/int.rs index 2950086..b48f617 100644 --- a/crates/fayalite/src/int.rs +++ b/crates/fayalite/src/int.rs @@ -18,6 +18,7 @@ use std::{ borrow::{BorrowMut, Cow}, fmt, marker::PhantomData, + num::NonZero, ops::{Bound, Index, Not, Range, RangeBounds, RangeInclusive}, sync::Arc, }; @@ -468,7 +469,11 @@ impl SInt { } macro_rules! impl_prim_int { - ($prim_int:ident, $ty:ty) => { + ( + $(#[$meta:meta])* + $prim_int:ident, $ty:ty + ) => { + $(#[$meta])* impl ToExpr for $prim_int { type Type = $ty; @@ -479,6 +484,17 @@ macro_rules! impl_prim_int { ) } } + $(#[$meta])* + impl ToExpr for NonZero<$prim_int> { + type Type = $ty; + + fn to_expr(&self) -> Expr { + <$ty>::le_bytes_to_expr_wrapping( + &self.get().to_le_bytes(), + <$ty as BoolOrIntType>::Width::VALUE, + ) + } + } }; } @@ -493,6 +509,16 @@ impl_prim_int!(i32, SInt<32>); impl_prim_int!(i64, SInt<64>); impl_prim_int!(i128, SInt<128>); +impl_prim_int!( + /// for portability reasons, [`usize`] always translates to [`UInt<64>`] + usize, UInt<64> +); + +impl_prim_int!( + /// for portability reasons, [`isize`] always translates to [`SInt<64>`] + isize, SInt<64> +); + pub trait BoolOrIntType: Type + sealed::BoolOrIntTypeSealed { type Width: Size; type Signed: GenericConstBool;