Data.Word

module Data.Word(Word,Word8(..),Word16(..),Word32(..){-,Word64-}) where
import Builtin(shiftRWord,maxWord32)
import Word
import Data.Bits
import Data.Ix

instance Show Word   where showsPrec p (Word w)   = showsPrec p w
instance Show Word8  where showsPrec p (Word8 w)  = showsPrec p w
instance Show Word16 where showsPrec p (Word16 w) = showsPrec p w
instance Show Word32 where showsPrec p (Word32 w) = showsPrec p w
--instance Show Word64 where showsPrec p (Word64 w) = showsPrec p w

instance Read Word   where readsPrec p s = [(Word w,r)|(w,r)<-readsPrec p s]
instance Read Word8  where readsPrec p s = [(Word8 w,r)|(w,r)<-readsPrec p s]
instance Read Word16 where readsPrec p s = [(Word16 w,r)|(w,r)<-readsPrec p s]
instance Read Word32 where readsPrec p s = [(Word32 w,r)|(w,r)<-readsPrec p s]
--instance Read Word64 where readsPrec p s = [(Word64 w,r)|(w,r)<-readsPrec p s]

word8 n = Word8 (n .&. 0xff)
word16 n = Word16 (n .&. 0xffff)
word32 n = Word32 (n .&. maxWord32)
--word64 n = Word64 n

instance Bounded Word   where minBound = 0; maxBound = Word (-1)
instance Bounded Word8  where minBound = 0; maxBound = word8 maxBound
instance Bounded Word16 where minBound = 0; maxBound = word16 maxBound
instance Bounded Word32 where minBound = 0; maxBound = word32 (-1)
--instance Bounded Word64 where minBound = 0; maxBound = Word64 (-1)

instance Enum Word   where toEnum = Word;   fromEnum (Word n) = n
instance Enum Word8  where toEnum = word8;  fromEnum (Word8 n) = n
instance Enum Word16 where toEnum = word16; fromEnum (Word16 n) = n
instance Enum Word32 where toEnum = word32; fromEnum (Word32 n) = n
--instance Enum Word64 where toEnum = word64; fromEnum (Word64 n) = n

instance Num Word where
    fromInteger = Word . fromInteger
    Word x + Word y = Word (x + y)
    Word x - Word y = Word (x - y)
    Word x * Word y = Word (x * y)
    abs = id
    signum 0 = 0
    signum _ = 1

instance Num Word8 where
    fromInteger = word8 . fromInteger
    Word8 x + Word8 y = word8 (x + y)
    Word8 x - Word8 y = word8 (x - y)
    Word8 x * Word8 y = word8 (x * y)
    abs = id
    signum 0 = 0
    signum _ = 1

instance Num Word16 where
    fromInteger = word16 . fromInteger
    Word16 x + Word16 y = word16 (x + y)
    Word16 x - Word16 y = word16 (x - y)
    Word16 x * Word16 y = word16 (x * y)
    abs = id
    signum 0 = 0
    signum _ = 1

instance Num Word32 where
    fromInteger = word32 . fromInteger
--  fromInt = word32
    Word32 x + Word32 y = word32 (x + y)
    Word32 x - Word32 y = word32 (x - y)
    Word32 x * Word32 y = word32 (x * y)
    abs = id
    signum 0 = 0
    signum _ = 1
{-
instance Num Word64 where
    fromInteger = word64 . fromInteger
    Word64 x + Word64 y = word64 (x + y)
    Word64 x - Word64 y = word64 (x - y)
    Word64 x * Word64 y = word64 (x * y)
    abs = id
    signum 0 = 0
    signum _ = 1
-}
instance Integral Word  where
    toInteger (Word n) = toInteger n
    quotRem (Word n) (Word d) = case quotRem n d of (q,r) -> (Word q,Word r)

instance Integral Word8 where
    toInteger (Word8 n) = toInteger n
    quotRem (Word8 n) (Word8 d) = case quotRem n d of (q,r) -> (Word8 q,Word8 r)
    
instance Integral Word16 where
    toInteger (Word16 n) = toInteger n
    quotRem (Word16 n) (Word16 d)=case quotRem n d of (q,r)->(Word16 q,Word16 r)

instance Integral Word32 where toInteger (Word32 n) = toInteger n
--instance Integral Word64 where toInteger (Word64 n) = toInteger n

instance Real Word where toRational (Word n) = toRational n
instance Real Word8 where toRational (Word8 n) = toRational n
instance Real Word16 where toRational (Word16 n) = toRational n
instance Real Word32 where toRational (Word32 n) = toRational n
--instance Real Word64 where toRational (Word64 n) = toRational n

instance Ix Word8 where
  range (Word8 lo,Word8 hi) = [Word8 i | i<-range (lo,hi)]
  index (Word8 lo,Word8 hi) (Word8 i) = index (lo,hi) i
  inRange (Word8 lo,Word8 hi) (Word8 i) = inRange (lo,hi) i

instance Ix Word16 where
  range (Word16 lo,Word16 hi) = [Word16 i | i<-range (lo,hi)]
  index (Word16 lo,Word16 hi) (Word16 i) = index (lo,hi) i
  inRange (Word16 lo,Word16 hi) (Word16 i) = inRange (lo,hi) i

instance Ix Word32 where
  range (lo,hi) = [lo..hi]
  index (Word32 lo,_) (Word32 i) = i-lo
  inRange (Word32 lo,Word32 hi) (Word32 i) = lo<=i && i<=hi

instance Bits Word where
    Word x .|. Word y = Word (x .|. y)
    Word x .&. Word y = Word (x .&. y)
    Word x `xor` Word y = Word (x `xor` y)
    shiftL (Word x) n = Word (shiftL x n)
    shiftR (Word x) n = Word (shiftRWord x n)
    bitSize (Word n) = bitSize n

instance Bits Word8 where
    Word8 x .|. Word8 y = Word8 (x .|. y)
    Word8 x .&. Word8 y = Word8 (x .&. y)
    Word8 x `xor` Word8 y = Word8 (x `xor` y)
    shiftL (Word8 x) n = word8 (shiftL x n)
    shiftR (Word8 x) n = Word8 (shiftR x n)
    bitSize _ = 8

instance Bits Word16 where
    Word16 x .|. Word16 y = Word16 (x .|. y)
    Word16 x .&. Word16 y = Word16 (x .&. y)
    Word16 x `xor` Word16 y = Word16 (x `xor` y)
    shiftL (Word16 x) n = word16 (shiftL x n)
    shiftR (Word16 x) n = Word16 (shiftR x n)
    bitSize _ = 16

instance Bits Word32 where
    Word32 x .|. Word32 y = Word32 (x .|. y)
    Word32 x .&. Word32 y = Word32 (x .&. y)
    Word32 x `xor` Word32 y = Word32 (x `xor` y)
    complement (Word32 x) = word32 (x `xor` (-1))
    shiftL (Word32 x) n = word32 (shiftL x n)
    shiftR (Word32 x) n = Word32 (shiftRWord x n)
    bitSize _ = 32
{-
instance Bits Word64 where
    Word64 x .|. Word64 y = Word64 (x .|. y)
    Word64 x .&. Word64 y = Word64 (x .&. y)
    Word64 x `xor` Word64 y = Word64 (x `xor` y)
    shiftL (Word64 x) n = word64 (shiftL x n)
    shiftR (Word64 x) n = Word64 (shiftRWord x n)
    bitSize _ = 64
-}  
instance FiniteBits Word where finiteBitSize (Word n) = finiteBitSize n
instance FiniteBits Word8 where finiteBitSize _ = 8
instance FiniteBits Word16 where finiteBitSize _ = 16
instance FiniteBits Word32 where finiteBitSize _ = 32
--instance FiniteBits Word64 where finiteBitSize _ = 64