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