bv-sized 0.2.1 → 0.3.0
raw patch · 4 files changed
+82/−18 lines, 4 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Data.BitVector.Sized: bvDivS :: BitVector w -> BitVector w -> BitVector w
- Data.BitVector.Sized: bvDivU :: BitVector w -> BitVector w -> BitVector w
+ Data.BitVector.Sized: bv0 :: BitVector 0
+ Data.BitVector.Sized: bvConcatMany :: KnownNat w' => [BitVector w] -> BitVector w'
+ Data.BitVector.Sized: bvConcatManyWithRepr :: NatRepr w' -> [BitVector w] -> BitVector w'
+ Data.BitVector.Sized: bvGetBytesU :: Int -> BitVector w -> [BitVector 8]
+ Data.BitVector.Sized: bvQuotS :: BitVector w -> BitVector w -> BitVector w
+ Data.BitVector.Sized: bvQuotU :: BitVector w -> BitVector w -> BitVector w
+ Data.BitVector.Sized: bvRemS :: BitVector w -> BitVector w -> BitVector w
+ Data.BitVector.Sized: bvRemU :: BitVector w -> BitVector w -> BitVector w
+ Data.BitVector.Sized: instance GHC.TypeNats.KnownNat w => GHC.Arr.Ix (Data.BitVector.Sized.BitVector w)
Files
- bv-sized.cabal +1/−1
- changelog.md +7/−0
- src/Data/BitVector/Sized.hs +73/−16
- src/Data/BitVector/Sized/BitLayout.hs +1/−1
bv-sized.cabal view
@@ -1,5 +1,5 @@ name: bv-sized-version: 0.2.1+version: 0.3.0 category: Bit Vectors synopsis: a BitVector datatype that is parameterized by the vector width description:
changelog.md view
@@ -22,3 +22,10 @@ * bvDivU, bvDivS * Added Read instance, fixed Show to be compatible. Using prettyclass for pretty printing. (I guess this is semi-breaking, but whatever.)++## 0.3.0 *April 2018*+ * fixed bug with bvShiftR, it was doing a left shift!+ * Division now rounds to zero for negative integers, bvDiv -> bvQuot+ * added Ix instance for BitVector w+ * added bv0, zero-width vector+ * bvConcatMany, bvGetBytesU (conversion to/from list of bytes)
src/Data/BitVector/Sized.hs view
@@ -22,6 +22,7 @@ ( -- * BitVector type BitVector(..) , bitVector+ , bv0 -- * Bitwise operations (width-preserving) -- | These are alternative versions of some of the 'Bits' functions where we do -- not need to know the width at compile time. They are all width-preserving.@@ -33,13 +34,15 @@ , bvPopCount , bvTruncBits -- * Arithmetic operations (width-preserving)- , bvAdd, bvMul, bvDivU, bvDivS+ , bvAdd, bvMul+ , bvQuotU, bvQuotS+ , bvRemU, bvRemS , bvAbs, bvNegate , bvSignum , bvLTS, bvLTU -- * Variable-width operations -- | These are functions that involve bit vectors of different lengths.- , bvConcat, (<:>)+ , bvConcat, (<:>), bvConcatMany, bvConcatManyWithRepr , bvExtract, bvExtractWithRepr , bvZext, bvZextWithRepr , bvSext, bvSextWithRepr@@ -47,11 +50,13 @@ -- * Conversions to Integer , bvIntegerU , bvIntegerS+ -- * Byte decomposition+ , bvGetBytesU ) where import Data.Bits-import Data.Parameterized.Classes-import Data.Parameterized.NatRepr+import Data.Ix+import Data.Parameterized import GHC.TypeLits import Numeric import System.Random@@ -69,18 +74,22 @@ -- | Construct a bit vector with a particular width, where the width is inferrable -- from the type context. The 'Integer' input (an unbounded data type, hence with an--- infinite-width bit representation), whether positive or negative is silently+-- infinite-width bit representation), whether positive or negative, is silently -- truncated to fit into the number of bits demanded by the return type. -- -- >>> bitVector 0xA :: BitVector 4 -- 0xa--- >>> :type it--- it :: BitVector 4+-- >>> bitVector 0xA :: BitVector 2+-- 0x2 bitVector :: KnownNat w => Integer -> BitVector w bitVector x = BV wRepr (truncBits width (fromIntegral x)) where wRepr = knownNat width = natValue wRepr +-- | The zero bitvector with width 0.+bv0 :: BitVector 0+bv0 = bitVector 0+ ---------------------------------------- -- BitVector -> Integer functions @@ -115,7 +124,7 @@ bvComplement (BV wRepr x) = BV wRepr (truncBits width (complement x)) where width = natValue wRepr --- | Bitwise shift.+-- | Bitwise shift. Uses an arithmetic right shift. bvShift :: BitVector w -> Int -> BitVector w bvShift bv@(BV wRepr _) shf = BV wRepr (truncBits width (x `shift` shf)) where width = natValue wRepr@@ -135,7 +144,7 @@ -- | Right logical shift. bvShiftRL :: BitVector w -> Int -> BitVector w-bvShiftRL bv@(BV wRepr _) shf = BV wRepr (truncBits width (x `shift` toPos shf))+bvShiftRL bv@(BV wRepr _) shf = BV wRepr (truncBits width (x `shift` (- toPos shf))) where width = natValue wRepr x = bvIntegerU bv @@ -176,17 +185,29 @@ bvMul (BV wRepr x) (BV _ y) = BV wRepr (truncBits width (x * y)) where width = natValue wRepr --- | Bitwise division (unsigned).-bvDivU :: BitVector w -> BitVector w -> BitVector w-bvDivU (BV wRepr x) (BV _ y) = BV wRepr (x `div` y)+-- | Bitwise division (unsigned). Rounds to zero.+bvQuotU :: BitVector w -> BitVector w -> BitVector w+bvQuotU (BV wRepr x) (BV _ y) = BV wRepr (x `quot` y) --- | Bitwise division (signed).-bvDivS :: BitVector w -> BitVector w -> BitVector w-bvDivS bv1@(BV wRepr _) bv2 = BV wRepr (truncBits width (x `div` y))+-- | Bitwise division (signed). Rounds to zero (not negative infinity).+bvQuotS :: BitVector w -> BitVector w -> BitVector w+bvQuotS bv1@(BV wRepr _) bv2 = BV wRepr (truncBits width (x `quot` y)) where x = bvIntegerS bv1 y = bvIntegerS bv2 width = natValue wRepr +-- | Bitwise remainder after division (unsigned), when rounded to zero.+bvRemU :: BitVector w -> BitVector w -> BitVector w+bvRemU (BV wRepr x) (BV _ y) = BV wRepr (x `rem` y)++-- | Bitwise remainder after division (signed), when rounded to zero (not negative+-- infinity).+bvRemS :: BitVector w -> BitVector w -> BitVector w+bvRemS bv1@(BV wRepr _) bv2 = BV wRepr (truncBits width (x `rem` y))+ where x = bvIntegerS bv1+ y = bvIntegerS bv2+ width = natValue wRepr+ -- | Bitwise absolute value. bvAbs :: BitVector w -> BitVector w bvAbs bv@(BV wRepr _) = BV wRepr abs_x@@ -233,6 +254,26 @@ (<:>) :: BitVector v -> BitVector w -> BitVector (v+w) (<:>) = bvConcat +bvConcatSome :: Some BitVector -> Some BitVector -> Some BitVector+bvConcatSome (Some bv1) (Some bv2) = Some (bv2 <:> bv1)++-- | Concatenate a list of 'BitVector's into a 'BitVector' of arbitrary width. The ordering is little endian:+--+-- >>> bvConcatMany [0xAA :: BitVector 8, 0xBB] :: BitVector 16+-- 0xbbaa+-- >>> bvConcatMany [0xAA :: BitVector 8, 0xBB, 0xCC] :: BitVector 16+-- 0xbbaa+--+-- If the sum of the widths of the input 'BitVector's exceeds the output width, we+-- ignore the tail end of the list.+bvConcatMany :: KnownNat w' => [BitVector w] -> BitVector w'+bvConcatMany = bvConcatManyWithRepr knownNat++-- | 'bvConcatMany' with an explicit 'NatRepr'.+bvConcatManyWithRepr :: NatRepr w' -> [BitVector w] -> BitVector w'+bvConcatManyWithRepr wRepr bvs =+ viewSome (bvZextWithRepr wRepr) $ foldl bvConcatSome (Some bv0) (Some <$> bvs)+ infixl 6 <:> -- | Slice out a smaller bit vector from a larger one. The lowest significant bit is@@ -313,6 +354,17 @@ width = natValue prodRepr ----------------------------------------+-- Byte decomposition++-- | Given a 'BitVector' of arbitrary length, decompose it into a list of bytes. Uses+-- an unsigned interpretation of the input vector, so if you ask for more bytes that+-- the 'BitVector' contains, you get zeros. The result is little-endian, so the first+-- element of the list will be the least significant byte of the input vector.+bvGetBytesU :: Int -> BitVector w -> [BitVector 8]+bvGetBytesU n _ | n <= 0 = []+bvGetBytesU n bv = bvExtract 0 bv : bvGetBytesU (n-1) (bvShiftRL bv 8)++---------------------------------------- -- Class instances instance Show (BitVector w) where@@ -368,6 +420,11 @@ toEnum = bitVector . fromIntegral fromEnum = fromIntegral . bvIntegerU +instance KnownNat w => Ix (BitVector w) where+ range (lo, hi) = bitVector <$> [bvIntegerU lo .. bvIntegerU hi]+ index (lo, hi) bv = index (bvIntegerU lo, bvIntegerU hi) (bvIntegerU bv)+ inRange (lo, hi) bv = inRange (bvIntegerU lo, bvIntegerU hi) (bvIntegerU bv)+ instance KnownNat w => Bounded (BitVector w) where minBound = bitVector 0 maxBound = bitVector (-1)@@ -385,7 +442,7 @@ prettyHex :: (Integral a, PrintfArg a, Show a) => a -> Integer -> String prettyHex width val = printf format val width- where numDigits = (width+3) `div` 4+ where numDigits = (width+3) `quot` 4 format = "0x%." ++ show numDigits ++ "x<%d>" instance Pretty (BitVector w) where
src/Data/BitVector/Sized/BitLayout.hs view
@@ -36,7 +36,7 @@ import Data.BitVector.Sized import Data.Foldable-import Control.Lens+import Control.Lens (lens, Simple, Lens) import Data.Parameterized import qualified Data.Sequence as S import Data.Sequence (Seq)