16a225ef4d4443675d1514e91c491acabe3c689f
[ghc-hetmet.git] / ghc / lib / std / PrelWord.lhs
1 %
2 % (c) The University of Glasgow, 1997-2000
3 %
4 \section[PrelWord]{Module @PrelWord@}
5
6 \begin{code}
7 #include "MachDeps.h"
8
9 module PrelWord (
10         Word8(..), Word16(..), Word32(..), Word64(..),
11
12         -- SUP: deprecated in the new FFI, subsumed by fromIntegral
13         , intToWord8      -- :: Int     -> Word8
14         , intToWord16     -- :: Int     -> Word16
15         , intToWord32     -- :: Int     -> Word32
16         , intToWord64     -- :: Int     -> Word64
17
18         , integerToWord8  -- :: Integer -> Word8
19         , integerToWord16 -- :: Integer -> Word16
20         , integerToWord32 -- :: Integer -> Word32
21         , integerToWord64 -- :: Integer -> Word64
22
23         , word8ToInt      -- :: Word8   -> Int
24         , word8ToInteger  -- :: Word8   -> Integer
25         , word8ToWord16   -- :: Word8   -> Word16
26         , word8ToWord32   -- :: Word8   -> Word32
27         , word8ToWord64   -- :: Word8   -> Word64
28
29         , word16ToInt     -- :: Word16  -> Int
30         , word16ToInteger -- :: Word16  -> Integer
31         , word16ToWord8   -- :: Word16  -> Word8
32         , word16ToWord32  -- :: Word16  -> Word32
33         , word16ToWord64  -- :: Word16  -> Word64
34
35         , word32ToInt     -- :: Word32  -> Int
36         , word32ToInteger -- :: Word32  -> Integer
37         , word32ToWord8   -- :: Word32  -> Word8
38         , word32ToWord16  -- :: Word32  -> Word16
39         , word32ToWord64  -- :: Word32  -> Word64
40
41         , word64ToInt     -- :: Word64  -> Int
42         , word64ToInteger -- :: Word64  -> Integer
43         , word64ToWord8   -- :: Word64  -> Word8
44         , word64ToWord16  -- :: Word64  -> Word16
45         , word64ToWord32  -- :: Word64  -> Word32
46
47         -- NB! GHC SPECIFIC:
48         , wordToWord8     -- :: Word    -> Word8
49         , wordToWord16    -- :: Word    -> Word16
50         , wordToWord32    -- :: Word    -> Word32
51         , wordToWord64    -- :: Word    -> Word64
52
53         , word8ToWord     -- :: Word8   -> Word
54         , word16ToWord    -- :: Word16  -> Word
55         , word32ToWord    -- :: Word32  -> Word
56         , word64ToWord    -- :: Word64  -> Word
57
58         -- The "official" place to get these from is Addr.
59         -- SUP: deprecated in the new FFI, subsumed by the Storable class
60         , indexWord8OffAddr
61         , indexWord16OffAddr
62         , indexWord32OffAddr
63         , indexWord64OffAddr
64         
65         , readWord8OffAddr
66         , readWord16OffAddr
67         , readWord32OffAddr
68         , readWord64OffAddr
69         
70         , writeWord8OffAddr
71         , writeWord16OffAddr
72         , writeWord32OffAddr
73         , writeWord64OffAddr
74
75         -- internal stuff
76         , wordToInt
77         , wordToWord8#, wordToWord16#, wordToWord32#, wordToWord64#
78
79         , word64ToInt64#, int64ToWord64#
80         , wordToWord64#, word64ToWord#
81
82         , toEnumError, fromEnumError, succError, predError, divZeroError
83   ) where
84
85 import Numeric  ( showInt )
86
87 import PrelArr
88 import PrelRead
89 import PrelIOBase
90 import PrelEnum
91 import PrelAddr
92 import PrelReal
93 import PrelNum
94 import PrelBase
95
96 -- ---------------------------------------------------------------------------
97 -- Coercion functions (DEPRECATED)
98 -- ---------------------------------------------------------------------------
99
100 intToWord8      :: Int     -> Word8
101 intToWord16     :: Int     -> Word16
102 intToWord32     :: Int     -> Word32
103 intToWord64     :: Int     -> Word64
104
105 integerToWord8  :: Integer -> Word8
106 integerToWord16 :: Integer -> Word16
107 integerToWord32 :: Integer -> Word32
108 integerToWord64 :: Integer -> Word64
109
110 word8ToInt      :: Word8   -> Int
111 word8ToInteger  :: Word8   -> Integer
112 word8ToWord16   :: Word8   -> Word16
113 word8ToWord32   :: Word8   -> Word32
114 word8ToWord64   :: Word8   -> Word64
115
116 word16ToInt     :: Word16  -> Int
117 word16ToInteger :: Word16  -> Integer
118 word16ToWord8   :: Word16  -> Word8
119 word16ToWord32  :: Word16  -> Word32
120 word16ToWord64  :: Word16  -> Word64
121
122 word32ToInt     :: Word32  -> Int
123 word32ToInteger :: Word32  -> Integer
124 word32ToWord8   :: Word32  -> Word8
125 word32ToWord16  :: Word32  -> Word16
126 word32ToWord64  :: Word32  -> Word64
127
128 word64ToInt     :: Word64  -> Int
129 word64ToInteger :: Word64  -> Integer
130 word64ToWord8   :: Word64  -> Word8
131 word64ToWord16  :: Word64  -> Word16
132 word64ToWord32  :: Word64  -> Word32
133
134 wordToWord8     :: Word    -> Word8
135 wordToWord16    :: Word    -> Word16
136 wordToWord32    :: Word    -> Word32
137 wordToWord64    :: Word    -> Word64
138
139 word8ToWord     :: Word8   -> Word
140 word16ToWord    :: Word16  -> Word
141 word32ToWord    :: Word32  -> Word
142 word64ToWord    :: Word64  -> Word
143
144 intToWord8      = word32ToWord8   . intToWord32
145 intToWord16     = word32ToWord16  . intToWord32
146
147 integerToWord8  = fromInteger
148 integerToWord16 = fromInteger
149
150 word8ToInt      = word32ToInt     . word8ToWord32
151 word8ToInteger  = word32ToInteger . word8ToWord32
152
153 word16ToInt     = word32ToInt     . word16ToWord32
154 word16ToInteger = word32ToInteger . word16ToWord32
155
156 #if WORD_SIZE_IN_BYTES > 4
157 intToWord32 (I# x)   = W32# ((int2Word# x) `and#` (case (maxBound::Word32) of W32# x# -> x#))
158 #else
159 intToWord32 (I# x)   = W32# (int2Word# x)
160 #endif
161
162 word32ToInt (W32# x) = I#   (word2Int# x)
163
164 word32ToInteger (W32# x) = word2Integer x
165 integerToWord32 = fromInteger
166
167 -----------------------------------------------------------------------------
168 -- The following rules for fromIntegral remove the need to export specialized
169 -- conversion functions.
170 -----------------------------------------------------------------------------
171
172 {-# RULES
173    "fromIntegral/Int->Word8"        fromIntegral = intToWord8;
174    "fromIntegral/Int->Word16"       fromIntegral = intToWord16;
175    "fromIntegral/Int->Word32"       fromIntegral = intToWord32;
176    "fromIntegral/Int->Word64"       fromIntegral = intToWord64;
177
178    "fromIntegral/Integer->Word8"    fromIntegral = integerToWord8;
179    "fromIntegral/Integer->Word16"   fromIntegral = integerToWord16;
180    "fromIntegral/Integer->Word32"   fromIntegral = integerToWord32;
181    "fromIntegral/Integer->Word64"   fromIntegral = integerToWord64;
182
183    "fromIntegral/Word8->Int"        fromIntegral = word8ToInt;
184    "fromIntegral/Word8->Integer"    fromIntegral = word8ToInteger;
185    "fromIntegral/Word8->Word16"     fromIntegral = word8ToWord16;
186    "fromIntegral/Word8->Word32"     fromIntegral = word8ToWord32;
187    "fromIntegral/Word8->Word64"     fromIntegral = word8ToWord64;
188
189    "fromIntegral/Word16->Int"       fromIntegral = word16ToInt;
190    "fromIntegral/Word16->Integer"   fromIntegral = word16ToInteger;
191    "fromIntegral/Word16->Word8"     fromIntegral = word16ToWord8;
192    "fromIntegral/Word16->Word32"    fromIntegral = word16ToWord32;
193    "fromIntegral/Word16->Word64"    fromIntegral = word16ToWord64;
194
195    "fromIntegral/Word32->Int"       fromIntegral = word32ToInt;
196    "fromIntegral/Word32->Integer"   fromIntegral = word32ToInteger;
197    "fromIntegral/Word32->Word8"     fromIntegral = word32ToWord8;
198    "fromIntegral/Word32->Word16"    fromIntegral = word32ToWord16;
199    "fromIntegral/Word32->Word64"    fromIntegral = word32ToWord64;
200
201    "fromIntegral/Word64->Int"       fromIntegral = word64ToInt;
202    "fromIntegral/Word64->Integer"   fromIntegral = word64ToInteger;
203    "fromIntegral/Word64->Word8"     fromIntegral = word64ToWord8;
204    "fromIntegral/Word64->Word16"    fromIntegral = word64ToWord16;
205    "fromIntegral/Word64->Word32"    fromIntegral = word64ToWord32
206  #-}
207
208 \end{code}
209
210 \subsection[Word8]{The @Word8@ interface}
211
212
213 The byte type @Word8@ is represented in the Haskell
214 heap by boxing up a 32-bit quantity, @Word#@. An invariant
215 for this representation is that the higher 24 bits are
216 *always* zeroed out. A consequence of this is that
217 operations that could possibly overflow have to mask
218 out the top three bytes before building the resulting @Word8@.
219
220 \begin{code}
221 data Word8  = W8# Word#
222
223 instance CCallable Word8
224 instance CReturnable Word8
225
226 word8ToWord32 (W8#  x) = W32# x
227 word8ToWord16 (W8#  x) = W16# x
228 word32ToWord8 (W32# x) = W8# (wordToWord8# x)
229
230 -- mask out upper three bytes.
231 intToWord8# :: Int# -> Word#
232 intToWord8# i# = (int2Word# i#) `and#` (int2Word# 0xff#)
233
234 wordToWord8# :: Word# -> Word#
235 wordToWord8# w# = w# `and#` (int2Word# 0xff#)
236
237 instance Eq  Word8     where 
238   (W8# x) == (W8# y) = x `eqWord#` y
239   (W8# x) /= (W8# y) = x `neWord#` y
240
241 instance Ord Word8     where 
242   compare (W8# x#) (W8# y#) = compareWord# x# y#
243   (<)  (W8# x) (W8# y)      = x `ltWord#` y
244   (<=) (W8# x) (W8# y)      = x `leWord#` y
245   (>=) (W8# x) (W8# y)      = x `geWord#` y
246   (>)  (W8# x) (W8# y)      = x `gtWord#` y
247   max x@(W8# x#) y@(W8# y#) = 
248      case (compareWord# x# y#) of { LT -> y ; EQ -> x ; GT -> x }
249   min x@(W8# x#) y@(W8# y#) =
250      case (compareWord# x# y#) of { LT -> x ; EQ -> x ; GT -> y }
251
252 -- Helper function, used by Ord Word* instances.
253 compareWord# :: Word# -> Word# -> Ordering
254 compareWord# x# y# 
255  | x# `ltWord#` y# = LT
256  | x# `eqWord#` y# = EQ
257  | otherwise       = GT
258
259 instance Num Word8 where
260   (W8# x) + (W8# y) = 
261       W8# (intToWord8# (word2Int# x +# word2Int# y))
262   (W8# x) - (W8# y) = 
263       W8# (intToWord8# (word2Int# x -# word2Int# y))
264   (W8# x) * (W8# y) = 
265       W8# (intToWord8# (word2Int# x *# word2Int# y))
266   negate w@(W8# x)  = 
267      if x' ==# 0# 
268       then w
269       else W8# (int2Word# (0x100# -# x'))
270      where
271       x' = word2Int# x
272   abs x         = x
273   signum        = signumReal
274   fromInteger (S# i#)    = W8# (wordToWord8# (int2Word# i#))
275   fromInteger (J# s# d#) = W8# (wordToWord8# (integer2Word# s# d#))
276   fromInt       = intToWord8
277
278 instance Bounded Word8 where
279   minBound = 0
280   maxBound = 0xff
281
282 instance Real Word8 where
283   toRational x = toInteger x % 1
284
285 -- Note: no need to mask results here 
286 -- as they cannot overflow.
287 instance Integral Word8 where
288   div  x@(W8# x#)  (W8# y#) 
289     | y# `neWord#` (int2Word# 0#) = W8# (x# `quotWord#` y#)
290     | otherwise                   = divZeroError "div{Word8}" x
291
292   quot x@(W8# x#)  (W8# y#)   
293     | y# `neWord#` (int2Word# 0#) = W8# (x# `quotWord#` y#)
294     | otherwise                   = divZeroError "quot{Word8}" x
295
296   rem  x@(W8# x#)  (W8# y#)
297     | y# `neWord#` (int2Word# 0#) = W8# (x# `remWord#` y#)
298     | otherwise                   = divZeroError "rem{Word8}" x
299
300   mod  x@(W8# x#)  (W8# y#)
301     | y# `neWord#` (int2Word# 0#) = W8# (x# `remWord#` y#)
302     | otherwise                   = divZeroError "mod{Word8}" x
303
304   quotRem (W8# x) (W8# y) = (W8# (x `quotWord#` y), W8# (x `remWord#` y))
305   divMod  (W8# x) (W8# y) = (W8# (x `quotWord#` y), W8# (x `remWord#` y))
306
307   toInteger = toInteger . toInt
308   toInt     = word8ToInt
309
310 instance Ix Word8 where
311     range (m,n)          = [m..n]
312     index b@(m,_) i
313            | inRange b i = word8ToInt (i-m)
314            | otherwise   = indexError b i "Word8"
315     inRange (m,n) i      = m <= i && i <= n
316
317 instance Enum Word8 where
318     succ w          
319       | w == maxBound = succError "Word8"
320       | otherwise     = w+1
321     pred w          
322       | w == minBound = predError "Word8"
323       | otherwise     = w-1
324
325     toEnum   i@(I# i#)  
326       | i >= toInt (minBound::Word8) && i <= toInt (maxBound::Word8) 
327       = W8# (intToWord8# i#)
328       | otherwise
329       = toEnumError "Word8" i (minBound::Word8,maxBound::Word8)
330
331     fromEnum  (W8# w) = I# (word2Int# w)
332
333     enumFrom          = boundedEnumFrom
334     enumFromThen      = boundedEnumFromThen
335
336 instance Read Word8 where
337     readsPrec _ = readDec
338
339 instance Show Word8 where
340     showsPrec _ = showInt
341 \end{code}
342
343 \subsection[Word16]{The @Word16@ interface}
344
345 The double byte type @Word16@ is represented in the Haskell
346 heap by boxing up a machine word, @Word#@. An invariant
347 for this representation is that only the lower 16 bits are
348 `active', any bits above are {\em always} zeroed out.
349 A consequence of this is that operations that could possibly
350 overflow have to mask out anything above the lower two bytes
351 before putting together the resulting @Word16@.
352
353 \begin{code}
354 data Word16 = W16# Word#
355
356 instance CCallable Word16
357 instance CReturnable Word16
358
359 word16ToWord8  (W16# x) = W8#  (wordToWord8#  x)
360 word16ToWord32 (W16# x) = W32# x
361
362 word32ToWord16 (W32# x) = W16# (wordToWord16# x)
363
364 -- mask out upper 16 bits.
365 intToWord16# :: Int# -> Word#
366 intToWord16# i# = ((int2Word# i#) `and#` (int2Word# 0xffff#))
367
368 wordToWord16# :: Word# -> Word#
369 wordToWord16# w# = w# `and#` (int2Word# 0xffff#)
370
371 instance Eq  Word16    where 
372   (W16# x) == (W16# y) = x `eqWord#` y
373   (W16# x) /= (W16# y) = x `neWord#` y
374
375 instance Ord Word16     where
376   compare (W16# x#) (W16# y#) = compareWord# x# y#
377   (<)  (W16# x) (W16# y)      = x `ltWord#` y
378   (<=) (W16# x) (W16# y)      = x `leWord#` y
379   (>=) (W16# x) (W16# y)      = x `geWord#` y
380   (>)  (W16# x) (W16# y)      = x `gtWord#` y
381   max x@(W16# x#) y@(W16# y#) = 
382      case (compareWord# x# y#) of { LT -> y ; EQ -> x ; GT -> x }
383   min x@(W16# x#) y@(W16# y#) =
384      case (compareWord# x# y#) of { LT -> x ; EQ -> x ; GT -> y }
385
386
387
388 instance Num Word16 where
389   (W16# x) + (W16# y) = 
390        W16# (intToWord16# (word2Int# x +# word2Int# y))
391   (W16# x) - (W16# y) = 
392        W16# (intToWord16# (word2Int# x -# word2Int# y))
393   (W16# x) * (W16# y) = 
394        W16# (intToWord16# (word2Int# x *# word2Int# y))
395   negate w@(W16# x)  = 
396        if x' ==# 0# 
397         then w
398         else W16# (int2Word# (0x10000# -# x'))
399        where
400         x' = word2Int# x
401   abs x         = x
402   signum        = signumReal
403   fromInteger (S# i#)    = W16# (wordToWord16# (int2Word# i#))
404   fromInteger (J# s# d#) = W16# (wordToWord16# (integer2Word# s# d#))
405   fromInt       = intToWord16
406
407 instance Bounded Word16 where
408   minBound = 0
409   maxBound = 0xffff
410
411 instance Real Word16 where
412   toRational x = toInteger x % 1
413
414 instance Integral Word16 where
415   div  x@(W16# x#)  (W16# y#)
416    | y# `neWord#` (int2Word# 0#) = W16# (x# `quotWord#` y#)
417    | otherwise                   = divZeroError "div{Word16}" x
418
419   quot x@(W16# x#) (W16# y#)
420    | y# `neWord#`(int2Word# 0#)  = W16# (x# `quotWord#` y#)
421    | otherwise                   = divZeroError "quot{Word16}" x
422
423   rem  x@(W16# x#) (W16# y#)
424    | y# `neWord#` (int2Word# 0#) = W16# (x# `remWord#` y#)
425    | otherwise                   = divZeroError "rem{Word16}" x
426
427   mod  x@(W16# x#)  (W16# y#)
428    | y# `neWord#` (int2Word# 0#) = W16# (x# `remWord#` y#)
429    | otherwise                   = divZeroError "mod{Word16}" x
430
431   quotRem (W16# x) (W16# y) = (W16# (x `quotWord#` y), W16# (x `remWord#` y))
432   divMod  (W16# x) (W16# y) = (W16# (x `quotWord#` y), W16# (x `remWord#` y))
433
434   toInteger = toInteger . toInt
435   toInt     = word16ToInt
436
437 instance Ix Word16 where
438   range (m,n)          = [m..n]
439   index b@(m,_) i
440          | inRange b i = word16ToInt (i - m)
441          | otherwise   = indexError b i "Word16"
442   inRange (m,n) i      = m <= i && i <= n
443
444 instance Enum Word16 where
445     succ w          
446       | w == maxBound = succError "Word16"
447       | otherwise     = w+1
448     pred w          
449       | w == minBound = predError "Word16"
450       | otherwise     = w-1
451
452     toEnum   i@(I# i#)  
453       | i >= toInt (minBound::Word16) && i <= toInt (maxBound::Word16)
454       = W16# (intToWord16# i#)
455       | otherwise
456       = toEnumError "Word16" i (minBound::Word16,maxBound::Word16)
457
458     fromEnum  (W16# w) = I# (word2Int# w)
459     enumFrom     = boundedEnumFrom
460     enumFromThen = boundedEnumFromThen
461
462 instance Read Word16 where
463   readsPrec _ = readDec
464
465 instance Show Word16 where
466   showsPrec _ = showInt
467 \end{code}
468
469 \subsection[Word32]{The @Word32@ interface}
470
471 The quad byte type @Word32@ is represented in the Haskell
472 heap by boxing up a machine word, @Word#@. An invariant
473 for this representation is that any bits above the lower
474 32 are {\em always} zeroed out. A consequence of this is that
475 operations that could possibly overflow have to mask
476 the result before building the resulting @Word16@.
477
478 \begin{code}
479 data Word32 = W32# Word#
480
481 instance CCallable Word32
482 instance CReturnable Word32
483
484 instance Eq  Word32    where 
485   (W32# x) == (W32# y) = x `eqWord#` y
486   (W32# x) /= (W32# y) = x `neWord#` y
487
488 instance Ord Word32    where
489   compare (W32# x#) (W32# y#) = compareWord# x# y#
490   (<)  (W32# x) (W32# y)      = x `ltWord#` y
491   (<=) (W32# x) (W32# y)      = x `leWord#` y
492   (>=) (W32# x) (W32# y)      = x `geWord#` y
493   (>)  (W32# x) (W32# y)      = x `gtWord#` y
494   max x@(W32# x#) y@(W32# y#) = 
495      case (compareWord# x# y#) of { LT -> y ; EQ -> x ; GT -> x }
496   min x@(W32# x#) y@(W32# y#) =
497      case (compareWord# x# y#) of { LT -> x ; EQ -> x ; GT -> y }
498
499 instance Num Word32 where
500   (W32# x) + (W32# y) = 
501        W32# (intToWord32# (word2Int# x +# word2Int# y))
502   (W32# x) - (W32# y) =
503        W32# (intToWord32# (word2Int# x -# word2Int# y))
504   (W32# x) * (W32# y) = 
505        W32# (intToWord32# (word2Int# x *# word2Int# y))
506 #if WORD_SIZE_IN_BYTES == 8
507   negate w@(W32# x)  = 
508       if x' ==# 0#
509        then w
510        else W32# (intToWord32# (0x100000000# -# x'))
511        where
512         x' = word2Int# x
513 #else
514   negate (W32# x)  = W32# (intToWord32# (negateInt# (word2Int# x)))
515 #endif
516   abs x           = x
517   signum          = signumReal
518   fromInteger (S# i#)    = W32# (intToWord32# i#)
519   fromInteger (J# s# d#) = W32# (wordToWord32# (integer2Word# s# d#))
520   fromInt (I# x)  = W32# (intToWord32# x)
521     -- ToDo: restrict fromInt{eger} range.
522
523 intToWord32#  :: Int#  -> Word#
524 wordToWord32# :: Word# -> Word#
525
526 #if WORD_SIZE_IN_BYTES == 8
527 intToWord32#  i#  = (int2Word# i#) `and#` (int2Word# 0xffffffff#)
528 wordToWord32# w#  = w# `and#` (int2Word# 0xffffffff#)
529 wordToWord64# w#  = w#
530 #else
531 intToWord32#  i# = int2Word# i#
532 wordToWord32# w# = w#
533 #endif
534
535 instance Bounded Word32 where
536     minBound = 0
537 #if WORD_SIZE_IN_BYTES == 8
538     maxBound = 0xffffffff
539 #else
540     maxBound = minBound - 1
541 #endif
542
543 instance Real Word32 where
544     toRational x = toInteger x % 1
545
546 instance Integral Word32 where
547     div  x y 
548       | y /= 0         = quotWord32 x y
549       | otherwise      = divZeroError "div{Word32}" x
550
551     quot x y
552       | y /= 0         = quotWord32 x y
553       | otherwise      = divZeroError "quot{Word32}" x
554
555     rem  x y
556       | y /= 0         = remWord32 x y
557       | otherwise      = divZeroError "rem{Word32}" x
558
559     mod  x y
560       | y /= 0         = remWord32 x y
561       | otherwise      = divZeroError "mod{Word32}" x
562
563     quotRem a b        = (a `quot` b, a `rem` b)
564     divMod x y         = quotRem x y
565
566     toInteger          = word32ToInteger 
567     toInt              = word32ToInt
568
569
570 {-# INLINE quotWord32 #-}
571 {-# INLINE remWord32  #-}
572 remWord32, quotWord32 :: Word32 -> Word32 -> Word32
573 (W32# x) `quotWord32` (W32# y) = W32# (x `quotWord#` y)
574 (W32# x) `remWord32`  (W32# y) = W32# (x `remWord#`  y)
575
576
577 instance Ix Word32 where
578     range (m,n)          = [m..n]
579     index b@(m,_) i
580            | inRange b i = word32ToInt (i - m)
581            | otherwise   = indexError b i "Word32"
582     inRange (m,n) i      = m <= i && i <= n
583
584 instance Enum Word32 where
585     succ w          
586       | w == maxBound = succError "Word32"
587       | otherwise     = w+1
588     pred w          
589       | w == minBound = predError "Word32"
590       | otherwise     = w-1
591
592      -- the toEnum/fromEnum will fail if the mapping isn't legal,
593      -- use the intTo* & *ToInt coercion functions to 'bypass' these range checks.
594     toEnum   x
595       | x >= 0    = intToWord32 x
596       | otherwise
597       = toEnumError "Word32" x (minBound::Word32,maxBound::Word32)
598
599     fromEnum   x
600       | x <= intToWord32 (maxBound::Int)
601       = word32ToInt x
602       | otherwise
603       = fromEnumError "Word32" x 
604
605     enumFrom w           = [w .. maxBound]
606     enumFromTo   w1 w2
607        | w1 <= w2        = eftt32 True{-increasing-} w1 diff_f last
608        | otherwise       = []
609         where
610          last = (> w2)
611          diff_f x = x + 1 
612           
613     enumFromThen w1 w2   = [w1,w2 .. last]
614        where
615          last :: Word32
616          last
617           | w1 <=w2   = maxBound
618           | otherwise = minBound
619
620     enumFromThenTo w1 w2 wend  = eftt32 increasing w1 step_f last
621      where
622        increasing = w1 <= w2
623        diff1 = w2 - w1
624        diff2 = w1 - w2
625        
626        last
627         | increasing = (> wend)
628         | otherwise  = (< wend)
629
630        step_f 
631         | increasing = \ x -> x + diff1
632         | otherwise  = \ x -> x - diff2
633
634 eftt32 :: Bool -> Word32 -> (Word32 -> Word32) -> (Word32-> Bool) -> [Word32]
635 eftt32 increasing init stepper done = go init
636   where
637     go now
638      | done now                    = []
639      | increasing     && now > nxt = [now] -- oflow
640      | not increasing && now < nxt = [now] -- uflow
641      | otherwise                   = now : go nxt
642      where
643       nxt = stepper now 
644
645 instance Read Word32 where
646     readsPrec _ = readDec
647
648 instance Show Word32 where
649     showsPrec _ = showInt
650
651 -- -----------------------------------------------------------------------------
652 -- Word64
653 -- -----------------------------------------------------------------------------
654
655 #if WORD_SIZE_IN_BYTES == 8
656 --data Word64 = W64# Word#
657
658 word32ToWord64 (W32 w#) = W64# w#
659
660 word8ToWord64 (W8# w#) = W64# w#
661 word64ToWord8 (W64# w#) = W8# (w# `and#` (int2Word# 0xff#))
662
663 word16ToWord64 (W16# w#) = W64# w#
664 word64ToWord16 (W64# w#) = W16# (w# `and#` (int2Word# 0xffff#))
665
666 wordToWord32# :: Word# -> Word#
667 wordToWord32# w# = w# `and#` (case (maxBound::Word32) of W# x# -> x#)
668
669 word64ToWord32 :: Word64 -> Word32
670 word64ToWord32 (W64# w#) = W32# (wordToWord32# w#)
671
672 wordToWord64# w# = w#
673 word64ToWord# w# = w#
674
675 instance Eq  Word64     where 
676   (W64# x) == (W64# y) = x `eqWord#` y
677   (W64# x) /= (W64# y) = x `neWord#` y
678
679 instance Ord Word64     where 
680   compare (W64# x#) (W64# y#) = compareWord# x# y#
681   (<)  (W64# x) (W64# y)      = x `ltWord#` y
682   (<=) (W64# x) (W64# y)      = x `leWord#` y
683   (>=) (W64# x) (W64# y)      = x `geWord#` y
684   (>)  (W64# x) (W64# y)      = x `gtWord#` y
685   max x@(W64# x#) y@(W64# y#) = 
686      case (compareWord# x# y#) of { LT -> y ; EQ -> x ; GT -> x }
687   min x@(W64# x#) y@(W64# y#) =
688      case (compareWord# x# y#) of { LT -> x ; EQ -> x ; GT -> y }
689
690 instance Num Word64 where
691   (W64# x) + (W64# y) = 
692       W64# (intToWord64# (word2Int# x +# word2Int# y))
693   (W64# x) - (W64# y) = 
694       W64# (intToWord64# (word2Int# x -# word2Int# y))
695   (W64# x) * (W64# y) = 
696       W64# (intToWord64# (word2Int# x *# word2Int# y))
697   negate w@(W64# x)  = 
698      if x' ==# 0# 
699       then w
700       else W64# (int2Word# (0x100# -# x'))
701      where
702       x' = word2Int# x
703   abs x         = x
704   signum        = signumReal
705   fromInteger (S# i#)    = W64# (int2Word# i#)
706   fromInteger (J# s# d#) = W64# (integer2Word# s# d#)
707   fromInt       = intToWord64
708
709 -- Note: no need to mask results here 
710 -- as they cannot overflow.
711 instance Integral Word64 where
712   div  x@(W64# x#)  (W64# y#)
713     | y# `neWord#` (int2Word# 0#)  = W64# (x# `quotWord#` y#)
714     | otherwise                    = divZeroError "div{Word64}" x
715
716   quot x@(W64# x#)  (W64# y#)
717     | y# `neWord#` (int2Word# 0#)  = W64# (x# `quotWord#` y#)
718     | otherwise                    = divZeroError "quot{Word64}" x
719
720   rem  x@(W64# x#)  (W64# y#)
721     | y# `neWord#` (int2Word# 0#)  = W64# (x# `remWord#` y#)
722     | otherwise                    = divZeroError "rem{Word64}" x
723
724   mod  (W64# x)  (W64# y)   
725     | y# `neWord#` (int2Word# 0#)  = W64# (x `remWord#` y)
726     | otherwise                    = divZeroError "mod{Word64}" x
727
728   quotRem (W64# x) (W64# y) = (W64# (x `quotWord#` y), W64# (x `remWord#` y))
729   divMod  (W64# x) (W64# y) = (W64# (x `quotWord#` y), W64# (x `remWord#` y))
730
731   toInteger (W64# x)        = word2Integer# x
732   toInt x                   = word64ToInt x
733
734 #else /* WORD_SIZE_IN_BYTES < 8 */
735
736 --defined in PrelCCall: data Word64 = W64 Word64# deriving (Eq, Ord, Bounded)
737
738 -- for completeness sake
739 word32ToWord64 (W32# w#) = W64# (wordToWord64# w#)
740 word64ToWord32 (W64# w#) = W32# (word64ToWord# w#)
741
742 word8ToWord64 (W8# w#) = W64# (wordToWord64# w#)
743 word64ToWord8 (W64# w#) = W8# ((word64ToWord# w#) `and#` (int2Word# 0xff#))
744
745 word16ToWord64 (W16# w#) = W64# (wordToWord64# w#)
746 word64ToWord16 (W64# w#) = W16# ((word64ToWord# w#) `and#` (int2Word# 0xffff#))
747
748 word64ToInteger (W64# w#) = 
749   case word64ToInteger# w# of
750     (# s#, p# #) -> J# s# p#
751 word64ToInt w = 
752    case w `quotRem` 0x100000000 of 
753      (_,l) -> toInt (word64ToWord32 l)
754
755 intToWord64# :: Int# -> Word64#
756 intToWord64# i# = wordToWord64# (int2Word# i#)
757
758 intToWord64 (I# i#) = W64# (intToWord64# i#)
759
760 integerToWord64 (S# i#)    = W64# (intToWord64# i#)
761 integerToWord64 (J# s# d#) = W64# (integerToWord64# s# d#)
762
763 instance Eq  Word64     where 
764   (W64# x) == (W64# y) = x `eqWord64#` y
765   (W64# x) /= (W64# y) = not (x `eqWord64#` y)
766
767 instance Ord Word64     where 
768   compare (W64# x#) (W64# y#) = compareWord64# x# y#
769   (<)  (W64# x) (W64# y)      = x `ltWord64#` y
770   (<=) (W64# x) (W64# y)      = x `leWord64#` y
771   (>=) (W64# x) (W64# y)      = x `geWord64#` y
772   (>)  (W64# x) (W64# y)      = x `gtWord64#` y
773   max x@(W64# x#) y@(W64# y#) = 
774      case (compareWord64# x# y#) of { LT -> y ; EQ -> x ; GT -> x }
775   min x@(W64# x#) y@(W64# y#) =
776      case (compareWord64# x# y#) of { LT -> x ; EQ -> x ; GT -> y }
777
778 instance Num Word64 where
779   (W64# x) + (W64# y) = 
780       W64# (int64ToWord64# (word64ToInt64# x `plusInt64#` word64ToInt64# y))
781   (W64# x) - (W64# y) = 
782       W64# (int64ToWord64# (word64ToInt64# x `minusInt64#` word64ToInt64# y))
783   (W64# x) * (W64# y) = 
784       W64# (int64ToWord64# (word64ToInt64# x `timesInt64#` word64ToInt64# y))
785   negate w
786      | w == 0     = w
787      | otherwise  = maxBound - w
788
789   abs x         = x
790   signum        = signumReal
791   fromInteger i = integerToWord64 i
792   fromInt       = intToWord64
793
794 -- Note: no need to mask results here  as they cannot overflow.
795 -- ToDo: protect against div by zero.
796 instance Integral Word64 where
797   div  (W64# x)  (W64# y)   = W64# (x `quotWord64#` y)
798   quot (W64# x)  (W64# y)   = W64# (x `quotWord64#` y)
799   rem  (W64# x)  (W64# y)   = W64# (x `remWord64#` y)
800   mod  (W64# x)  (W64# y)   = W64# (x `remWord64#` y)
801   quotRem (W64# x) (W64# y) = (W64# (x `quotWord64#` y), W64# (x `remWord64#` y))
802   divMod  (W64# x) (W64# y) = (W64# (x `quotWord64#` y), W64# (x `remWord64#` y))
803   toInteger w64             = word64ToInteger w64
804   toInt x                   = word64ToInt x
805
806 compareWord64# :: Word64# -> Word64# -> Ordering
807 compareWord64# i# j# 
808  | i# `ltWord64#` j# = LT
809  | i# `eqWord64#` j# = EQ
810  | otherwise         = GT
811
812 -- Word64# primop wrappers:
813
814 ltWord64# :: Word64# -> Word64# -> Bool
815 ltWord64# x# y# = stg_ltWord64 x# y# /= 0
816
817 leWord64# :: Word64# -> Word64# -> Bool
818 leWord64# x# y# = stg_leWord64 x# y# /= 0
819
820 eqWord64# :: Word64# -> Word64# -> Bool
821 eqWord64# x# y# = stg_eqWord64 x# y# /= 0
822       
823 neWord64# :: Word64# -> Word64# -> Bool
824 neWord64# x# y# = stg_neWord64 x# y# /= 0
825       
826 geWord64# :: Word64# -> Word64# -> Bool
827 geWord64# x# y# = stg_geWord64 x# y# /= 0
828       
829 gtWord64# :: Word64# -> Word64# -> Bool
830 gtWord64# x# y# = stg_gtWord64 x# y# /= 0
831
832 plusInt64# :: Int64# -> Int64# -> Int64#
833 plusInt64# a# b# = case stg_plusInt64 a# b# of { I64# i# -> i# }
834
835 minusInt64# :: Int64# -> Int64# -> Int64#
836 minusInt64# a# b# = case stg_minusInt64 a# b# of { I64# i# -> i# }
837
838 timesInt64# :: Int64# -> Int64# -> Int64#
839 timesInt64# a# b# = case stg_timesInt64 a# b# of { I64# i# -> i# }
840
841 quotWord64# :: Word64# -> Word64# -> Word64#
842 quotWord64# a# b# = case stg_quotWord64 a# b# of { W64# w# -> w# }
843
844 remWord64# :: Word64# -> Word64# -> Word64#
845 remWord64# a# b# = case stg_remWord64 a# b# of { W64# w# -> w# }
846
847 negateInt64# :: Int64# -> Int64#
848 negateInt64# a# = case stg_negateInt64 a# of { I64# i# -> i# }
849
850 word64ToWord# :: Word64# -> Word#
851 word64ToWord# w64# = case stg_word64ToWord w64# of { W# w# -> w# }
852       
853 wordToWord64# :: Word# -> Word64#
854 wordToWord64# w# = case stg_wordToWord64 w# of { W64# w64# -> w64# }
855
856 word64ToInt64# :: Word64# -> Int64#
857 word64ToInt64# w64# = case stg_word64ToInt64 w64# of { I64# i# -> i# }
858
859 int64ToWord64# :: Int64# -> Word64#
860 int64ToWord64# i64# = case stg_int64ToWord64 i64# of { W64# w# -> w# }
861
862 intToInt64# :: Int# -> Int64#
863 intToInt64# i# = case stg_intToInt64 i# of { I64# i64# -> i64# }
864       
865 foreign import "stg_intToInt64" unsafe stg_intToInt64 :: Int# -> Int64
866 foreign import "stg_int64ToWord64" unsafe stg_int64ToWord64 :: Int64# -> Word64
867 foreign import "stg_word64ToInt64" unsafe stg_word64ToInt64 :: Word64# -> Int64
868 foreign import "stg_wordToWord64" unsafe stg_wordToWord64 :: Word# -> Word64
869 foreign import "stg_word64ToWord" unsafe stg_word64ToWord :: Word64# -> Word
870 foreign import "stg_negateInt64" unsafe stg_negateInt64 :: Int64# -> Int64
871 foreign import "stg_remWord64" unsafe stg_remWord64 :: Word64# -> Word64# -> Word64
872 foreign import "stg_quotWord64" unsafe stg_quotWord64 :: Word64# -> Word64# -> Word64
873 foreign import "stg_timesInt64" unsafe stg_timesInt64 :: Int64# -> Int64# -> Int64
874 foreign import "stg_minusInt64" unsafe stg_minusInt64 :: Int64# -> Int64# -> Int64
875 foreign import "stg_plusInt64" unsafe stg_plusInt64 :: Int64# -> Int64# -> Int64
876 foreign import "stg_gtWord64" unsafe stg_gtWord64 :: Word64# -> Word64# -> Int
877 foreign import "stg_geWord64" unsafe stg_geWord64 :: Word64# -> Word64# -> Int
878 foreign import "stg_neWord64" unsafe stg_neWord64 :: Word64# -> Word64# -> Int
879 foreign import "stg_eqWord64" unsafe stg_eqWord64 :: Word64# -> Word64# -> Int
880 foreign import "stg_leWord64" unsafe stg_leWord64 :: Word64# -> Word64# -> Int
881 foreign import "stg_ltWord64" unsafe stg_ltWord64 :: Word64# -> Word64# -> Int
882
883 #endif
884
885 instance Enum Word64 where
886     succ w          
887       | w == maxBound = succError "Word64"
888       | otherwise     = w+1
889     pred w          
890       | w == minBound = predError "Word64"
891       | otherwise     = w-1
892
893     toEnum i
894       | i >= 0    = intToWord64 i
895       | otherwise 
896       = toEnumError "Word64" i (minBound::Word64,maxBound::Word64)
897
898     fromEnum w
899       | w <= intToWord64 (maxBound::Int)
900       = word64ToInt w
901       | otherwise
902       = fromEnumError "Word64" w
903
904     enumFrom e1        = map integerToWord64 [word64ToInteger e1 .. word64ToInteger maxBound]
905     enumFromTo e1 e2   = map integerToWord64 [word64ToInteger e1 .. word64ToInteger e2]
906     enumFromThen e1 e2 = map integerToWord64 [word64ToInteger e1, word64ToInteger e2 .. word64ToInteger last]
907                        where 
908                           last :: Word64
909                           last 
910                            | e2 < e1   = minBound
911                            | otherwise = maxBound
912
913     enumFromThenTo e1 e2 e3 = map integerToWord64 [word64ToInteger e1, word64ToInteger e2 .. word64ToInteger e3]
914
915 instance Show Word64 where
916   showsPrec p x = showsPrec p (word64ToInteger x)
917
918 instance Read Word64 where
919   readsPrec _ s = [ (integerToWord64 x,r) | (x,r) <- readDec s ]
920
921 instance Ix Word64 where
922     range (m,n)          = [m..n]
923     index b@(m,_) i
924            | inRange b i = word64ToInt (i-m)
925            | otherwise   = indexError b i "Word64"
926     inRange (m,n) i      = m <= i && i <= n
927
928 instance Bounded Word64 where
929   minBound = 0
930   maxBound = minBound - 1
931
932 instance Real Word64 where
933   toRational x = toInteger x % 1
934
935 -- -----------------------------------------------------------------------------
936 -- Reading/writing words to/from memory
937 -- -----------------------------------------------------------------------------
938
939 indexWord8OffAddr  :: Addr -> Int -> Word8
940 indexWord8OffAddr (A# a#) (I# i#) = W8# (indexWord8OffAddr# a# i#)
941
942 indexWord16OffAddr  :: Addr -> Int -> Word16
943 indexWord16OffAddr (A# a#) (I# i#) = W16# (indexWord16OffAddr# a# i#)
944
945 indexWord32OffAddr  :: Addr -> Int -> Word32
946 indexWord32OffAddr (A# a#) (I# i#) = W32# (indexWord32OffAddr# a# i#)
947
948 indexWord64OffAddr  :: Addr -> Int -> Word64
949 #if WORD_SIZE_IN_BYTES == 8
950 indexWord64OffAddr (A# a#) (I# i#) = W64# (indexWordOffAddr# a# i#)
951 #else
952 indexWord64OffAddr (A# a#) (I# i#) = W64# (indexWord64OffAddr# a# i#)
953 #endif
954
955
956 readWord8OffAddr :: Addr -> Int -> IO Word8
957 readWord8OffAddr (A# a) (I# i)
958   = IO $ \s -> case readWord8OffAddr# a i s of (# s, w #) -> (# s, W8# w #)
959
960 readWord16OffAddr :: Addr -> Int -> IO Word16
961 readWord16OffAddr (A# a) (I# i)
962   = IO $ \s -> case readWord16OffAddr# a i s of (# s, w #) -> (# s, W16# w #)
963
964 readWord32OffAddr :: Addr -> Int -> IO Word32
965 readWord32OffAddr (A# a) (I# i)
966   = IO $ \s -> case readWord32OffAddr# a i s of (# s, w #) -> (# s, W32# w #)
967
968 readWord64OffAddr  :: Addr -> Int -> IO Word64
969 #if WORD_SIZE_IN_BYTES == 8
970 readWord64OffAddr (A# a) (I# i)
971   = IO $ \s -> case readWordOffAddr# a i s of (# s, w #) -> (# s, W64# w #)
972 #else
973 readWord64OffAddr (A# a) (I# i)
974   = IO $ \s -> case readWord64OffAddr# a i s of (# s, w #) -> (# s, W64# w #)
975 #endif
976
977
978 writeWord8OffAddr  :: Addr -> Int -> Word8  -> IO ()
979 writeWord8OffAddr (A# a#) (I# i#) (W8# w#) = IO $ \ s# ->
980       case (writeWord8OffAddr# a# i# w# s#) of s2# -> (# s2#, () #)
981
982 writeWord16OffAddr  :: Addr -> Int -> Word16  -> IO ()
983 writeWord16OffAddr (A# a#) (I# i#) (W16# w#) = IO $ \ s# ->
984       case (writeWord16OffAddr# a# i# w# s#) of s2# -> (# s2#, () #)
985
986 writeWord32OffAddr  :: Addr -> Int -> Word32  -> IO ()
987 writeWord32OffAddr (A# a#) (I# i#) (W32# w#) = IO $ \ s# ->
988       case (writeWord32OffAddr# a# i# w# s#) of s2# -> (# s2#, () #)
989
990 writeWord64OffAddr :: Addr -> Int -> Word64 -> IO ()
991 #if WORD_SIZE_IN_BYTES == 8
992 writeWord64OffAddr (A# a#) (I# i#) (W64# w#) = IO $ \ s# ->
993       case (writeWordOffAddr#  a# i# w# s#) of s2# -> (# s2#, () #)
994 #else
995 writeWord64OffAddr (A# a#) (I# i#) (W64# w#) = IO $ \ s# ->
996       case (writeWord64OffAddr#  a# i# w# s#) of s2# -> (# s2#, () #)
997 #endif
998 \end{code}
999
1000 The Hugs-GHC extension libraries provide functions for going between
1001 Int and the various (un)signed ints. Here we provide the same for
1002 the GHC specific Word type:
1003
1004 \begin{code}
1005 word8ToWord  (W8#  w#) = W# w#
1006 wordToWord8  (W#   w#)  = W8# (w# `and#` (case (maxBound::Word8) of W8#   x# -> x#))
1007
1008 word16ToWord (W16# w#) = W# w#
1009 wordToWord16 (W#   w#) = W16# (w# `and#` (case (maxBound::Word16) of W16# x# -> x#))
1010
1011 word32ToWord (W32# w#) = W# w#
1012 wordToWord32 (W#   w#) = W32# (w# `and#` (case (maxBound::Word32) of W32# x# -> x#))
1013
1014 wordToWord64 (W#   w#) = W64# (wordToWord64# w#)
1015 -- lossy on 32-bit platforms, but provided nontheless.
1016 word64ToWord (W64# w#) = W#   (word64ToWord# w#)
1017
1018 word2Integer :: Word# -> Integer
1019 word2Integer w | i >=# 0#   = S# i
1020                | otherwise = case word2Integer# w of
1021                                 (# s, d #) -> J# s d
1022    where i = word2Int# w
1023 \end{code}
1024
1025 Misc utils.
1026
1027 \begin{code}
1028 signumReal :: (Ord a, Num a) => a -> a
1029 signumReal x | x == 0    =  0
1030              | x > 0     =  1
1031              | otherwise = -1
1032 \end{code}
1033
1034 Utils for generating friendly error messages.
1035
1036 \begin{code}
1037 toEnumError :: (Show a,Show b) => String -> a -> (b,b) -> c
1038 toEnumError inst_ty tag bnds
1039   = error ("Enum.toEnum{" ++ inst_ty ++ "}: tag " ++
1040            (showParen True (showsPrec 0 tag) $
1041              " is outside of bounds " ++
1042              show bnds))
1043
1044 fromEnumError :: (Show a,Show b) => String -> a -> b
1045 fromEnumError inst_ty tag
1046   = error ("Enum.fromEnum{" ++ inst_ty ++ "}: value " ++
1047            (showParen True (showsPrec 0 tag) $
1048              " is outside of Int's bounds " ++
1049              show (minBound::Int,maxBound::Int)))
1050
1051 succError :: String -> a
1052 succError inst_ty
1053   = error ("Enum.succ{" ++ inst_ty ++ "}: tried to take `succ' of maxBound")
1054
1055 predError :: String -> a
1056 predError inst_ty
1057   = error ("Enum.pred{" ++ inst_ty ++ "}: tried to take `pred' of minBound")
1058
1059 divZeroError :: (Show a) => String -> a -> b
1060 divZeroError meth v 
1061   = error ("Integral." ++ meth ++ ": divide by 0 (" ++ show v ++ " / 0)")
1062 \end{code}