2 % (c) The AQUA Project, Glasgow University, 1994-1996
5 \section[Word]{Module @Word@}
7 This code is largely copied from the Hugs library of the same name.
10 {-# OPTIONS -fno-implicit-prelude #-}
17 , word8ToWord32 -- :: Word8 -> Word32
18 , word32ToWord8 -- :: Word32 -> Word8
19 , word16ToWord32 -- :: Word16 -> Word32
20 , word32ToWord16 -- :: Word32 -> Word16
21 , word8ToInt -- :: Word8 -> Int
22 , intToWord8 -- :: Int -> Word8
23 , word16ToInt -- :: Word16 -> Int
24 , intToWord16 -- :: Int -> Word16
25 , word32ToInt -- :: Word32 -> Int
26 , intToWord32 -- :: Int -> Word32
37 -----------------------------------------------------------------------------
38 -- The "official" coercion functions
39 -----------------------------------------------------------------------------
41 word8ToWord32 :: Word8 -> Word32
42 word32ToWord8 :: Word32 -> Word8
43 word16ToWord32 :: Word16 -> Word32
44 word32ToWord16 :: Word32 -> Word16
46 word8ToInt :: Word8 -> Int
47 intToWord8 :: Int -> Word8
48 word16ToInt :: Word16 -> Int
49 intToWord16 :: Int -> Word16
51 word8ToInt = word32ToInt . word8ToWord32
52 intToWord8 = word32ToWord8 . intToWord32
53 word16ToInt = word32ToInt . word16ToWord32
54 intToWord16 = word32ToWord16 . intToWord32
56 intToWord32 (I# x) = W32# (int2Word# x)
57 word32ToInt (W32# x) = I# (word2Int# x)
59 -----------------------------------------------------------------------------
61 -----------------------------------------------------------------------------
63 newtype Word8 = W8 Word32
65 word8ToWord32 (W8 x) = x .&. 0xff
68 instance Eq Word8 where (==) = binop (==)
69 instance Ord Word8 where compare = binop compare
71 instance Num Word8 where
72 x + y = to (binop (+) x y)
73 x - y = to (binop (-) x y)
74 negate = to . negate . from
75 x * y = to (binop (*) x y)
78 fromInteger = to . integer2Word
81 instance Bounded Word8 where
85 instance Real Word8 where
86 toRational x = toInteger x % 1
88 instance Integral Word8 where
89 x `div` y = to (binop div x y)
90 x `quot` y = to (binop quot x y)
91 x `rem` y = to (binop rem x y)
92 x `mod` y = to (binop mod x y)
93 x `quotRem` y = to2 (binop quotRem x y)
95 toInteger = toInteger . from
98 instance Ix Word8 where
101 | inRange b i = word32ToInt (from (i - m))
102 | otherwise = error "index: Index out of range"
103 inRange (m,n) i = m <= i && i <= n
105 instance Enum Word8 where
106 toEnum = to . intToWord32
107 fromEnum = word32ToInt . from
108 enumFrom c = map toEnum [fromEnum c .. fromEnum (maxBound::Word8)]
109 enumFromThen c d = map toEnum [fromEnum c, fromEnum d .. fromEnum (last::Word8)]
110 where last = if d < c then minBound else maxBound
112 instance Read Word8 where
113 readsPrec p = readDec
115 instance Show Word8 where
116 showsPrec p = showInt
118 instance Bits Word8 where
119 x .&. y = to (binop (.&.) x y)
120 x .|. y = to (binop (.|.) x y)
121 x `xor` y = to (binop xor x y)
122 complement = to . complement . from
123 x `shift` i = to (from x `shift` i)
126 setBit x i = to (setBit (from x) i)
127 clearBit x i = to (clearBit (from x) i)
128 complementBit x i = to (complementBit (from x) i)
129 testBit x i = testBit (from x) i
133 -----------------------------------------------------------------------------
135 -----------------------------------------------------------------------------
137 newtype Word16 = W16 Word32
139 word16ToWord32 (W16 x) = x .&. 0xffff
142 instance Eq Word16 where (==) = binop (==)
143 instance Ord Word16 where compare = binop compare
145 instance Num Word16 where
146 x + y = to (binop (+) x y)
147 x - y = to (binop (-) x y)
148 negate = to . negate . from
149 x * y = to (binop (*) x y)
152 fromInteger = to . integer2Word
153 fromInt = intToWord16
155 instance Bounded Word16 where
159 instance Real Word16 where
160 toRational x = toInteger x % 1
162 instance Integral Word16 where
163 x `div` y = to (binop div x y)
164 x `quot` y = to (binop quot x y)
165 x `rem` y = to (binop rem x y)
166 x `mod` y = to (binop mod x y)
167 x `quotRem` y = to2 (binop quotRem x y)
169 toInteger = toInteger . from
172 instance Ix Word16 where
175 | inRange b i = word32ToInt (from (i - m))
176 | otherwise = error "index: Index out of range"
177 inRange (m,n) i = m <= i && i <= n
179 instance Enum Word16 where
180 toEnum = to . intToWord32
181 fromEnum = word32ToInt . from
182 enumFrom c = map toEnum [fromEnum c .. fromEnum (maxBound::Word16)]
183 enumFromThen c d = map toEnum [fromEnum c, fromEnum d .. fromEnum (last::Word16)]
184 where last = if d < c then minBound else maxBound
186 instance Read Word16 where
187 readsPrec p = readDec
189 instance Show Word16 where
190 showsPrec p = showInt
192 instance Bits Word16 where
193 x .&. y = to (binop (.&.) x y)
194 x .|. y = to (binop (.|.) x y)
195 x `xor` y = to (binop xor x y)
196 complement = to . complement . from
197 x `shift` i = to (from x `shift` i)
200 setBit x i = to (setBit (from x) i)
201 clearBit x i = to (clearBit (from x) i)
202 complementBit x i = to (complementBit (from x) i)
203 testBit x i = testBit (from x) i
207 -----------------------------------------------------------------------------
210 -- This code assumes that Word# is 32-bits - which is true on a 32-bit
211 -- architecture, but will need to be updated for 64-bit architectures.
212 -----------------------------------------------------------------------------
214 data Word32 = W32# Word# deriving (Eq, Ord)
216 instance Num Word32 where
220 negate (W32# x) = W32# (int2Word# (negateInt# (word2Int# x)))
223 fromInteger = integer2Word
224 fromInt (I# x) = W32# (int2Word# x)
227 intop op x y = intToWord32 (word32ToInt x `op` word32ToInt y)
229 instance Bounded Word32 where
231 maxBound = minBound - 1
233 instance Real Word32 where
234 toRational x = toInteger x % 1
236 instance Integral Word32 where
237 x `div` y = if x > 0 && y < 0 then quotWord (x-y-1) y
238 else if x < 0 && y > 0 then quotWord (x-y+1) y
242 x `mod` y = if x > 0 && y < 0 || x < 0 && y > 0 then
243 if r/=0 then r+y else 0
246 where r = remWord x y
247 a `quotRem` b = (a `quot` b, a `rem` b)
248 divMod x y = (x `div` y, x `mod` y)
249 toInteger (W32# x) = int2Integer# (word2Int# x)
250 toInt (W32# x) = I# (word2Int# x)
252 {-# INLINE quotWord #-}
253 {-# INLINE remWord #-}
254 (W32# x) `quotWord` (W32# y) = W32# (x `quotWord#` y)
255 (W32# x) `remWord` (W32# y) = W32# (x `remWord#` y)
257 instance Ix Word32 where
260 | inRange b i = word32ToInt (i - m)
261 | otherwise = error "index: Index out of range"
262 inRange (m,n) i = m <= i && i <= n
264 instance Enum Word32 where
266 fromEnum = word32ToInt
267 enumFrom c = map toEnum [fromEnum c .. fromEnum (maxBound::Word32)]
268 enumFromThen c d = map toEnum [fromEnum c, fromEnum d .. fromEnum (last::Word32)]
269 where last = if d < c then minBound else maxBound
271 instance Read Word32 where
272 readsPrec p = readDec
274 instance Show Word32 where
275 showsPrec p = showInt
277 instance Bits Word32 where
281 complement x = x `xor` maxBound
282 shift (W32# x) i@(I# i#)
283 | i > 0 = W32# (shiftL# x i#)
284 | otherwise = W32# (shiftRA# x (negateInt# i#))
287 setBit x i = x .|. bit i
288 clearBit x i = x .&. complement (bit i)
289 complementBit x i = x `xor` bit i
290 testBit x i = (x .&. bit i) /= 0
294 {-# INLINE wordop #-}
295 wordop op (W32# x) (W32# y) = W32# (x `op` y)
297 -----------------------------------------------------------------------------
299 -----------------------------------------------------------------------------
301 data Word64 = W64 {lo,hi::Word32} deriving (Eq, Ord, Bounded)
303 w64ToInteger W64{lo,hi} = toInteger lo + 0x100000000 * toInteger hi
304 integerToW64 x = case x `quotRem` 0x100000000 of
305 (h,l) -> W64{lo=fromInteger l, hi=fromInteger h}
307 instance Show Word64 where
308 showsPrec p x = showsPrec p (w64ToInteger x)
310 instance Read Word64 where
311 readsPrec p s = [ (integerToW64 x,r) | (x,r) <- readDec s ]
313 -----------------------------------------------------------------------------
314 -- End of exported definitions
316 -- The remainder of this file consists of definitions which are only
317 -- used in the implementation.
318 -----------------------------------------------------------------------------
320 -----------------------------------------------------------------------------
321 -- Coercions - used to make the instance declarations more uniform
322 -----------------------------------------------------------------------------
328 instance Coerce Word8 where
332 instance Coerce Word16 where
333 from = word16ToWord32
336 binop :: Coerce word => (Word32 -> Word32 -> a) -> (word -> word -> a)
337 binop op x y = from x `op` from y
339 to2 :: Coerce word => (Word32, Word32) -> (word, word)
340 to2 (x,y) = (to x, to y)
342 integer2Word (J# a# s# d#) = W32# (int2Word# (integer2Int# a# s# d#))
344 -----------------------------------------------------------------------------
345 -- Code copied from the Prelude
346 -----------------------------------------------------------------------------
348 signumReal x | x == 0 = 0
352 -- showInt is used for positive numbers only
353 -- stolen from Hugs prelude --SDM
354 showInt :: Integral a => a -> ShowS
355 showInt n r | n < 0 = error "Word.showInt: can't show negative numbers"
357 let (n',d) = quotRem n 10
358 r' = toEnum (fromEnum '0' + fromIntegral d) : r
359 in if n' == 0 then r' else showInt n' r'