%
-% (c) The AQUA Project, Glasgow University, 1997-1998
+% (c) The AQUA Project, Glasgow University, 1997-1999
%
\section[Int]{Module @Int@}
, Int16
, Int32
, Int64
+
+ , int8ToInt16 -- :: Int8 -> Int16
+ , int8ToInt32 -- :: Int8 -> Int32
+ , int8ToInt64 -- :: Int8 -> Int64
+
+ , int16ToInt8 -- :: Int16 -> Int8
+ , int16ToInt32 -- :: Int16 -> Int32
+ , int16ToInt64 -- :: Int16 -> Int64
+
+ , int32ToInt8 -- :: Int32 -> Int8
+ , int32ToInt16 -- :: Int32 -> Int16
+ , int32ToInt64 -- :: Int32 -> Int64
+
+ , int64ToInt8 -- :: Int64 -> Int8
+ , int64ToInt16 -- :: Int64 -> Int16
+ , int64ToInt32 -- :: Int64 -> Int32
+
, int8ToInt -- :: Int8 -> Int
- , intToInt8 -- :: Int -> Int8
, int16ToInt -- :: Int16 -> Int
- , intToInt16 -- :: Int -> Int16
, int32ToInt -- :: Int32 -> Int
- , intToInt32 -- :: Int -> Int32
+ , int64ToInt -- :: Int32 -> Int
- , intToInt64 -- :: Int -> Int64
- , int64ToInt -- :: Int64 -> Int
+ , intToInt8 -- :: Int -> Int8
+ , intToInt16 -- :: Int -> Int16
+ , intToInt32 -- :: Int -> Int32
+ , intToInt64 -- :: Int -> Int32
+ , integerToInt8 -- :: Integer -> Int8
+ , integerToInt16 -- :: Integer -> Int16
+ , integerToInt32 -- :: Integer -> Int32
, integerToInt64 -- :: Integer -> Int64
+
+ , int8ToInteger -- :: Int8 -> Integer
+ , int16ToInteger -- :: Int16 -> Integer
+ , int32ToInteger -- :: Int32 -> Integer
, int64ToInteger -- :: Int64 -> Integer
-- plus Eq, Ord, Num, Bounded, Real, Integral, Ix, Enum, Read,
-----------------------------------------------------------------------------
int8ToInt :: Int8 -> Int
-intToInt8 :: Int -> Int8
int16ToInt :: Int16 -> Int
-intToInt16 :: Int -> Int16
int32ToInt :: Int32 -> Int
-intToInt32 :: Int -> Int32
--- And some non-exported ones
+intToInt8 :: Int -> Int8
+intToInt16 :: Int -> Int16
+intToInt32 :: Int -> Int32
int8ToInt16 :: Int8 -> Int16
int8ToInt32 :: Int8 -> Int32
+
int16ToInt8 :: Int16 -> Int8
int16ToInt32 :: Int16 -> Int32
+
int32ToInt8 :: Int32 -> Int8
int32ToInt16 :: Int32 -> Int16
int8ToInt16 (I8# x) = I16# x
int8ToInt32 (I8# x) = I32# x
+int8ToInt64 = int32ToInt64 . int8ToInt32
+
int16ToInt8 (I16# x) = I8# x
int16ToInt32 (I16# x) = I32# x
+int16ToInt64 = int32ToInt64 . int16ToInt32
+
int32ToInt8 (I32# x) = I8# x
int32ToInt16 (I32# x) = I16# x
quot x@(I8# _) y@(I8# y#)
| y# /=# 0# = x `quotInt8` y
- | otherwise = error "Integral.Int8.quot: divide by 0\n"
+ | otherwise = divZeroError "quot{Int8}" x
rem x@(I8# _) y@(I8# y#)
| y# /=# 0# = x `remInt8` y
- | otherwise = error "Integral.Int8.rem: divide by 0\n"
+ | otherwise = divZeroError "rem{Int8}" x
mod x y
| x > 0 && y < 0 || x < 0 && y > 0 = if r/=0 then r+y else 0
| otherwise = r
instance Enum Int8 where
succ i
- | i == maxBound = error ("Enum{Int8}.succ: tried to take `succ' of " ++ show i)
+ | i == maxBound = succError "Int8"
| otherwise = i+1
pred i
- | i == minBound = error ("Enum{Int8}.pred: tried to take `pred' of " ++ show i)
- | otherwise = i+1
-
- toEnum = intToInt8
- fromEnum = int8ToInt
- enumFrom c = map toEnum [fromEnum c .. fromEnum (maxBound::Int8)]
- enumFromThen c d = map toEnum [fromEnum c, fromEnum d .. fromEnum (last::Int8)]
- where last = if d < c then minBound else maxBound
+ | i == minBound = predError "Int8"
+ | otherwise = i-1
+
+ toEnum x
+ | x >= toInt (minBound::Int8) && x <= toInt (maxBound::Int8)
+ = intToInt8 x
+ | otherwise
+ = toEnumError "Int8" x (minBound::Int8,maxBound::Int8)
+
+ fromEnum = int8ToInt
+ enumFrom e1 = map toEnum [fromEnum e1 .. fromEnum (maxBound::Int8)]
+ enumFromThen e1 e2 =
+ map toEnum [fromEnum e1, fromEnum e2 .. fromEnum (last::Int8)]
+ where
+ last
+ | e2 < e1 = minBound
+ | otherwise = maxBound
instance Read Int8 where
readsPrec p s = [ (intToInt8 x,r) | (x,r) <- readsPrec p s ]
quot x@(I16# _) y@(I16# y#)
| y# /=# 0# = x `quotInt16` y
- | otherwise = error "Integral.Int16.quot: divide by 0\n"
+ | otherwise = divZeroError "quot{Int16}" x
rem x@(I16# _) y@(I16# y#)
| y# /=# 0# = x `remInt16` y
- | otherwise = error "Integral.Int16.rem: divide by 0\n"
+ | otherwise = divZeroError "rem{Int16}" x
mod x y
| x > 0 && y < 0 || x < 0 && y > 0 = if r/=0 then r+y else 0
| otherwise = r
instance Enum Int16 where
succ i
- | i == maxBound = error ("Enum{Int16}.succ: tried to take `succ' of " ++ show i)
+ | i == maxBound = succError "Int16"
| otherwise = i+1
+
pred i
- | i == minBound = error ("Enum{Int16}.pred: tried to take `pred' of " ++ show i)
- | otherwise = i+1
+ | i == minBound = predError "Int16"
+ | otherwise = i-1
+
+ toEnum x
+ | x >= toInt (minBound::Int16) && x <= toInt (maxBound::Int16)
+ = intToInt16 x
+ | otherwise
+ = toEnumError "Int16" x (minBound::Int16, maxBound::Int16)
- toEnum = intToInt16
fromEnum = int16ToInt
- enumFrom c = map toEnum [fromEnum c .. fromEnum (maxBound::Int16)]
- enumFromThen c d = map toEnum [fromEnum c, fromEnum d .. fromEnum (last::Int16)]
- where last = if d < c then minBound else maxBound
+
+ enumFrom e1 = map toEnum [fromEnum e1 .. fromEnum (maxBound::Int16)]
+ enumFromThen e1 e2 = map toEnum [fromEnum e1, fromEnum e2 .. fromEnum (last::Int16)]
+ where last
+ | e2 < e1 = minBound
+ | otherwise = maxBound
instance Read Int16 where
readsPrec p s = [ (intToInt16 x,r) | (x,r) <- readsPrec p s ]
= case (integer2Int# a# s# d#) of { i# -> I32# (intToInt32# i#) }
fromInt = intToInt32
--- ToDo: remove LitLit when minBound::Int is fixed (currently it's one
--- too high, and doesn't allow the correct minBound to be defined here).
instance Bounded Int32 where
- minBound = case ``0x80000000'' of { I# x -> I32# x }
- maxBound = I32# 0x7fffffff#
+ minBound = fromInt minBound
+ maxBound = fromInt maxBound
instance Real Int32 where
toRational x = toInteger x % 1
| otherwise = quotInt32 x y
quot x@(I32# _) y@(I32# y#)
| y# /=# 0# = x `quotInt32` y
- | otherwise = error "Integral.Int32.quot: divide by 0\n"
+ | otherwise = divZeroError "quot{Int32}" x
rem x@(I32# _) y@(I32# y#)
| y# /=# 0# = x `remInt32` y
- | otherwise = error "Integral.Int32.rem: divide by 0\n"
+ | otherwise = divZeroError "rem{Int32}" x
mod x y
| x > 0 && y < 0 || x < 0 && y > 0 = if r/=0 then r+y else 0
| otherwise = r
instance Enum Int32 where
succ i
- | i == maxBound = error ("Enum{Int32}.succ: tried to take `succ' of " ++ show i)
- | otherwise = i+1
- pred i
- | i == minBound = error ("Enum{Int32}.pred: tried to take `pred' of " ++ show i)
+ | i == maxBound = succError "Int32"
| otherwise = i+1
- toEnum = intToInt32
- fromEnum = int32ToInt
- enumFrom c = map toEnum [fromEnum c .. fromEnum (maxBound::Int32)]
- enumFromThen c d = map toEnum [fromEnum c, fromEnum d .. fromEnum (last::Int32)]
- where last = if d < c then minBound else maxBound
+ pred i
+ | i == minBound = predError "Int32"
+ | otherwise = i-1
+
+ toEnum x
+ -- with Int having the same range as Int32, the following test
+ -- shouldn't fail. However, having it here
+ | x >= toInt (minBound::Int32) && x <= toInt (maxBound::Int32)
+ = intToInt32 x
+ | otherwise
+ = toEnumError "Int32" x (minBound::Int32, maxBound::Int32)
+
+ fromEnum = int32ToInt
+
+ enumFrom e1 = map toEnum [fromEnum e1 .. fromEnum (maxBound::Int32)]
+ enumFromThen e1 e2 = map toEnum [fromEnum e1, fromEnum e2 .. fromEnum (last::Int32)]
+ where
+ last
+ | e2 < e1 = minBound
+ | otherwise = maxBound
instance Read Int32 where
readsPrec p s = [ (intToInt32 x,r) | (x,r) <- readsPrec p s ]
minBound = integerToInt64 (-0x8000000000000000)
maxBound = integerToInt64 0x7fffffffffffffff
-instance Real Int64 where
- toRational x = toInteger x % 1
-
instance Integral Int64 where
div x y
| x > 0 && y < 0 = quotInt64 (x-y-1) y
quot x@(I64# _) y@(I64# y#)
| y# /=# 0# = x `quotInt64` y
- | otherwise = error "Integral.Int64.quot: divide by 0\n"
+ | otherwise = divZeroError "quot{Int64}" x
rem x@(I64# _) y@(I64# y#)
| y# /=# 0# = x `remInt64` y
- | otherwise = error "Integral.Int32.rem: divide by 0\n"
+ | otherwise = divZeroError "rem{Int64}" x
mod x y
| x > 0 && y < 0 || x < 0 && y > 0 = if r/=0 then r+y else 0
toInteger (I64# i#) = toInteger (I# i#)
toInt (I64# i#) = I# i#
-instance Enum Int64 where
- succ i
- | i == maxBound = error ("Enum{Int64}.succ: tried to take `succ' of " ++ show i)
- | otherwise = i+1
- pred i
- | i == minBound = error ("Enum{Int64}.pred: tried to take `pred' of " ++ show i)
- | otherwise = i+1
-
- toEnum (I# i) = I64# i#
- fromEnum (I64# i) = I64# i#
- enumFrom c = map toEnum [fromEnum c .. fromEnum (maxBound::Int64)] -- a long list!
- enumFromThen c d = map toEnum [fromEnum c, fromEnum d .. fromEnum (last::Int64)]
- where last = if d < c then minBound else maxBound
-
-
-instance Read Int64 where
- readsPrec p s = [ (intToInt64 x,r) | (x,r) <- readsPrec p s ]
-
-instance Show Int64 where
- showsPrec p i64 = showsPrec p (int64ToInt i64)
-
instance Bits Int64 where
(I64# x) .&. (I64# y) = I64# (word2Int# ((int2Word# x) `and#` (int2Word# y)))
(I64# x) .|. (I64# y) = I64# (word2Int# ((int2Word# x) `or#` (int2Word# y)))
integerToInt64 :: Integer -> Int64
integerToInt64 (J# a# s# d#) = I64# (integerToInt64# a# s# d#)
-instance Show Int64 where
- showsPrec p x = showsPrec p (int64ToInteger x)
-
-instance Read Int64 where
- readsPrec _ s = [ (integerToInt64 x,r) | (x,r) <- readDec s ]
-
instance Eq Int64 where
(I64# x) == (I64# y) = x `eqInt64#` y
(I64# x) /= (I64# y) = x `neInt64#` y
minBound = integerToInt64 (-0x8000000000000000)
maxBound = integerToInt64 0x7fffffffffffffff
-instance Real Int64 where
- toRational x = toInteger x % 1
-
instance Integral Int64 where
div x y
| x > 0 && y < 0 = quotInt64 (x-y-1) y
quot x@(I64# _) y@(I64# y#)
| y# `neInt64#` (intToInt64# 0#) = x `quotInt64` y
- | otherwise = error "Integral.Int64.quot: divide by 0\n"
+ | otherwise = divZeroError "quot{Int64}" x
rem x@(I64# _) y@(I64# y#)
| y# `neInt64#` (intToInt64# 0#) = x `remInt64` y
- | otherwise = error "Integral.Int32.rem: divide by 0\n"
+ | otherwise = divZeroError "rem{Int64}" x
mod x y
| x > 0 && y < 0 || x < 0 && y > 0 = if r/=0 then r+y else 0
toInteger i = int64ToInteger i
toInt i = int64ToInt i
-instance Enum Int64 where
- succ i
- | i == maxBound = error ("Enum{Int64}.succ: tried to take `succ' of " ++ show i)
- | otherwise = i+1
- pred i
- | i == minBound = error ("Enum{Int64}.pred: tried to take `pred' of " ++ show i)
- | otherwise = i+1
-
- toEnum (I# i) = I64# (intToInt64# i)
- fromEnum (I64# w) = I# (int64ToInt# w)
- enumFrom i = eft64 i 1
- enumFromTo i1 i2 = eftt64 i1 1 (> i2)
- enumFromThen i1 i2 = eftt64 i1 (i2 - i1) (>last)
- where
- last
- | i1 < i2 = maxBound::Int64
- | otherwise = minBound
-
-
instance Bits Int64 where
(I64# x) .&. (I64# y) = I64# (word64ToInt64# ((int64ToWord64# x) `and64#` (int64ToWord64# y)))
(I64# x) .|. (I64# y) = I64# (word64ToInt64# ((int64ToWord64# x) `or64#` (int64ToWord64# y)))
int64ToInt :: Int64 -> Int
int64ToInt (I64# i#) = I# (int64ToInt# i#)
--- Enum Int64 helper funs:
-
-eftt64 :: Int64 -> Int64 -> (Int64->Bool) -> [Int64]
-eftt64 init step done = go init
- where
- go now
- | done now = []
- | otherwise = now : go (now+step)
-
-eft64 :: Int64 -> Int64 -> [Int64]
-eft64 now step = go now
- where
- go x
- | x == maxBound = [x]
- | otherwise = x:go (x+step)
-
-
-- Word64# primop wrappers:
ltInt64# :: Int64# -> Int64# -> Bool
#endif
+--
+-- Code that's independent of Int64 rep.
+--
+instance Enum Int64 where
+ succ i
+ | i == maxBound = succError "Int64"
+ | otherwise = i+1
+
+ pred i
+ | i == minBound = predError "Int64"
+ | otherwise = i-1
+
+ toEnum i = intToInt64 i
+ fromEnum x
+ | x >= intToInt64 (minBound::Int) && x <= intToInt64 (maxBound::Int)
+ = int64ToInt x
+ | otherwise
+ = fromEnumError "Int64" x
+
+ enumFrom e1 = map integerToInt64 [int64ToInteger e1 .. int64ToInteger (maxBound::Int64)]
+ enumFromTo e1 e2 = map integerToInt64 [int64ToInteger e1 .. int64ToInteger e2]
+ enumFromThen e1 e2 = map integerToInt64 [int64ToInteger e1, int64ToInteger e2 .. int64ToInteger last]
+ where
+ last :: Int64
+ last
+ | e2 < e1 = minBound
+ | otherwise = maxBound
+
+ enumFromThenTo e1 e2 e3 = map integerToInt64 [int64ToInteger e1, int64ToInteger e2 .. int64ToInteger e3]
+
+
+instance Show Int64 where
+ showsPrec p i64 = showsPrec p (int64ToInteger i64)
+
+instance Read Int64 where
+ readsPrec _ s = [ (integerToInt64 x,r) | (x,r) <- readDec s ]
+
+
instance Ix Int64 where
range (m,n) = [m..n]
index b@(m,_) i
| otherwise = indexError i b "Int64"
inRange (m,n) i = m <= i && i <= n
+instance Real Int64 where
+ toRational x = toInteger x % 1
+
sizeofInt64 :: Word32
sizeofInt64 = 8
+
+int8ToInteger :: Int8 -> Integer
+int8ToInteger i = toInteger i
+
+int16ToInteger :: Int16 -> Integer
+int16ToInteger i = toInteger i
+
+int32ToInteger :: Int32 -> Integer
+int32ToInteger i = toInteger i
+
+int64ToInt8 :: Int64 -> Int8
+int64ToInt8 = int32ToInt8 . int64ToInt32
+
+int64ToInt16 :: Int64 -> Int16
+int64ToInt16 = int32ToInt16 . int64ToInt32
+
+integerToInt8 :: Integer -> Int8
+integerToInt8 = fromInteger
+
+integerToInt16 :: Integer -> Int16
+integerToInt16 = fromInteger
+
+integerToInt32 :: Integer -> Int32
+integerToInt32 = fromInteger
+
\end{code}
%
showParen True (showsPrec 0 rng) "")
+toEnumError :: (Show a,Show b) => String -> a -> (b,b) -> c
+toEnumError inst_ty tag bnds
+ = error ("Enum.toEnum{" ++ inst_ty ++ "}: tag " ++
+ (showParen True (showsPrec 0 tag) $
+ " is outside of bounds " ++
+ show bnds))
+
+fromEnumError :: (Show a,Show b) => String -> a -> b
+fromEnumError inst_ty tag
+ = error ("Enum.fromEnum{" ++ inst_ty ++ "}: value " ++
+ (showParen True (showsPrec 0 tag) $
+ " is outside of Int's bounds " ++
+ show (minBound::Int,maxBound::Int)))
+
+succError :: String -> a
+succError inst_ty
+ = error ("Enum.succ{" ++ inst_ty ++ "}: tried to take `succ' of maxBound")
+
+predError :: String -> a
+predError inst_ty
+ = error ("Enum.pred{" ++ inst_ty ++ "}: tried to take `pred' of minBound")
+
+divZeroError :: (Show a) => String -> a -> b
+divZeroError meth v
+ = error ("Integral." ++ meth ++ ": divide by 0 (" ++ show v ++ " / 0)")
+
\end{code}
, Word64 -- Integral, Ix, Enum,
-- Read, Show, Bits,
-- CCallable, CReturnable
- -- (last two
+ -- (last two are GHC specific.)
+ , word8ToWord16 -- :: Word8 -> Word16
, word8ToWord32 -- :: Word8 -> Word32
- , word32ToWord8 -- :: Word32 -> Word8
+ , word8ToWord64 -- :: Word8 -> Word64
+
+ , word16ToWord8 -- :: Word16 -> Word32
, word16ToWord32 -- :: Word16 -> Word32
+ , word16ToWord64 -- :: Word8 -> Word64
+
+ , word32ToWord8 -- :: Word32 -> Word8
, word32ToWord16 -- :: Word32 -> Word16
+ , word32ToWord64 -- :: Word32 -> Word64
+ , word64ToWord8 -- :: Word64 -> Word8
+ , word64ToWord16 -- :: Word64 -> Word16
+ , word64ToWord32 -- :: Word64 -> Word32
+
, word8ToInt -- :: Word8 -> Int
- , intToWord8 -- :: Int -> Word8
, word16ToInt -- :: Word16 -> Int
- , intToWord16 -- :: Int -> Word16
, word32ToInt -- :: Word32 -> Int
+ , word64ToInt -- :: Word64 -> Int
+
+ , intToWord8 -- :: Int -> Word8
+ , intToWord16 -- :: Int -> Word16
, intToWord32 -- :: Int -> Word32
+ , intToWord64 -- :: Int -> Word64
- , word32ToWord64 -- :: Word32 -> Word64
- , word64ToWord32 -- :: Word64 -> Word32
-
+ , word8ToInteger -- :: Word8 -> Integer
+ , word16ToInteger -- :: Word16 -> Integer
+ , word32ToInteger -- :: Word32 -> Integer
, word64ToInteger -- :: Word64 -> Integer
+
+ , integerToWord8 -- :: Integer -> Word8
+ , integerToWord16 -- :: Integer -> Word16
+ , integerToWord32 -- :: Integer -> Word32
, integerToWord64 -- :: Integer -> Word64
-- NB! GHC SPECIFIC:
, wordToWord8 -- :: Word -> Word8
- , word8ToWord -- :: Word8 -> Word
, wordToWord16 -- :: Word -> Word16
- , word16ToWord -- :: Word16 -> Word
, wordToWord32 -- :: Word -> Word32
- , word32ToWord -- :: Word32 -> Word
, wordToWord64 -- :: Word -> Word64
+
+ , word8ToWord -- :: Word8 -> Word
+ , word16ToWord -- :: Word16 -> Word
+ , word32ToWord -- :: Word32 -> Word
, word64ToWord -- :: Word64 -> Word
-- The "official" place to get these from is Addr.
-----------------------------------------------------------------------------
word8ToWord32 :: Word8 -> Word32
-word32ToWord8 :: Word32 -> Word8
word16ToWord32 :: Word16 -> Word32
+word32ToWord8 :: Word32 -> Word8
word32ToWord16 :: Word32 -> Word16
-word8ToInt :: Word8 -> Int
-intToWord8 :: Int -> Word8
-word16ToInt :: Word16 -> Int
-intToWord16 :: Int -> Word16
+word8ToInt :: Word8 -> Int
+word16ToInt :: Word16 -> Int
+intToWord8 :: Int -> Word8
+intToWord16 :: Int -> Word16
+
+integerToWord8 :: Integer -> Word8
+integerToWord16 :: Integer -> Word16
-word8ToInt = word32ToInt . word8ToWord32
-intToWord8 = word32ToWord8 . intToWord32
-word16ToInt = word32ToInt . word16ToWord32
-intToWord16 = word32ToWord16 . intToWord32
+word8ToInt = word32ToInt . word8ToWord32
+intToWord8 = word32ToWord8 . intToWord32
+word16ToInt = word32ToInt . word16ToWord32
+intToWord16 = word32ToWord16 . intToWord32
+word8ToInteger = word32ToInteger . word8ToWord32
+word16ToInteger = word32ToInteger . word16ToWord32
+integerToWord8 = fromInteger
+integerToWord16 = fromInteger
intToWord32 :: Int -> Word32
intToWord32 (I# x) = W32# ((int2Word# x) `and#` (case (maxBound::Word32) of W32# x# -> x#))
word32ToInt :: Word32 -> Int
word32ToInt (W32# x) = I# (word2Int# x)
+word32ToInteger :: Word32 -> Integer
+word32ToInteger (W32# x) = word2Integer x
+
+integerToWord32 :: Integer -> Word32
+integerToWord32 = fromInteger
+
wordToInt :: Word -> Int
wordToInt (W# w#) = I# (word2Int# w#)
instance CReturnable Word8
word8ToWord32 (W8# x) = W32# x
+word8ToWord16 (W8# x) = W16# x
word32ToWord8 (W32# x) = W8# (wordToWord8# x)
-- mask out upper three bytes.
-- Note: no need to mask results here
-- as they cannot overflow.
instance Integral Word8 where
- div (W8# x) (W8# y) = W8# (x `quotWord#` y)
- quot (W8# x) (W8# y) = W8# (x `quotWord#` y)
- rem (W8# x) (W8# y) = W8# (x `remWord#` y)
- mod (W8# x) (W8# y) = W8# (x `remWord#` y)
+ div x@(W8# x#) (W8# y#)
+ | y# `neWord#` (int2Word# 0#) = W8# (x# `quotWord#` y#)
+ | otherwise = divZeroError "div{Word8}" x
+
+ quot x@(W8# x#) (W8# y#)
+ | y# `neWord#` (int2Word# 0#) = W8# (x# `quotWord#` y#)
+ | otherwise = divZeroError "quot{Word8}" x
+
+ rem x@(W8# x#) (W8# y#)
+ | y# `neWord#` (int2Word# 0#) = W8# (x# `remWord#` y#)
+ | otherwise = divZeroError "rem{Word8}" x
+
+ mod x@(W8# x#) (W8# y#)
+ | y# `neWord#` (int2Word# 0#) = W8# (x# `remWord#` y#)
+ | otherwise = divZeroError "mod{Word8}" x
+
quotRem (W8# x) (W8# y) = (W8# (x `quotWord#` y), W8# (x `remWord#` y))
divMod (W8# x) (W8# y) = (W8# (x `quotWord#` y), W8# (x `remWord#` y))
+
toInteger (W8# x) = word2Integer x
toInt x = word8ToInt x
instance Enum Word8 where
succ w
- | w == maxBound = error ("Enum{Word8}.succ: tried to take `succ' of " ++ show w)
+ | w == maxBound = succError "Word8"
| otherwise = w+1
pred w
- | w == minBound = error ("Enum{Word8}.pred: tried to take `pred' of " ++ show w)
- | otherwise = w+1
+ | w == minBound = predError "Word8"
+ | otherwise = w-1
+
+ toEnum i@(I# i#)
+ | i >= toInt (minBound::Word8) && i <= toInt (maxBound::Word8)
+ = W8# (intToWord8# i#)
+ | otherwise
+ = toEnumError "Word8" i (minBound::Word8,maxBound::Word8)
- toEnum (I# i) = W8# (intToWord8# i)
fromEnum (W8# w) = I# (word2Int# w)
- enumFrom c = map toEnum [fromEnum c .. fromEnum (maxBound::Word8)]
- enumFromThen c d = map toEnum [fromEnum c, fromEnum d .. fromEnum (last::Word8)]
- where last = if d < c then minBound else maxBound
+ enumFrom c = map toEnum [fromEnum c .. fromEnum (maxBound::Word8)]
+ enumFromThen c d = map toEnum [fromEnum c, fromEnum d .. fromEnum last]
+ where
+ last :: Word8
+ last
+ | d < c = minBound
+ | otherwise = maxBound
instance Read Word8 where
readsPrec _ = readDec
instance CReturnable Word16
word16ToWord32 (W16# x) = W32# x
+word16ToWord8 (W16# x) = W8# (wordToWord8# x)
word32ToWord16 (W32# x) = W16# (wordToWord16# x)
-- mask out upper 16 bits.
toRational x = toInteger x % 1
instance Integral Word16 where
- div (W16# x) (W16# y) = W16# (x `quotWord#` y)
- quot (W16# x) (W16# y) = W16# (x `quotWord#` y)
- rem (W16# x) (W16# y) = W16# (x `remWord#` y)
- mod (W16# x) (W16# y) = W16# (x `remWord#` y)
+ div x@(W16# x#) (W16# y#)
+ | y# `neWord#` (int2Word# 0#) = W16# (x# `quotWord#` y#)
+ | otherwise = divZeroError "div{Word16}" x
+
+ quot x@(W16# x#) (W16# y#)
+ | y# `neWord#`(int2Word# 0#) = W16# (x# `quotWord#` y#)
+ | otherwise = divZeroError "quot{Word16}" x
+
+ rem x@(W16# x#) (W16# y#)
+ | y# `neWord#` (int2Word# 0#) = W16# (x# `remWord#` y#)
+ | otherwise = divZeroError "rem{Word16}" x
+
+ mod x@(W16# x#) (W16# y#)
+ | y# `neWord#` (int2Word# 0#) = W16# (x# `remWord#` y#)
+ | otherwise = divZeroError "mod{Word16}" x
+
quotRem (W16# x) (W16# y) = (W16# (x `quotWord#` y), W16# (x `remWord#` y))
divMod (W16# x) (W16# y) = (W16# (x `quotWord#` y), W16# (x `remWord#` y))
+
toInteger (W16# x) = word2Integer x
toInt x = word16ToInt x
inRange (m,n) i = m <= i && i <= n
instance Enum Word16 where
- succ w
- | w == maxBound = error ("Enum{Word16}.succ: tried to take `succ' of " ++ show w)
- | otherwise = w+1
- pred w
- | w == minBound = error ("Enum{Word16}.pred: tried to take `pred' of " ++ show w)
+ succ w
+ | w == maxBound = succError "Word16"
| otherwise = w+1
- toEnum (I# i) = W16# (intToWord16# i)
- fromEnum (W16# w) = I# (word2Int# w)
- enumFrom c = map toEnum [fromEnum c .. fromEnum (maxBound::Word16)]
- enumFromThen c d = map toEnum [fromEnum c, fromEnum d .. fromEnum (last::Word16)]
- where last = if d < c then minBound else maxBound
+ pred w
+ | w == minBound = predError "Word16"
+ | otherwise = w-1
+
+ toEnum i@(I# i#)
+ | i >= toInt (minBound::Word16) && i <= toInt (maxBound::Word16)
+ = W16# (intToWord16# i#)
+ | otherwise
+ = toEnumError "Word16" i (minBound::Word16,maxBound::Word16)
+
+ fromEnum (W16# w) = I# (word2Int# w)
+ enumFrom c = map toEnum [fromEnum c .. fromEnum (maxBound::Word16)]
+ enumFromThen c d = map toEnum [fromEnum c, fromEnum d .. fromEnum last]
+ where
+ last :: Word16
+ last
+ | d < c = minBound
+ | otherwise = maxBound
instance Read Word16 where
readsPrec _ = readDec
wordToWord32# :: Word# -> Word#
#if WORD_SIZE_IN_BYTES == 8
-intToWord32# i# = (int2Word# i#) `and#` (int2Word# 0xffffffff)
-wordToWord32# w# = w# `and#` (int2Word# 0xffffffff)
-wordToWord64# w# = w#
+intToWord32# i# = (int2Word# i#) `and#` (int2Word# 0xffffffff#)
+wordToWord32# w# = w# `and#` (int2Word# 0xffffffff#)
+wordToWord64# w# = w#
#else
intToWord32# i# = int2Word# i#
wordToWord32# w# = w#
toRational x = toInteger x % 1
instance Integral Word32 where
- div x y = quotWord32 x y
- quot x y = quotWord32 x y
- rem x y = remWord32 x y
- mod x y = remWord32 x y
+ div x y
+ | y /= 0 = quotWord32 x y
+ | otherwise = divZeroError "div{Word32}" x
+
+ quot x y
+ | y /= 0 = quotWord32 x y
+ | otherwise = divZeroError "quot{Word32}" x
+
+ rem x y
+ | y /= 0 = remWord32 x y
+ | otherwise = divZeroError "rem{Word32}" x
+
+ mod x y
+ | y /= 0 = remWord32 x y
+ | otherwise = divZeroError "mod{Word32}" x
+
quotRem a b = (a `quotWord32` b, a `remWord32` b)
divMod x y = quotRem x y
+
toInteger (W32# x) = word2Integer x
toInt (W32# x) = I# (word2Int# x)
instance Enum Word32 where
succ w
- | w == maxBound = error ("Enum{Word32}.succ: tried to take `succ' of " ++ show w)
+ | w == maxBound = succError "Word32"
| otherwise = w+1
pred w
- | w == minBound = error ("Enum{Word32}.pred: tried to take `pred' of " ++ show w)
- | otherwise = w+1
- toEnum = intToWord32
- fromEnum = word32ToInt -- lossy, don't use.
- enumFrom w = [w .. maxBound]
- enumFromTo w1 w2
- | w1 > w2 = []
- | otherwise = eft32 w1 w2
-
+ | w == minBound = predError "Word32"
+ | otherwise = w-1
+
+ -- the toEnum/fromEnum will fail if the mapping isn't legal,
+ -- use the intTo* & *ToInt coercion functions to 'bypass' these range checks.
+ toEnum x
+ | x >= 0 = intToWord32 x
+ | otherwise
+ = toEnumError "Word32" x (minBound::Word32,maxBound::Word32)
+
+ fromEnum x
+ | x <= intToWord32 (maxBound::Int)
+ = word32ToInt x
+ | otherwise
+ = fromEnumError "Word32" x
+
+ enumFrom w = [w .. maxBound]
+ enumFromTo w1 w2 = eftt32 increasing w1 diff_f last
+ where
+ increasing = w1 <= w2
+
+ last
+ | increasing = (> w2)
+ | otherwise = (< w2)
+
+ diff_f
+ | increasing = \ x -> x + 1
+ | otherwise = \ x -> x - 1
+
enumFromThen w1 w2 = [w1,w2 .. last]
where
+ last :: Word32
last
- | w1 < w2 = maxBound::Word32
+ | w1 <=w2 = maxBound
| otherwise = minBound
- enumFromThenTo w1 w2 wend = eftt32 w1 stepWith
+ enumFromThenTo w1 w2 wend = eftt32 increasing w1 step_f last
where
+ increasing = w1 <= w2
diff1 = w2 - w1
diff2 = w1 - w2
+
+ last
+ | increasing = (> wend)
+ | otherwise = (< wend)
- increasing = w2 > w1
+ step_f
+ | increasing = \ x -> x + diff1
+ | otherwise = \ x -> x - diff2
- stepWith :: Word32 -> Maybe Word32
- stepWith x
- | increasing && x > nxt = Nothing --oflow.
- | wend <= x = Nothing
- | otherwise = Just nxt
- where
- nxt
- | increasing = x + diff1
- | otherwise = x - diff2
-eftt32 :: Word32 -> (Word32 -> Maybe Word32) -> [Word32]
-eftt32 init stepper = go init
+eftt32 :: Bool -> Word32 -> (Word32 -> Word32) -> (Word32-> Bool) -> [Word32]
+eftt32 increasing init stepper done = go init
where
- go now =
- case stepper now of
- Nothing -> [now]
- Just v -> now : go v
-
-eft32 :: Word32 -> Word32 -> [Word32]
-eft32 now last = go now
- where
- go x
- | x == last = [x]
- | otherwise = x:go (x+1)
+ go now
+ | done now = []
+ | increasing && now > nxt = [now] -- oflow
+ | not increasing && now < nxt = [now] -- uflow
+ | otherwise = now : go nxt
+ where
+ nxt = stepper now
+
instance Read Word32 where
readsPrec _ = readDec
word32ToWord64 :: Word32 -> Word64
word32ToWord64 (W32 w#) = W64# w#
+word8ToWord64 :: Word8 -> Word64
+word8ToWord64 (W8# w#) = W64# w#
+
+word64ToWord8 :: Word64 -> Word8
+word64ToWord8 (W64# w#) = W8# (w# `and#` (int2Word# 0xff#))
+
+word16ToWord64 :: Word16 -> Word64
+word16ToWord64 (W16# w#) = W64# w#
+
+word64ToWord16 :: Word64 -> Word16
+word64ToWord16 (W64# w#) = W16# (w# `and#` (int2Word# 0xffff#))
+
wordToWord32# :: Word# -> Word#
wordToWord32# w# = w# `and#` (case (maxBound::Word32) of W# x# -> x#)
fromInteger (J# a# s# d#) = W64# (integer2Word# a# s# d#)
fromInt = intToWord64
-instance Bounded Word64 where
- minBound = 0
- maxBound = minBound - 1
-
-instance Real Word64 where
- toRational x = toInteger x % 1
-
-- Note: no need to mask results here
-- as they cannot overflow.
instance Integral Word64 where
- div (W64# x) (W64# y) = W64# (x `quotWord#` y)
- quot (W64# x) (W64# y) = W64# (x `quotWord#` y)
- rem (W64# x) (W64# y) = W64# (x `remWord#` y)
- mod (W64# x) (W64# y) = W64# (x `remWord#` y)
- quotRem (W64# x) (W64# y) = (W64# (x `quotWord#` y), W64# (x `remWord#` y))
- divMod (W64# x) (W64# y) = (W64# (x `quotWord#` y), W64# (x `remWord#` y))
- toInteger (W64# x) = word2Integer# x
- toInt x = word64ToInt x
+ div x@(W64# x#) (W64# y#)
+ | y# `neWord#` (int2Word# 0#) = W64# (x# `quotWord#` y#)
+ | otherwise = divZeroError "div{Word64}" x
-instance Ix Word64 where
- range (m,n) = [m..n]
- index b@(m,_) i
- | inRange b i = word64ToInt (i-m)
- | otherwise = indexError i b "Word64"
- inRange (m,n) i = m <= i && i <= n
+ quot x@(W64# x#) (W64# y#)
+ | y# `neWord#` (int2Word# 0#) = W64# (x# `quotWord#` y#)
+ | otherwise = divZeroError "quot{Word64}" x
-instance Enum Word64 where
- succ w
- | w == maxBound = error ("Enum{Word64}.succ: tried to take `succ' of " ++ show w)
- | otherwise = w+1
- pred w
- | w == minBound = error ("Enum{Word64}.pred: tried to take `pred' of " ++ show w)
- | otherwise = w+1
- toEnum (I# i) = W64# (intToWord# i)
- fromEnum (W64# w) = I# (word2Int# w) -- lossy, don't use.
- enumFrom w = eft64 w 1
- enumFromTo w1 w2 = eftt64 w1 1 (> w2)
- enumFromThen w1 w2 = eftt64 w1 (w2 - w1) (>last)
- where
- last
- | w1 < w2 = maxBound::Word64
- | otherwise = minBound
+ rem x@(W64# x#) (W64# y#)
+ | y# `neWord#` (int2Word# 0#) = W64# (x# `remWord#` y#)
+ | otherwise = divZeroError "rem{Word64}" x
-instance Read Word64 where
- readsPrec _ = readDec
+ mod (W64# x) (W64# y)
+ | y# `neWord#` (int2Word# 0#) = W64# (x `remWord#` y)
+ | otherwise = divZeroError "mod{Word64}" x
-instance Show Word64 where
- showsPrec _ = showInt
+ quotRem (W64# x) (W64# y) = (W64# (x `quotWord#` y), W64# (x `remWord#` y))
+ divMod (W64# x) (W64# y) = (W64# (x `quotWord#` y), W64# (x `remWord#` y))
+
+ toInteger (W64# x) = word2Integer# x
+ toInt x = word64ToInt x
instance Bits Word64 where
word64ToWord32 :: Word64 -> Word32
word64ToWord32 (W64# w#) = W32# (word64ToWord# w#)
+word8ToWord64 :: Word8 -> Word64
+word8ToWord64 (W8# w#) = W64# (wordToWord64# w#)
+
+word64ToWord8 :: Word64 -> Word8
+word64ToWord8 (W64# w#) = W8# ((word64ToWord# w#) `and#` (int2Word# 0xff#))
+
+word16ToWord64 :: Word16 -> Word64
+word16ToWord64 (W16# w#) = W64# (wordToWord64# w#)
+
+word64ToWord16 :: Word64 -> Word16
+word64ToWord16 (W64# w#) = W16# ((word64ToWord# w#) `and#` (int2Word# 0xffff#))
+
+
word64ToInteger :: Word64 -> Integer
word64ToInteger (W64# w#) =
case word64ToInteger# w# of
integerToWord64 :: Integer -> Word64
integerToWord64 (J# a# s# d#) = W64# (integerToWord64# a# s# d#)
-instance Show Word64 where
- showsPrec p x = showsPrec p (word64ToInteger x)
-
-instance Read Word64 where
- readsPrec _ s = [ (integerToWord64 x,r) | (x,r) <- readDec s ]
-
instance Eq Word64 where
(W64# x) == (W64# y) = x `eqWord64#` y
(W64# x) /= (W64# y) = not (x `eqWord64#` y)
fromInteger i = integerToWord64 i
fromInt = intToWord64
-instance Bounded Word64 where
- minBound = 0
- maxBound = minBound - 1
-
-instance Real Word64 where
- toRational x = toInteger x % 1
-
-- Note: no need to mask results here
-- as they cannot overflow.
+-- ToDo: protect against div by zero.
instance Integral Word64 where
div (W64# x) (W64# y) = W64# (x `quotWord64#` y)
quot (W64# x) (W64# y) = W64# (x `quotWord64#` y)
toInt x = word64ToInt x
-instance Ix Word64 where
- range (m,n) = [m..n]
- index b@(m,_) i
- | inRange b i = word64ToInt (i-m)
- | otherwise = indexError i b "Word64"
- inRange (m,n) i = m <= i && i <= n
-
-instance Enum Word64 where
- succ w
- | w == maxBound = error ("Enum{Word64}.succ: tried to take `succ' of " ++ show w)
- | otherwise = w+1
- pred w
- | w == minBound = error ("Enum{Word64}.pred: tried to take `pred' of " ++ show w)
- | otherwise = w+1
- toEnum (I# i) = W64# (intToWord64# i)
- fromEnum (W64# w) = I# (word2Int# (word64ToWord# w)) -- lossy, don't use.
- enumFrom w = eft64 w 1
- enumFromTo w1 w2 = eftt64 w1 1 (> w2)
- enumFromThen w1 w2 = eftt64 w1 (w2 - w1) (>last)
- where
- last
- | w1 < w2 = maxBound::Word64
- | otherwise = minBound
-
instance Bits Word64 where
(W64# x) .&. (W64# y) = W64# (x `and64#` y)
(W64# x) .|. (W64# y) = W64# (x `or64#` y)
#endif
+instance Enum Word64 where
+ succ w
+ | w == maxBound = succError "Word64"
+ | otherwise = w+1
+ pred w
+ | w == minBound = predError "Word64"
+ | otherwise = w-1
+
+ toEnum i
+ | i >= 0 = intToWord64 i
+ | otherwise
+ = toEnumError "Word64" i (minBound::Word64,maxBound::Word64)
+
+ fromEnum w
+ | w <= intToWord64 (maxBound::Int)
+ = word64ToInt w
+ | otherwise
+ = fromEnumError "Word64" w
+
+ enumFrom e1 = map integerToWord64 [word64ToInteger e1 .. word64ToInteger maxBound]
+ enumFromTo e1 e2 = map integerToWord64 [word64ToInteger e1 .. word64ToInteger e2]
+ enumFromThen e1 e2 = map integerToWord64 [word64ToInteger e1, word64ToInteger e2 .. word64ToInteger last]
+ where
+ last :: Word64
+ last
+ | e2 < e1 = minBound
+ | otherwise = maxBound
+
+ enumFromThenTo e1 e2 e3 = map integerToWord64 [word64ToInteger e1, word64ToInteger e2 .. word64ToInteger e3]
+
+instance Show Word64 where
+ showsPrec p x = showsPrec p (word64ToInteger x)
+
+instance Read Word64 where
+ readsPrec _ s = [ (integerToWord64 x,r) | (x,r) <- readDec s ]
+
+instance Ix Word64 where
+ range (m,n) = [m..n]
+ index b@(m,_) i
+ | inRange b i = word64ToInt (i-m)
+ | otherwise = indexError i b "Word64"
+ inRange (m,n) i = m <= i && i <= n
+
+instance Bounded Word64 where
+ minBound = 0
+ maxBound = minBound - 1
+
+instance Real Word64 where
+ toRational x = toInteger x % 1
+
sizeofWord64 :: Word32
sizeofWord64 = 8
--- Enum Word64 helper funs:
-
-eftt64 :: Word64 -> Word64 -> (Word64->Bool) -> [Word64]
-eftt64 init step done = go init
- where
- go now
- | done now = []
- | otherwise = now : go (now+step)
-
-eft64 :: Word64 -> Word64 -> [Word64]
-eft64 now step = go now
- where
- go x
- | x == maxBound = [x]
- | otherwise = x:go (x+step)
\end{code}
\end{code}
-C&P'ed from Ix.lhs
+Utils for generating friendly error messages.
\begin{code}
{-# NOINLINE indexError #-}
-indexError :: Show a => a -> (a,a) -> String -> b
+indexError :: (Show a) => a -> (a,a) -> String -> b
indexError i rng tp
= error (showString "Ix{" . showString tp . showString "}.index: Index " .
showParen True (showsPrec 0 i) .
showString " out of range " $
showParen True (showsPrec 0 rng) "")
+toEnumError :: (Show a,Show b) => String -> a -> (b,b) -> c
+toEnumError inst_ty tag bnds
+ = error ("Enum.toEnum{" ++ inst_ty ++ "}: tag " ++
+ (showParen True (showsPrec 0 tag) $
+ " is outside of bounds " ++
+ show bnds))
+
+fromEnumError :: (Show a,Show b) => String -> a -> b
+fromEnumError inst_ty tag
+ = error ("Enum.fromEnum{" ++ inst_ty ++ "}: value " ++
+ (showParen True (showsPrec 0 tag) $
+ " is outside of Int's bounds " ++
+ show (minBound::Int,maxBound::Int)))
+
+succError :: String -> a
+succError inst_ty
+ = error ("Enum.succ{" ++ inst_ty ++ "}: tried to take `succ' of maxBound")
+
+predError :: String -> a
+predError inst_ty
+ = error ("Enum.pred{" ++ inst_ty ++ "}: tried to take `pred' of minBound")
+
+divZeroError :: (Show a) => String -> a -> b
+divZeroError meth v
+ = error ("Integral." ++ meth ++ ": divide by 0 (" ++ show v ++ " / 0)")
\end{code}