[project @ 2004-06-15 10:20:05 by malcolm]
[ghc-base.git] / Foreign / C / Types.hs
index 944cf6d..0eb64d0 100644 (file)
@@ -9,50 +9,49 @@
 -- Stability   :  provisional
 -- Portability :  portable
 --
--- Mapping of C types to corresponding Haskell types. A cool hack...
+-- Mapping of C types to corresponding Haskell types.
 --
 -----------------------------------------------------------------------------
 
 module Foreign.C.Types
+#ifndef __NHC__
        ( -- Integral types, instances of: Eq, Ord, Num, Read, Show, Enum,
          -- Typeable, Storable, Bounded, Real, Integral, Bits
-         CChar(..),  CSChar(..),  CUChar(..)
-       , CShort(..), CUShort(..), CInt(..),   CUInt(..)
-       , CLong(..),  CULong(..)
-       , CPtrdiff(..), CSize(..), CWchar(..), CSigAtomic(..)
-        , CLLong(..), CULLong(..)
+         CChar,  CSChar,  CUChar
+       , CShort, CUShort, CInt,   CUInt
+       , CLong,  CULong
+       , CPtrdiff, CSize, CWchar, CSigAtomic
+        , CLLong, CULLong
          -- Numeric types, instances of: Eq, Ord, Num, Read, Show, Enum,
          -- Typeable, Storable
-       , CClock(..),   CTime(..)
+       , CClock,   CTime
 
          -- Floating types, instances of: Eq, Ord, Num, Read, Show, Enum,
          -- Typeable, Storable, Real, Fractional, Floating, RealFrac,
          -- RealFloat 
-       , CFloat(..),  CDouble(..), CLDouble(..)
+       , CFloat,  CDouble, CLDouble
+#else
+       ( -- Exported non-abstractly in nhc98 to fix an interface file problem.
+         CChar(..),    CSChar(..),  CUChar(..)
+       , CShort(..),   CUShort(..), CInt(..),   CUInt(..)
+       , CLong(..),    CULong(..)
+       , CPtrdiff(..), CSize(..),   CWchar(..), CSigAtomic(..)
+        , CLLong(..),   CULLong(..)
+       , CClock(..),   CTime(..)
+       , CFloat(..),   CDouble(..), CLDouble(..)
+#endif
 
           -- Instances of: Eq and Storable
        , CFile,        CFpos,     CJmpBuf
        ) where
 
-#ifdef __NHC__
-import NHC.FFI
-  ( CChar(..),  CSChar(..),  CUChar(..)
-  , CShort(..), CUShort(..), CInt(..),   CUInt(..)
-  , CLong(..),  CULong(..), CLLong(..), CULLong(..)
-  , CPtrdiff(..), CSize(..), CWchar(..), CSigAtomic(..)
-  , CClock(..),   CTime(..)
-  , CFloat(..),  CDouble(..), CLDouble(..)
-  , CFile,        CFpos,     CJmpBuf
-  , Storable(..)
-  )
-#else
+#ifndef __NHC__
 
-import Foreign.C.TypesISO
 import Foreign.Storable
 import Data.Bits       ( Bits(..) )
 import Data.Int                ( Int8,  Int16,  Int32,  Int64  )
 import Data.Word       ( Word8, Word16, Word32, Word64 )
-import Data.Dynamic
+import Data.Typeable
 
 #ifdef __GLASGOW_HASKELL__
 import GHC.Base
@@ -67,7 +66,7 @@ import Control.Monad
 import Foreign.Ptr
 #endif
 
-#include "Dynamic.h"
+#include "Typeable.h"
 #include "CTypes.h"
 
 INTEGRAL_TYPE(CChar,tyConCChar,"CChar",HTYPE_CHAR)
@@ -117,4 +116,89 @@ FLOATING_TYPE(CDouble,tyConCDouble,"CDouble",HTYPE_DOUBLE)
 -- HACK: Currently no long double in the FFI, so we simply re-use double
 FLOATING_TYPE(CLDouble,tyConCLDouble,"CLDouble",HTYPE_DOUBLE)
 
+{-# RULES
+"realToFrac/a->CFloat"    realToFrac = \x -> CFloat   (realToFrac x)
+"realToFrac/a->CDouble"   realToFrac = \x -> CDouble  (realToFrac x)
+"realToFrac/a->CLDouble"  realToFrac = \x -> CLDouble (realToFrac x)
+
+"realToFrac/CFloat->a"    realToFrac = \(CFloat   x) -> realToFrac x
+"realToFrac/CDouble->a"   realToFrac = \(CDouble  x) -> realToFrac x
+"realToFrac/CLDouble->a"  realToFrac = \(CLDouble x) -> realToFrac x
+ #-}
+
+INTEGRAL_TYPE(CPtrdiff,tyConCPtrdiff,"CPtrdiff",HTYPE_PTRDIFF_T)
+INTEGRAL_TYPE(CSize,tyConCSize,"CSize",HTYPE_SIZE_T)
+INTEGRAL_TYPE(CWchar,tyConCWchar,"CWchar",HTYPE_WCHAR_T)
+INTEGRAL_TYPE(CSigAtomic,tyConCSigAtomic,"CSigAtomic",HTYPE_SIG_ATOMIC_T)
+
+{-# RULES
+"fromIntegral/a->CPtrdiff"   fromIntegral = \x -> CPtrdiff   (fromIntegral x)
+"fromIntegral/a->CSize"      fromIntegral = \x -> CSize      (fromIntegral x)
+"fromIntegral/a->CWchar"     fromIntegral = \x -> CWchar     (fromIntegral x)
+"fromIntegral/a->CSigAtomic" fromIntegral = \x -> CSigAtomic (fromIntegral x)
+
+"fromIntegral/CPtrdiff->a"   fromIntegral = \(CPtrdiff   x) -> fromIntegral x
+"fromIntegral/CSize->a"      fromIntegral = \(CSize      x) -> fromIntegral x
+"fromIntegral/CWchar->a"     fromIntegral = \(CWchar     x) -> fromIntegral x
+"fromIntegral/CSigAtomic->a" fromIntegral = \(CSigAtomic x) -> fromIntegral x
+ #-}
+
+ARITHMETIC_TYPE(CClock,tyConCClock,"CClock",HTYPE_CLOCK_T)
+ARITHMETIC_TYPE(CTime,tyConCTime,"CTime",HTYPE_TIME_T)
+
+-- FIXME: Implement and provide instances for Eq and Storable
+data CFile = CFile
+data CFpos = CFpos
+data CJmpBuf = CJmpBuf
+
+-- C99 types which are still missing include:
+-- intptr_t, uintptr_t, intmax_t, uintmax_t, wint_t, wctrans_t, wctype_t
+
+#else  /* __NHC__ */
+
+import NHC.FFI
+  ( CChar(..),    CSChar(..),  CUChar(..)
+  , CShort(..),   CUShort(..), CInt(..),   CUInt(..)
+  , CLong(..),    CULong(..),  CLLong(..), CULLong(..)
+  , CPtrdiff(..), CSize(..),   CWchar(..), CSigAtomic(..)
+  , CClock(..),   CTime(..)
+  , CFloat(..),   CDouble(..), CLDouble(..)
+  , CFile,        CFpos,       CJmpBuf
+  , Storable(..)
+  )
+import Data.Bits
+import NHC.SizedTypes
+
+#define INSTANCE_BITS(T) \
+instance Bits T where { \
+  (T x) .&.     (T y)   = T (x .&.   y) ; \
+  (T x) .|.     (T y)   = T (x .|.   y) ; \
+  (T x) `xor`   (T y)   = T (x `xor` y) ; \
+  complement    (T x)   = T (complement x) ; \
+  shift         (T x) n = T (shift x n) ; \
+  rotate        (T x) n = T (rotate x n) ; \
+  bit                 n = T (bit n) ; \
+  setBit        (T x) n = T (setBit x n) ; \
+  clearBit      (T x) n = T (clearBit x n) ; \
+  complementBit (T x) n = T (complementBit x n) ; \
+  testBit       (T x) n = testBit x n ; \
+  bitSize       (T x)   = bitSize x ; \
+  isSigned      (T x)   = isSigned x }
+
+INSTANCE_BITS(CChar)
+INSTANCE_BITS(CSChar)
+INSTANCE_BITS(CUChar)
+INSTANCE_BITS(CShort)
+INSTANCE_BITS(CUShort)
+INSTANCE_BITS(CInt)
+INSTANCE_BITS(CUInt)
+INSTANCE_BITS(CLong)
+INSTANCE_BITS(CULong)
+INSTANCE_BITS(CLLong)
+INSTANCE_BITS(CULLong)
+INSTANCE_BITS(CPtrdiff)
+INSTANCE_BITS(CWchar)
+INSTANCE_BITS(CSigAtomic)
+INSTANCE_BITS(CSize)
+
 #endif