summaryrefslogtreecommitdiff
path: root/ghc/lib/glaExts
diff options
context:
space:
mode:
authorsimonm <unknown>1997-11-11 14:34:23 +0000
committersimonm <unknown>1997-11-11 14:34:23 +0000
commita138ab7b559413b7b27fec48e9eeefd08862159c (patch)
tree5e4af03795fb518d75d643ea69bf3dc49a497840 /ghc/lib/glaExts
parentd51f7ef704de2c33db43a9f384e83eac8605bb61 (diff)
downloadhaskell-a138ab7b559413b7b27fec48e9eeefd08862159c.tar.gz
[project @ 1997-11-11 14:32:34 by simonm]
Library changes to: * remove PrimIO * change type of _ccall_ to IO * incorporate Alastair Reid's new library interfaces for compatibility with Hugs.
Diffstat (limited to 'ghc/lib/glaExts')
-rw-r--r--ghc/lib/glaExts/Addr.lhs31
-rw-r--r--ghc/lib/glaExts/Bits.lhs37
-rw-r--r--ghc/lib/glaExts/ByteArray.lhs3
-rw-r--r--ghc/lib/glaExts/CCall.lhs56
-rw-r--r--ghc/lib/glaExts/Foreign.lhs140
-rw-r--r--ghc/lib/glaExts/GlaExts.lhs25
-rw-r--r--ghc/lib/glaExts/IOExts.lhs31
-rw-r--r--ghc/lib/glaExts/IORef.lhs34
-rw-r--r--ghc/lib/glaExts/Int.lhs346
-rw-r--r--ghc/lib/glaExts/LazyST.lhs104
-rw-r--r--ghc/lib/glaExts/MutVar.lhs44
-rw-r--r--ghc/lib/glaExts/ST.lhs84
-rw-r--r--ghc/lib/glaExts/Word.lhs354
13 files changed, 1108 insertions, 181 deletions
diff --git a/ghc/lib/glaExts/Addr.lhs b/ghc/lib/glaExts/Addr.lhs
new file mode 100644
index 0000000000..a63409415f
--- /dev/null
+++ b/ghc/lib/glaExts/Addr.lhs
@@ -0,0 +1,31 @@
+%
+% (c) The AQUA Project, Glasgow University, 1994-1996
+%
+
+\section[Addr]{Module @Addr@}
+
+\begin{code}
+{-# OPTIONS -fno-implicit-prelude #-}
+
+module Addr (
+ Addr(..), -- ToDo: nullAddr,
+ ) where
+
+import GHC
+import PrelBase
+import STBase
+import CCall
+\end{code}
+
+\begin{code}
+data Addr = A# Addr# deriving (Eq, Ord) -- Glasgow extension
+
+nullAddr = ``NULL'' :: Addr
+
+instance CCallable Addr
+instance CCallable Addr#
+instance CReturnable Addr
+\end{code}
+
+
+
diff --git a/ghc/lib/glaExts/Bits.lhs b/ghc/lib/glaExts/Bits.lhs
new file mode 100644
index 0000000000..3a7a3b3949
--- /dev/null
+++ b/ghc/lib/glaExts/Bits.lhs
@@ -0,0 +1,37 @@
+%
+% (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
+%
+\section[Bits]{The @Bits@ Module}
+
+\begin{code}
+{-# OPTIONS -fno-implicit-prelude #-}
+
+module Bits where
+
+import PrelBase
+
+infixl 8 `shift`, `rotate`
+infixl 7 .&.
+infixl 6 `xor`
+infixl 5 .|.
+
+class Bits a where
+ (.&.), (.|.), xor :: a -> a -> a
+ complement :: a -> a
+ shift :: a -> Int -> a
+ rotate :: a -> Int -> a
+ bit :: Int -> a
+ setBit :: a -> Int -> a
+ clearBit :: a -> Int -> a
+ complementBit :: a -> Int -> a
+ testBit :: a -> Int -> Bool
+ bitSize :: a -> Int
+ isSigned :: a -> Bool
+
+shiftL, shiftR :: Bits a => a -> Int -> a
+rotateL, rotateR :: Bits a => a -> Int -> a
+shiftL a i = shift a i
+shiftR a i = shift a (-i)
+rotateL a i = rotate a i
+rotateR a i = rotate a (-i)
+\end{code}
diff --git a/ghc/lib/glaExts/ByteArray.lhs b/ghc/lib/glaExts/ByteArray.lhs
index f0f66b324d..d6326dc9ea 100644
--- a/ghc/lib/glaExts/ByteArray.lhs
+++ b/ghc/lib/glaExts/ByteArray.lhs
@@ -33,7 +33,8 @@ module ByteArray
import ArrBase
import Ix
-import Foreign (Addr, Word)
+import Foreign (Word)
+import Addr
\end{code}
diff --git a/ghc/lib/glaExts/CCall.lhs b/ghc/lib/glaExts/CCall.lhs
new file mode 100644
index 0000000000..6de7fbf2c8
--- /dev/null
+++ b/ghc/lib/glaExts/CCall.lhs
@@ -0,0 +1,56 @@
+%
+% (c) The AQUA Project, Glasgow University, 1994-1996
+%
+
+\section[CCall]{Module @CCall@}
+
+\begin{code}
+{-# OPTIONS -fno-implicit-prelude #-}
+
+module CCall (
+ CCallable(..), CReturnable(..),
+ Word(..)
+ ) where
+
+import PrelBase
+import GHC
+\end{code}
+
+%*********************************************************
+%* *
+\subsection{Classes @CCallable@ and @CReturnable@}
+%* *
+%*********************************************************
+
+\begin{code}
+class CCallable a
+class CReturnable a
+
+instance CCallable Char
+instance CCallable Char#
+instance CReturnable Char
+
+instance CCallable Int
+instance CCallable Int#
+instance CReturnable Int
+
+-- DsCCall knows how to pass strings...
+instance CCallable [Char]
+
+instance CCallable Float
+instance CCallable Float#
+instance CReturnable Float
+
+instance CCallable Double
+instance CCallable Double#
+instance CReturnable Double
+
+data Word = W# Word# deriving (Eq, Ord) -- Glasgow extension
+
+instance CCallable Word
+instance CCallable Word#
+instance CReturnable Word
+
+instance CReturnable () -- Why, exactly?
+\end{code}
+
diff --git a/ghc/lib/glaExts/Foreign.lhs b/ghc/lib/glaExts/Foreign.lhs
index d72e31454b..34d09908fa 100644
--- a/ghc/lib/glaExts/Foreign.lhs
+++ b/ghc/lib/glaExts/Foreign.lhs
@@ -12,93 +12,55 @@ module Foreign (
#ifndef __PARALLEL_HASKELL__
ForeignObj(..),
#endif
- Addr(..), Word(..)
+ Word(..),
+
+#ifndef __PARALLEL_HASKELL__
+ unpackCStringFO, -- :: ForeignObj -> [Char]
+ unpackNBytesFO, -- :: ForeignObj -> Int -> [Char]
+ unpackCStringFO#, -- :: ForeignObj# -> [Char]
+ unpackNBytesFO# -- :: ForeignObj# -> Int# -> [Char]
+#endif
) where
+import IOBase
import STBase
-import UnsafeST ( unsafePerformPrimIO )
+import Unsafe
import PrelBase
+import CCall
+import Addr
import GHC
\end{code}
%*********************************************************
%* *
-\subsection{Classes @CCallable@ and @CReturnable@}
-%* *
-%*********************************************************
-
-\begin{code}
-class CCallable a
-class CReturnable a
-
-instance CCallable Char
-instance CCallable Char#
-instance CReturnable Char
-
-instance CCallable Int
-instance CCallable Int#
-instance CReturnable Int
-
--- DsCCall knows how to pass strings...
-instance CCallable [Char]
-
-instance CCallable Float
-instance CCallable Float#
-instance CReturnable Float
-
-instance CCallable Double
-instance CCallable Double#
-instance CReturnable Double
-
-data Addr = A# Addr# deriving (Eq, Ord) -- Glasgow extension
-
-instance CCallable Addr
-instance CCallable Addr#
-instance CReturnable Addr
-
-data Word = W# Word# deriving (Eq, Ord) -- Glasgow extension
-
-instance CCallable Word
-instance CCallable Word#
-instance CReturnable Word
-
-instance CReturnable () -- Why, exactly?
-\end{code}
-
-
-%*********************************************************
-%* *
\subsection{Type @ForeignObj@ and its operations}
%* *
%*********************************************************
\begin{code}
#ifndef __PARALLEL_HASKELL__
---Defined in PrelBase: data ForeignObj = ForeignObj ForeignObj#
-data ForeignObj = ForeignObj ForeignObj# -- another one
-
instance CCallable ForeignObj
instance CCallable ForeignObj#
eqForeignObj :: ForeignObj -> ForeignObj -> Bool
-makeForeignObj :: Addr -> Addr -> PrimIO ForeignObj
-writeForeignObj :: ForeignObj -> Addr -> PrimIO ()
+makeForeignObj :: Addr -> Addr -> IO ForeignObj
+writeForeignObj :: ForeignObj -> Addr -> IO ()
{- derived op - attaching a free() finaliser to a malloc() allocated reference. -}
-makeMallocPtr :: Addr -> PrimIO ForeignObj
+makeMallocPtr :: Addr -> IO ForeignObj
-makeForeignObj (A# obj) (A# finaliser) = ST ( \ s# ->
+makeForeignObj (A# obj) (A# finaliser) = IO ( \ s# ->
case makeForeignObj# obj finaliser s# of
- StateAndForeignObj# s1# fo# -> STret s1# (ForeignObj fo#))
+ StateAndForeignObj# s1# fo# -> IOok s1# (ForeignObj fo#))
-writeForeignObj (ForeignObj fo#) (A# datum#) = ST ( \ s# ->
- case writeForeignObj# fo# datum# s# of { s1# -> STret s1# () } )
+writeForeignObj (ForeignObj fo#) (A# datum#) = IO ( \ s# ->
+ case writeForeignObj# fo# datum# s# of { s1# -> IOok s1# () } )
makeMallocPtr a = makeForeignObj a (``&free''::Addr)
eqForeignObj mp1 mp2
- = unsafePerformPrimIO (_ccall_ eqForeignObj mp1 mp2) /= (0::Int)
+ = unsafePerformIO (_ccall_ eqForeignObj mp1 mp2) /= (0::Int)
instance Eq ForeignObj where
p == q = eqForeignObj p q
@@ -106,7 +68,6 @@ instance Eq ForeignObj where
#endif /* !__PARALLEL_HASKELL__ */
\end{code}
-
%*********************************************************
%* *
\subsection{Type @StablePtr@ and its operations}
@@ -124,27 +85,23 @@ instance CReturnable (StablePtr a)
-- @makeStablePtr#@ since the corresponding macro is very long and we'll
-- get terrible code-bloat.
-makeStablePtr :: a -> PrimIO (StablePtr a)
-deRefStablePtr :: StablePtr a -> PrimIO a
-freeStablePtr :: StablePtr a -> PrimIO ()
-performGC :: PrimIO ()
+makeStablePtr :: a -> IO (StablePtr a)
+deRefStablePtr :: StablePtr a -> IO a
+freeStablePtr :: StablePtr a -> IO ()
{-# INLINE deRefStablePtr #-}
{-# INLINE freeStablePtr #-}
-{-# INLINE performGC #-}
-makeStablePtr f = ST $ \ rw1# ->
+makeStablePtr f = IO $ \ rw1# ->
case makeStablePtr# f rw1# of
- StateAndStablePtr# rw2# sp# -> STret rw2# (StablePtr sp#)
+ StateAndStablePtr# rw2# sp# -> IOok rw2# (StablePtr sp#)
-deRefStablePtr (StablePtr sp#) = ST $ \ rw1# ->
+deRefStablePtr (StablePtr sp#) = IO $ \ rw1# ->
case deRefStablePtr# sp# rw1# of
- StateAndPtr# rw2# a -> STret rw2# a
+ StateAndPtr# rw2# a -> IOok rw2# a
freeStablePtr sp = _ccall_ freeStablePointer sp
-performGC = _ccall_GC_ StgPerformGarbageCollection
-
#endif /* !__PARALLEL_HASKELL__ */
\end{code}
@@ -160,3 +117,46 @@ data StateAndStablePtr# s a = StateAndStablePtr# (State# s) (StablePtr# a)
#endif
data StateAndForeignObj# s = StateAndForeignObj# (State# s) ForeignObj#
\end{code}
+
+%*********************************************************
+%* *
+\subsection{Unpacking Foreigns}
+%* *
+%*********************************************************
+
+Primitives for converting Foreigns pointing to external
+sequence of bytes into a list of @Char@s (a renamed version
+of the code above).
+
+\begin{code}
+#ifndef __PARALLEL_HASKELL__
+unpackCStringFO :: ForeignObj -> [Char]
+unpackCStringFO (ForeignObj fo#) = unpackCStringFO# fo#
+
+unpackCStringFO# :: ForeignObj# -> [Char]
+unpackCStringFO# fo {- ptr. to NUL terminated string-}
+ = unpack 0#
+ where
+ unpack nh
+ | ch `eqChar#` '\0'# = []
+ | otherwise = C# ch : unpack (nh +# 1#)
+ where
+ ch = indexCharOffForeignObj# fo nh
+
+unpackNBytesFO :: ForeignObj -> Int -> [Char]
+unpackNBytesFO (ForeignObj fo) (I# l) = unpackNBytesFO# fo l
+
+unpackNBytesFO# :: ForeignObj# -> Int# -> [Char]
+ -- This one is called by the compiler to unpack literal strings with NULs in them; rare.
+unpackNBytesFO# fo len
+ = unpack 0#
+ where
+ unpack i
+ | i >=# len = []
+ | otherwise = C# ch : unpack (i +# 1#)
+ where
+ ch = indexCharOffForeignObj# fo i
+#endif
+\end{code}
+
+
diff --git a/ghc/lib/glaExts/GlaExts.lhs b/ghc/lib/glaExts/GlaExts.lhs
index eb89c9c439..525dc92a8a 100644
--- a/ghc/lib/glaExts/GlaExts.lhs
+++ b/ghc/lib/glaExts/GlaExts.lhs
@@ -14,32 +14,15 @@ GHC interfaces - instead import the GlaExts rag bag and you should be away!
module GlaExts
(
- -- From module STBase, the PrimIO monad
- -- (an instance of ST):
- PrimIO,
ST, RealWorld,
- thenPrimIO, --
- returnPrimIO,
- seqPrimIO,
- fixPrimIO,
- unsafePerformPrimIO,
- unsafeInterleavePrimIO,
+ unsafePerformIO,
+ unsafeInterleaveIO,
- -- backwards compatibility
- listPrimIO, -- :: [PrimIO a] -> PrimIO [a]
- mapPrimIO, -- :: (a -> PrimIO b) -> [a] -> PrimIO [b]
- mapAndUnzipPrimIO, -- :: (a -> PrimIO (b,c)) -> [a] -> PrimIO ([b],[c])
-
-
- -- operations for interfacing IO and ST/PrimIO
+ -- operations for interfacing IO and ST
--
stToIO, -- :: ST RealWorld a -> IO a
- primIOToIO, -- :: PrimIO a -> IO a
ioToST, -- :: IO a -> ST RealWorld a
- ioToPrimIO, -- :: IO a -> PrimIO a
- thenIO_Prim, -- :: PrimIO a -> (a -> IO b) -> IO b
- seqIO_Prim, -- :: PrimIO a -> IO b -> IO b
-- Everything from module ByteArray:
module ByteArray,
@@ -61,7 +44,7 @@ module GlaExts
import GHC
import STBase
-import UnsafeST
+import IOExts
import PrelBase
import ByteArray
import MutableArray
diff --git a/ghc/lib/glaExts/IOExts.lhs b/ghc/lib/glaExts/IOExts.lhs
new file mode 100644
index 0000000000..ed8a3c169a
--- /dev/null
+++ b/ghc/lib/glaExts/IOExts.lhs
@@ -0,0 +1,31 @@
+%
+% (c) The AQUA Project, Glasgow University, 1994-1996
+%
+
+\section[IOExts]{Module @IOExts@}
+
+\begin{code}
+{-# OPTIONS -fno-implicit-prelude #-}
+
+module IOExts
+ ( fixIO
+ , unsafePerformIO
+ , unsafeInterleaveIO
+
+ , IORef
+ -- instance Eq (MutVar a)
+ , newIORef
+ , readIORef
+ , writeIORef
+
+ , trace
+ , performGC
+ ) where
+\end{code}
+
+\begin{code}
+import IOBase
+import IORef
+import STBase
+import Unsafe
+\end{code}
diff --git a/ghc/lib/glaExts/IORef.lhs b/ghc/lib/glaExts/IORef.lhs
new file mode 100644
index 0000000000..85c6520185
--- /dev/null
+++ b/ghc/lib/glaExts/IORef.lhs
@@ -0,0 +1,34 @@
+%
+% (c) The AQUA Project, Glasgow University, 1994-1996
+%
+
+\section[IORef]{Module @IORef@}
+
+\begin{code}
+{-# OPTIONS -fno-implicit-prelude #-}
+
+module IORef (
+ IORef,
+ newIORef,
+ readIORef,
+ writeIORef
+ ) where
+
+import PrelBase
+import ArrBase
+import IOBase
+import STBase
+\end{code}
+
+\begin{code}
+newtype IORef a = IORef (MutableVar RealWorld a) deriving Eq
+
+newIORef :: a -> IO (IORef a)
+newIORef v = stToIO (newVar v) >>= \ var -> return (IORef var)
+
+readIORef :: IORef a -> IO a
+readIORef (IORef var) = stToIO (readVar var)
+
+writeIORef :: IORef a -> a -> IO ()
+writeIORef (IORef var) v = stToIO (writeVar var v)
+\end{code}
diff --git a/ghc/lib/glaExts/Int.lhs b/ghc/lib/glaExts/Int.lhs
new file mode 100644
index 0000000000..b539bae77c
--- /dev/null
+++ b/ghc/lib/glaExts/Int.lhs
@@ -0,0 +1,346 @@
+%
+% (c) The AQUA Project, Glasgow University, 1994-1996
+%
+
+\section[Int]{Module @Int@}
+
+This code is largely copied from the Hugs library of the same name.
+
+\begin{code}
+{-# OPTIONS -fno-implicit-prelude #-}
+
+-----------------------------------------------------------------------------
+-- Signed Integers
+-- Suitable for use with Hugs 1.4 on 32 bit systems.
+-----------------------------------------------------------------------------
+
+module Int
+ ( Int8
+ , Int16
+ , Int32
+ --, Int64
+ , int8ToInt -- :: Int8 -> Int
+ , intToInt8 -- :: Int -> Int8
+ , int16ToInt -- :: Int16 -> Int
+ , intToInt16 -- :: Int -> Int16
+ , int32ToInt -- :: Int32 -> Int
+ , intToInt32 -- :: Int -> Int32
+ -- plus Eq, Ord, Num, Bounded, Real, Integral, Ix, Enum, Read,
+ -- Show and Bits instances for each of Int8, Int16 and Int32
+ ) where
+
+import PrelBase
+import PrelNum
+import PrelRead
+import Ix
+import Error
+import Bits
+import GHC
+
+-----------------------------------------------------------------------------
+-- The "official" coercion functions
+-----------------------------------------------------------------------------
+
+int8ToInt :: Int8 -> Int
+intToInt8 :: Int -> Int8
+int16ToInt :: Int16 -> Int
+intToInt16 :: Int -> Int16
+int32ToInt :: Int32 -> Int
+intToInt32 :: Int -> Int32
+
+-- And some non-exported ones
+
+int8ToInt16 :: Int8 -> Int16
+int8ToInt32 :: Int8 -> Int32
+int16ToInt8 :: Int16 -> Int8
+int16ToInt32 :: Int16 -> Int32
+int32ToInt8 :: Int32 -> Int8
+int32ToInt16 :: Int32 -> Int16
+
+int8ToInt16 = I16 . int8ToInt
+int8ToInt32 = I32 . int8ToInt
+int16ToInt8 = I8 . int16ToInt
+int16ToInt32 = I32 . int16ToInt
+int32ToInt8 = I8 . int32ToInt
+int32ToInt16 = I16 . int32ToInt
+
+-----------------------------------------------------------------------------
+-- Int8
+-----------------------------------------------------------------------------
+
+newtype Int8 = I8 Int
+
+int8ToInt (I8 x) = if x' <= 0x7f then x' else x' - 0x100
+ where x' = case x of { I# x ->
+ I# (word2Int# (int2Word# x `and#` int2Word# 0xff#))
+ }
+intToInt8 = I8
+
+instance Eq Int8 where (==) = binop (==)
+instance Ord Int8 where compare = binop compare
+
+instance Num Int8 where
+ x + y = to (binop (+) x y)
+ x - y = to (binop (-) x y)
+ negate = to . negate . from
+ x * y = to (binop (*) x y)
+ abs = absReal
+ signum = signumReal
+ fromInteger = to . fromInteger
+ fromInt = to
+
+instance Bounded Int8 where
+ minBound = 0x80
+ maxBound = 0x7f
+
+instance Real Int8 where
+ toRational x = toInteger x % 1
+
+instance Integral Int8 where
+ x `div` y = to (binop div x y)
+ x `quot` y = to (binop quot x y)
+ x `rem` y = to (binop rem x y)
+ x `mod` y = to (binop mod x y)
+ x `quotRem` y = to2 (binop quotRem x y)
+ toInteger = toInteger . from
+ toInt = toInt . from
+
+instance Ix Int8 where
+ range (m,n) = [m..n]
+ index b@(m,n) i
+ | inRange b i = from (i - m)
+ | otherwise = error "index: Index out of range"
+ inRange (m,n) i = m <= i && i <= n
+
+instance Enum Int8 where
+ toEnum = to
+ fromEnum = from
+ 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
+
+instance Read Int8 where
+ readsPrec p s = [ (to x,r) | (x,r) <- readsPrec p s ]
+
+instance Show Int8 where
+ showsPrec p = showsPrec p . from
+
+binop8 :: (Int32 -> Int32 -> a) -> (Int8 -> Int8 -> a)
+binop8 op x y = int8ToInt32 x `op` int8ToInt32 y
+
+instance Bits Int8 where
+ x .&. y = int32ToInt8 (binop8 (.&.) x y)
+ x .|. y = int32ToInt8 (binop8 (.|.) x y)
+ x `xor` y = int32ToInt8 (binop8 xor x y)
+ complement = int32ToInt8 . complement . int8ToInt32
+ x `shift` i = int32ToInt8 (int8ToInt32 x `shift` i)
+-- rotate
+ bit = int32ToInt8 . bit
+ setBit x i = int32ToInt8 (setBit (int8ToInt32 x) i)
+ clearBit x i = int32ToInt8 (clearBit (int8ToInt32 x) i)
+ complementBit x i = int32ToInt8 (complementBit (int8ToInt32 x) i)
+ testBit x i = testBit (int8ToInt32 x) i
+ bitSize _ = 8
+ isSigned _ = True
+
+-----------------------------------------------------------------------------
+-- Int16
+-----------------------------------------------------------------------------
+
+newtype Int16 = I16 Int
+
+int16ToInt (I16 x) = if x' <= 0x7fff then x' else x' - 0x10000
+ where x' = case x of { I# x ->
+ I# (word2Int# (int2Word# x `and#` int2Word# 0xffff#))
+ }
+intToInt16 = I16
+
+instance Eq Int16 where (==) = binop (==)
+instance Ord Int16 where compare = binop compare
+
+instance Num Int16 where
+ x + y = to (binop (+) x y)
+ x - y = to (binop (-) x y)
+ negate = to . negate . from
+ x * y = to (binop (*) x y)
+ abs = absReal
+ signum = signumReal
+ fromInteger = to . fromInteger
+ fromInt = to
+
+instance Bounded Int16 where
+ minBound = 0x8000
+ maxBound = 0x7fff
+
+instance Real Int16 where
+ toRational x = toInteger x % 1
+
+instance Integral Int16 where
+ x `div` y = to (binop div x y)
+ x `quot` y = to (binop quot x y)
+ x `rem` y = to (binop rem x y)
+ x `mod` y = to (binop mod x y)
+ x `quotRem` y = to2 (binop quotRem x y)
+ toInteger = toInteger . from
+ toInt = toInt . from
+
+instance Ix Int16 where
+ range (m,n) = [m..n]
+ index b@(m,n) i
+ | inRange b i = from (i - m)
+ | otherwise = error "index: Index out of range"
+ inRange (m,n) i = m <= i && i <= n
+
+instance Enum Int16 where
+ toEnum = to
+ fromEnum = from
+ 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
+
+instance Read Int16 where
+ readsPrec p s = [ (to x,r) | (x,r) <- readsPrec p s ]
+
+instance Show Int16 where
+ showsPrec p = showsPrec p . from
+
+binop16 :: (Int32 -> Int32 -> a) -> (Int16 -> Int16 -> a)
+binop16 op x y = int16ToInt32 x `op` int16ToInt32 y
+
+instance Bits Int16 where
+ x .&. y = int32ToInt16 (binop16 (.&.) x y)
+ x .|. y = int32ToInt16 (binop16 (.|.) x y)
+ x `xor` y = int32ToInt16 (binop16 xor x y)
+ complement = int32ToInt16 . complement . int16ToInt32
+ x `shift` i = int32ToInt16 (int16ToInt32 x `shift` i)
+-- rotate
+ bit = int32ToInt16 . bit
+ setBit x i = int32ToInt16 (setBit (int16ToInt32 x) i)
+ clearBit x i = int32ToInt16 (clearBit (int16ToInt32 x) i)
+ complementBit x i = int32ToInt16 (complementBit (int16ToInt32 x) i)
+ testBit x i = testBit (int16ToInt32 x) i
+ bitSize _ = 16
+ isSigned _ = True
+
+-----------------------------------------------------------------------------
+-- Int32
+-----------------------------------------------------------------------------
+
+newtype Int32 = I32 Int
+
+int32ToInt (I32 x) = x
+intToInt32 = I32
+
+instance Eq Int32 where (==) = binop (==)
+instance Ord Int32 where compare = binop compare
+
+instance Num Int32 where
+ x + y = to (binop (+) x y)
+ x - y = to (binop (-) x y)
+ negate = to . negate . from
+ x * y = to (binop (*) x y)
+ abs = absReal
+ signum = signumReal
+ fromInteger = to . fromInteger
+ fromInt = to
+
+instance Bounded Int32 where
+ minBound = to minBound
+ maxBound = to maxBound
+
+instance Real Int32 where
+ toRational x = toInteger x % 1
+
+instance Integral Int32 where
+ x `div` y = to (binop div x y)
+ x `quot` y = to (binop quot x y)
+ x `rem` y = to (binop rem x y)
+ x `mod` y = to (binop mod x y)
+ x `quotRem` y = to2 (binop quotRem x y)
+ toInteger = toInteger . from
+ toInt = toInt . from
+
+instance Ix Int32 where
+ range (m,n) = [m..n]
+ index b@(m,n) i
+ | inRange b i = from (i - m)
+ | otherwise = error "index: Index out of range"
+ inRange (m,n) i = m <= i && i <= n
+
+instance Enum Int32 where
+ toEnum = to
+ fromEnum = from
+ 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
+
+instance Read Int32 where
+ readsPrec p s = [ (to x,r) | (x,r) <- readsPrec p s ]
+
+instance Show Int32 where
+ showsPrec p = showsPrec p . from
+
+instance Bits Int32 where
+ x .&. y = to (binop (wordop and#) x y)
+ x .|. y = to (binop (wordop or# ) x y)
+ x `xor` y = to (binop (wordop xor#) x y)
+ complement x = (x `xor` maxBound) + 1
+ shift (I32 (I# x)) i@(I# i#)
+ | i > 0 = I32 (I# (iShiftRL# x i#))
+ | otherwise = I32 (I# (iShiftL# x i#))
+-- rotate
+ bit i = 1 `shift` -i
+ setBit x i = x .|. bit i
+ clearBit x i = x .&. complement (bit i)
+ complementBit x i = x `xor` bit i
+ testBit x i = (x .&. bit i) /= 0
+ bitSize _ = 32
+ isSigned _ = True
+
+{-# INLINE wordop #-}
+wordop op (I# x) (I# y) = I# (word2Int# (int2Word# x `op` int2Word# y))
+
+-----------------------------------------------------------------------------
+-- End of exported definitions
+--
+-- The remainder of this file consists of definitions which are only
+-- used in the implementation.
+-----------------------------------------------------------------------------
+
+-----------------------------------------------------------------------------
+-- Coercions - used to make the instance declarations more uniform
+-----------------------------------------------------------------------------
+
+class Coerce a where
+ to :: Int -> a
+ from :: a -> Int
+
+instance Coerce Int32 where
+ from = int32ToInt
+ to = intToInt32
+
+instance Coerce Int8 where
+ from = int8ToInt
+ to = intToInt8
+
+instance Coerce Int16 where
+ from = int16ToInt
+ to = intToInt16
+
+binop :: Coerce int => (Int -> Int -> a) -> (int -> int -> a)
+binop op x y = from x `op` from y
+
+to2 :: Coerce int => (Int, Int) -> (int, int)
+to2 (x,y) = (to x, to y)
+
+-----------------------------------------------------------------------------
+-- Code copied from the Prelude
+-----------------------------------------------------------------------------
+
+absReal x | x >= 0 = x
+ | otherwise = -x
+
+signumReal x | x == 0 = 0
+ | x > 0 = 1
+ | otherwise = -1
+\end{code}
diff --git a/ghc/lib/glaExts/LazyST.lhs b/ghc/lib/glaExts/LazyST.lhs
new file mode 100644
index 0000000000..d6fb8f6648
--- /dev/null
+++ b/ghc/lib/glaExts/LazyST.lhs
@@ -0,0 +1,104 @@
+%
+% (c) The GRASP/AQUA Project, Glasgow University, 1992-1997
+%
+
+\section[LazyST]{The Lazy State Transformer Monad, @LazyST@}
+
+This module presents an identical interface to ST, but the underlying
+implementation of the state thread is lazy.
+
+\begin{code}
+module LazyST (
+
+ STBase.ST,
+
+ unsafeInterleaveST,
+
+ -- ST is one, so you'll likely need some Monad bits
+ module Monad,
+
+ ST.STRef,
+ newSTRef, readSTRef, writeSTRef,
+
+ ST.STArray,
+ newSTArray, readSTArray, writeSTArray, Ix,
+
+ strictToLazyST, lazyToStrictST
+ ) where
+
+import qualified ST
+import qualified STBase
+import ArrBase
+import Unsafe ( unsafeInterleaveST )
+import PrelBase ( Eq(..), Int, Bool, ($), ()(..) )
+import Monad
+import Ix
+
+newtype ST s a = ST (STBase.State s -> (a,STBase.State s))
+
+instance Monad (ST s) where
+
+ return a = ST $ \ s -> (a,s)
+ m >> k = m >>= \ _ -> k
+
+ (ST m) >>= k
+ = ST $ \ s ->
+ let
+ (r,new_s) = m s
+ ST k_a = k r
+ in
+ k_a new_s
+\end{code}
+
+%*********************************************************
+%* *
+\subsection{Variables}
+%* *
+%*********************************************************
+
+\begin{code}
+newSTRef :: a -> ST s (ST.STRef s a)
+readSTRef :: ST.STRef s a -> ST s a
+writeSTRef :: ST.STRef s a -> a -> ST s ()
+
+newSTRef = strictToLazyST . ST.newSTRef
+readSTRef = strictToLazyST . ST.readSTRef
+writeSTRef r a = strictToLazyST (ST.writeSTRef r a)
+\end{code}
+
+%*********************************************************
+%* *
+\subsection{Arrays}
+%* *
+%*********************************************************
+
+\begin{code}
+type STArray s ix elt = MutableArray s ix elt
+
+newSTArray :: Ix ix => (ix,ix) -> elt -> ST s (STArray s ix elt)
+readSTArray :: Ix ix => STArray s ix elt -> ix -> ST s elt
+writeSTArray :: Ix ix => STArray s ix elt -> ix -> elt -> ST s ()
+boundsSTArray :: Ix ix => STArray s ix elt -> (ix, ix)
+thawSTArray :: Ix ix => Array ix elt -> ST s (STArray s ix elt)
+freezeSTArray :: Ix ix => STArray s ix elt -> ST s (Array ix elt)
+unsafeFreezeSTArray :: Ix ix => STArray s ix elt -> ST s (Array ix elt)
+
+newSTArray ixs init = strictToLazyST (newArray ixs init)
+readSTArray arr ix = strictToLazyST (readArray arr ix)
+writeSTArray arr ix v = strictToLazyST (writeArray arr ix v)
+boundsSTArray = boundsOfArray
+thawSTArray = strictToLazyST . thawArray
+freezeSTArray = strictToLazyST . freezeArray
+unsafeFreezeSTArray = strictToLazyST . unsafeFreezeArray
+
+strictToLazyST :: STBase.ST s a -> ST s a
+strictToLazyST (STBase.ST m) = ST $ \s ->
+ let STBase.S# s# = s in
+ case m s# of { STBase.STret s2# r -> (r, STBase.S# s2#) }
+
+lazyToStrictST :: ST s a -> STBase.ST s a
+lazyToStrictST (ST m) = STBase.ST $ \s ->
+ case (m (STBase.S# s)) of (a, STBase.S# s') -> STBase.STret s' a
+
+
+\end{code}
diff --git a/ghc/lib/glaExts/MutVar.lhs b/ghc/lib/glaExts/MutVar.lhs
deleted file mode 100644
index c0a0f2aed4..0000000000
--- a/ghc/lib/glaExts/MutVar.lhs
+++ /dev/null
@@ -1,44 +0,0 @@
-%
-% (c) The AQUA Project, Glasgow University, 1994-1996
-%
-\section[MutVar]{Mutable variables}
-
-Mutable variables, for the @IO@ monad.
-
-\begin{code}
-module MutVar
-
- (
- MutVar, -- abstract
-
- newVar, -- :: a -> IO (MutVar a)
- readVar, -- :: MutVar a -> IO a
- writeVar, -- :: MutVar a -> a -> IO ()
- sameVar -- :: MutVar a -> MutVar a -> Bool
-
- ) where
-
-import qualified ST
-import qualified ArrBase
-import IOBase ( IO , stToIO )
-import GHC (RealWorld)
-
-\end{code}
-
-\begin{code}
-
-newtype MutVar a = MutVar (ArrBase.MutableVar RealWorld a)
-
-newVar :: a -> IO (MutVar a)
-newVar v = stToIO (ST.newVar v) >>= \ var -> return (MutVar var)
-
-readVar :: MutVar a -> IO a
-readVar (MutVar var) = stToIO (ST.readVar var)
-
-writeVar :: MutVar a -> a -> IO ()
-writeVar (MutVar var) v = stToIO (ST.writeVar var v)
-
-sameVar :: MutVar a -> MutVar a -> Bool
-sameVar (MutVar var1) (MutVar var2) = ST.sameVar var1 var2
-
-\end{code}
diff --git a/ghc/lib/glaExts/ST.lhs b/ghc/lib/glaExts/ST.lhs
index d25dc83dfb..3e5220fd07 100644
--- a/ghc/lib/glaExts/ST.lhs
+++ b/ghc/lib/glaExts/ST.lhs
@@ -8,35 +8,27 @@
module ST (
- -- ToDo: review this interface; I'm avoiding gratuitous changes for now
- -- SLPJ Jan 97
-
-
ST,
+ unsafeInterleaveST,
+
-- ST is one, so you'll likely need some Monad bits
module Monad,
- thenST, seqST, returnST, listST, fixST, runST, unsafeInterleaveST,
- mapST, mapAndUnzipST,
- -- the lazy variant
- -- returnLazyST, thenLazyST, seqLazyST,
+ STRef,
+ newSTRef, readSTRef, writeSTRef,
- MutableVar,
- newVar, readVar, writeVar, sameVar,
-
- MutableArray,
- newArray, readArray, writeArray, sameMutableArray
+ STArray,
+ newSTArray, readSTArray, writeSTArray, Ix
) where
-import IOBase ( error ) -- [Source not needed]
import ArrBase
+import Unsafe ( unsafeInterleaveST )
import STBase
-import UnsafeST ( unsafeInterleaveST )
-import PrelBase ( Int, Bool, ($), ()(..) )
-import GHC ( newArray#, readArray#, writeArray#, sameMutableArray#, sameMutableByteArray# )
+import PrelBase ( Eq(..), Int, Bool, ($), ()(..) )
import Monad
+import Ix
\end{code}
@@ -47,39 +39,41 @@ import Monad
%*********************************************************
\begin{code}
--- in ArrBase: type MutableVar s a = MutableArray s Int a
-
-newVar :: a -> ST s (MutableVar s a)
-readVar :: MutableVar s a -> ST s a
-writeVar :: MutableVar s a -> a -> ST s ()
-sameVar :: MutableVar s a -> MutableVar s a -> Bool
-
-newVar init = ST $ \ s# ->
- case (newArray# 1# init s#) of { StateAndMutableArray# s2# arr# ->
- STret s2# (MutableArray vAR_IXS arr#) }
- where
- vAR_IXS = error "newVar: Shouldn't access `bounds' of a MutableVar\n"
+newtype STRef s a = STRef (MutableVar s a) deriving Eq
-readVar (MutableArray _ var#) = ST $ \ s# ->
- case readArray# var# 0# s# of { StateAndPtr# s2# r ->
- STret s2# r }
+newSTRef :: a -> ST s (STRef s a)
+newSTRef v = newVar v >>= \ var -> return (STRef var)
-writeVar (MutableArray _ var#) val = ST $ \ s# ->
- case writeArray# var# 0# val s# of { s2# ->
- STret s2# () }
+readSTRef :: STRef s a -> ST s a
+readSTRef (STRef var) = readVar var
-sameVar (MutableArray _ var1#) (MutableArray _ var2#)
- = sameMutableArray# var1# var2#
+writeSTRef :: STRef s a -> a -> ST s ()
+writeSTRef (STRef var) v = writeVar var v
\end{code}
+%*********************************************************
+%* *
+\subsection{Arrays}
+%* *
+%*********************************************************
\begin{code}
-sameMutableArray :: MutableArray s ix elt -> MutableArray s ix elt -> Bool
-sameMutableByteArray :: MutableByteArray s ix -> MutableByteArray s ix -> Bool
-
-sameMutableArray (MutableArray _ arr1#) (MutableArray _ arr2#)
- = sameMutableArray# arr1# arr2#
-
-sameMutableByteArray (MutableByteArray _ arr1#) (MutableByteArray _ arr2#)
- = sameMutableByteArray# arr1# arr2#
+type STArray s ix elt = MutableArray s ix elt
+
+newSTArray :: Ix ix => (ix,ix) -> elt -> ST s (STArray s ix elt)
+writeSTArray :: Ix ix => STArray s ix elt -> ix -> elt -> ST s ()
+readSTArray :: Ix ix => STArray s ix elt -> ix -> ST s elt
+boundsSTArray :: Ix ix => STArray s ix elt -> (ix, ix)
+thawSTArray :: Ix ix => Array ix elt -> ST s (STArray s ix elt)
+freezeSTArray :: Ix ix => STArray s ix elt -> ST s (Array ix elt)
+unsafeFreezeSTArray :: Ix ix => STArray s ix elt -> ST s (Array ix elt)
+
+newSTArray = newArray
+boundsSTArray = boundsOfArray
+readSTArray = readArray
+writeSTArray = writeArray
+thawSTArray = thawArray
+freezeSTArray = freezeArray
+unsafeFreezeSTArray = unsafeFreezeArray
\end{code}
+
diff --git a/ghc/lib/glaExts/Word.lhs b/ghc/lib/glaExts/Word.lhs
new file mode 100644
index 0000000000..98cef49466
--- /dev/null
+++ b/ghc/lib/glaExts/Word.lhs
@@ -0,0 +1,354 @@
+%
+% (c) The AQUA Project, Glasgow University, 1994-1996
+%
+
+\section[Word]{Module @Word@}
+
+This code is largely copied from the Hugs library of the same name.
+
+\begin{code}
+{-# OPTIONS -fno-implicit-prelude #-}
+
+module Word
+ ( Word8
+ , Word16
+ , Word32
+ , Word64
+ , word8ToWord32 -- :: Word8 -> Word32
+ , word32ToWord8 -- :: Word32 -> Word8
+ , word16ToWord32 -- :: Word16 -> Word32
+ , word32ToWord16 -- :: Word32 -> Word16
+ , word8ToInt -- :: Word8 -> Int
+ , intToWord8 -- :: Int -> Word8
+ , word16ToInt -- :: Word16 -> Int
+ , intToWord16 -- :: Int -> Word16
+ , word32ToInt -- :: Word32 -> Int
+ , intToWord32 -- :: Int -> Word32
+ ) where
+
+import PrelBase
+import PrelNum
+import PrelRead
+import Ix
+import Error
+import Bits
+import GHC
+
+-----------------------------------------------------------------------------
+-- The "official" coercion functions
+-----------------------------------------------------------------------------
+
+word8ToWord32 :: Word8 -> Word32
+word32ToWord8 :: Word32 -> Word8
+word16ToWord32 :: Word16 -> Word32
+word32ToWord16 :: Word32 -> Word16
+
+word8ToInt :: Word8 -> Int
+intToWord8 :: Int -> Word8
+word16ToInt :: Word16 -> Int
+intToWord16 :: Int -> Word16
+
+word8ToInt = word32ToInt . word8ToWord32
+intToWord8 = word32ToWord8 . intToWord32
+word16ToInt = word32ToInt . word16ToWord32
+intToWord16 = word32ToWord16 . intToWord32
+
+intToWord32 (I# x) = W32# (int2Word# x)
+word32ToInt (W32# x) = I# (word2Int# x)
+
+-----------------------------------------------------------------------------
+-- Word8
+-----------------------------------------------------------------------------
+
+newtype Word8 = W8 Word32
+
+word8ToWord32 (W8 x) = x .&. 0xff
+word32ToWord8 = W8
+
+instance Eq Word8 where (==) = binop (==)
+instance Ord Word8 where compare = binop compare
+
+instance Num Word8 where
+ x + y = to (binop (+) x y)
+ x - y = to (binop (-) x y)
+ negate = to . negate . from
+ x * y = to (binop (*) x y)
+ abs = absReal
+ signum = signumReal
+ fromInteger = to . integer2Word
+ fromInt = intToWord8
+
+instance Bounded Word8 where
+ minBound = 0
+ maxBound = 0xff
+
+instance Real Word8 where
+ toRational x = toInteger x % 1
+
+instance Integral Word8 where
+ x `div` y = to (binop div x y)
+ x `quot` y = to (binop quot x y)
+ x `rem` y = to (binop rem x y)
+ x `mod` y = to (binop mod x y)
+ x `quotRem` y = to2 (binop quotRem x y)
+ divMod = quotRem
+ toInteger = toInteger . from
+ toInt = word8ToInt
+
+instance Ix Word8 where
+ range (m,n) = [m..n]
+ index b@(m,n) i
+ | inRange b i = word32ToInt (from (i - m))
+ | otherwise = error "index: Index out of range"
+ inRange (m,n) i = m <= i && i <= n
+
+instance Enum Word8 where
+ toEnum = to . intToWord32
+ fromEnum = word32ToInt . from
+ 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
+
+instance Read Word8 where
+ readsPrec p = readDec
+
+instance Show Word8 where
+ showsPrec p = showsPrec p . from
+
+instance Bits Word8 where
+ x .&. y = to (binop (.&.) x y)
+ x .|. y = to (binop (.|.) x y)
+ x `xor` y = to (binop xor x y)
+ complement = to . complement . from
+ x `shift` i = to (from x `shift` i)
+-- rotate
+ bit = to . bit
+ setBit x i = to (setBit (from x) i)
+ clearBit x i = to (clearBit (from x) i)
+ complementBit x i = to (complementBit (from x) i)
+ testBit x i = testBit (from x) i
+ bitSize _ = 8
+ isSigned _ = False
+
+-----------------------------------------------------------------------------
+-- Word16
+-----------------------------------------------------------------------------
+
+newtype Word16 = W16 Word32
+
+word16ToWord32 (W16 x) = x .&. 0xffff
+word32ToWord16 = W16
+
+instance Eq Word16 where (==) = binop (==)
+instance Ord Word16 where compare = binop compare
+
+instance Num Word16 where
+ x + y = to (binop (+) x y)
+ x - y = to (binop (-) x y)
+ negate = to . negate . from
+ x * y = to (binop (*) x y)
+ abs = absReal
+ signum = signumReal
+ fromInteger = to . integer2Word
+ fromInt = intToWord16
+
+instance Bounded Word16 where
+ minBound = 0
+ maxBound = 0xffff
+
+instance Real Word16 where
+ toRational x = toInteger x % 1
+
+instance Integral Word16 where
+ x `div` y = to (binop div x y)
+ x `quot` y = to (binop quot x y)
+ x `rem` y = to (binop rem x y)
+ x `mod` y = to (binop mod x y)
+ x `quotRem` y = to2 (binop quotRem x y)
+ divMod = quotRem
+ toInteger = toInteger . from
+ toInt = word16ToInt
+
+instance Ix Word16 where
+ range (m,n) = [m..n]
+ index b@(m,n) i
+ | inRange b i = word32ToInt (from (i - m))
+ | otherwise = error "index: Index out of range"
+ inRange (m,n) i = m <= i && i <= n
+
+instance Enum Word16 where
+ toEnum = to . intToWord32
+ fromEnum = word32ToInt . from
+ 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
+
+instance Read Word16 where
+ readsPrec p = readDec
+
+instance Show Word16 where
+ showsPrec p x = showsPrec p (from x)
+
+instance Bits Word16 where
+ x .&. y = to (binop (.&.) x y)
+ x .|. y = to (binop (.|.) x y)
+ x `xor` y = to (binop xor x y)
+ complement = to . complement . from
+ x `shift` i = to (from x `shift` i)
+-- rotate
+ bit = to . bit
+ setBit x i = to (setBit (from x) i)
+ clearBit x i = to (clearBit (from x) i)
+ complementBit x i = to (complementBit (from x) i)
+ testBit x i = testBit (from x) i
+ bitSize _ = 16
+ isSigned _ = False
+
+-----------------------------------------------------------------------------
+-- Word32
+-----------------------------------------------------------------------------
+
+data Word32 = W32# Word# deriving (Eq, Ord)
+
+instance Num Word32 where
+ (+) = intop (+)
+ (-) = intop (-)
+ (*) = intop (*)
+ negate (W32# x) = W32# (int2Word# (negateInt# (word2Int# x)))
+ abs = absReal
+ signum = signumReal
+ fromInteger = integer2Word
+ fromInt (I# x) = W32# (int2Word# x)
+
+{-# INLINE intop #-}
+intop op x y = intToWord32 (word32ToInt x `op` word32ToInt y)
+
+instance Bounded Word32 where
+ minBound = 0
+ maxBound = 0xffffffff
+
+instance Real Word32 where
+ toRational x = toInteger x % 1
+
+instance Integral Word32 where
+ x `div` y = if x > 0 && y < 0 then quotWord (x-y-1) y
+ else if x < 0 && y > 0 then quotWord (x-y+1) y
+ else quotWord x y
+ quot = quotWord
+ rem = remWord
+ x `mod` y = if x > 0 && y < 0 || x < 0 && y > 0 then
+ if r/=0 then r+y else 0
+ else
+ r
+ where r = remWord x y
+ a `quotRem` b = (a `quot` b, a `rem` b)
+ divMod x y = (x `div` y, x `mod` y)
+ toInteger (W32# x) = int2Integer# (word2Int# x)
+ toInt (W32# x) = I# (word2Int# x)
+
+{-# INLINE quotWord #-}
+{-# INLINE remWord #-}
+(W32# x) `quotWord` (W32# y) =
+ W32# (int2Word# (word2Int# x `quotInt#` word2Int# y))
+(W32# x) `remWord` (W32# y) =
+ W32# (int2Word# (word2Int# x `remInt#` word2Int# y))
+
+instance Ix Word32 where
+ range (m,n) = [m..n]
+ index b@(m,n) i
+ | inRange b i = word32ToInt (i - m)
+ | otherwise = error "index: Index out of range"
+ inRange (m,n) i = m <= i && i <= n
+
+instance Enum Word32 where
+ toEnum = intToWord32
+ fromEnum = word32ToInt
+ enumFrom c = map toEnum [fromEnum c .. fromEnum (maxBound::Word32)]
+ enumFromThen c d = map toEnum [fromEnum c, fromEnum d .. fromEnum (last::Word32)]
+ where last = if d < c then minBound else maxBound
+
+instance Read Word32 where
+ readsPrec p = readDec
+
+instance Show Word32 where
+ showsPrec p x = showsPrec p (word32ToInt x)
+
+instance Bits Word32 where
+ (.&.) = wordop and#
+ (.|.) = wordop or#
+ xor = wordop xor#
+ complement x = (x `xor` maxBound) + 1
+ shift (W32# x) i@(I# i#)
+ | i > 0 = W32# (shiftL# x i#)
+ | otherwise = W32# (shiftRL# x (negateInt# i#))
+ --rotate
+ bit i = 1 `shift` -i
+ setBit x i = x .|. bit i
+ clearBit x i = x .&. complement (bit i)
+ complementBit x i = x `xor` bit i
+ testBit x i = (x .&. bit i) /= 0
+ bitSize _ = 32
+ isSigned _ = False
+
+{-# INLINE wordop #-}
+wordop op (W32# x) (W32# y) = W32# (x `op` y)
+
+-----------------------------------------------------------------------------
+-- Word64
+-----------------------------------------------------------------------------
+
+data Word64 = W64 {lo,hi::Word32} deriving (Eq, Ord, Bounded)
+
+w64ToInteger W64{lo,hi} = toInteger lo + 0x100000000 * toInteger hi
+integerToW64 x = case x `quotRem` 0x100000000 of
+ (h,l) -> W64{lo=fromInteger l, hi=fromInteger h}
+
+instance Show Word64 where
+ showsPrec p x = showsPrec p (w64ToInteger x)
+
+instance Read Word64 where
+ readsPrec p s = [ (integerToW64 x,r) | (x,r) <- readDec s ]
+
+-----------------------------------------------------------------------------
+-- End of exported definitions
+--
+-- The remainder of this file consists of definitions which are only
+-- used in the implementation.
+-----------------------------------------------------------------------------
+
+-----------------------------------------------------------------------------
+-- Coercions - used to make the instance declarations more uniform
+-----------------------------------------------------------------------------
+
+class Coerce a where
+ to :: Word32 -> a
+ from :: a -> Word32
+
+instance Coerce Word8 where
+ from = word8ToWord32
+ to = word32ToWord8
+
+instance Coerce Word16 where
+ from = word16ToWord32
+ to = word32ToWord16
+
+binop :: Coerce word => (Word32 -> Word32 -> a) -> (word -> word -> a)
+binop op x y = from x `op` from y
+
+to2 :: Coerce word => (Word32, Word32) -> (word, word)
+to2 (x,y) = (to x, to y)
+
+integer2Word (J# a# s# d#) = W32# (int2Word# (integer2Int# a# s# d#))
+
+-----------------------------------------------------------------------------
+-- Code copied from the Prelude
+-----------------------------------------------------------------------------
+
+absReal x | x >= 0 = x
+ | otherwise = -x
+
+signumReal x | x == 0 = 0
+ | x > 0 = 1
+ | otherwise = -1
+
+\end{code}