[project @ 2004-06-15 10:20:05 by malcolm]
[ghc-base.git] / Foreign / C / Types.hs
1 {-# OPTIONS -fno-implicit-prelude #-}
2 -----------------------------------------------------------------------------
3 -- |
4 -- Module      :  Foreign.C.Types
5 -- Copyright   :  (c) The FFI task force 2001
6 -- License     :  BSD-style (see the file libraries/base/LICENSE)
7 -- 
8 -- Maintainer  :  ffi@haskell.org
9 -- Stability   :  provisional
10 -- Portability :  portable
11 --
12 -- Mapping of C types to corresponding Haskell types.
13 --
14 -----------------------------------------------------------------------------
15
16 module Foreign.C.Types
17 #ifndef __NHC__
18         ( -- Integral types, instances of: Eq, Ord, Num, Read, Show, Enum,
19           -- Typeable, Storable, Bounded, Real, Integral, Bits
20           CChar,  CSChar,  CUChar
21         , CShort, CUShort, CInt,   CUInt
22         , CLong,  CULong
23         , CPtrdiff, CSize, CWchar, CSigAtomic
24         , CLLong, CULLong
25           -- Numeric types, instances of: Eq, Ord, Num, Read, Show, Enum,
26           -- Typeable, Storable
27         , CClock,   CTime
28
29           -- Floating types, instances of: Eq, Ord, Num, Read, Show, Enum,
30           -- Typeable, Storable, Real, Fractional, Floating, RealFrac,
31           -- RealFloat 
32         , CFloat,  CDouble, CLDouble
33 #else
34         ( -- Exported non-abstractly in nhc98 to fix an interface file problem.
35           CChar(..),    CSChar(..),  CUChar(..)
36         , CShort(..),   CUShort(..), CInt(..),   CUInt(..)
37         , CLong(..),    CULong(..)
38         , CPtrdiff(..), CSize(..),   CWchar(..), CSigAtomic(..)
39         , CLLong(..),   CULLong(..)
40         , CClock(..),   CTime(..)
41         , CFloat(..),   CDouble(..), CLDouble(..)
42 #endif
43
44           -- Instances of: Eq and Storable
45         , CFile,        CFpos,     CJmpBuf
46         ) where
47
48 #ifndef __NHC__
49
50 import Foreign.Storable
51 import Data.Bits        ( Bits(..) )
52 import Data.Int         ( Int8,  Int16,  Int32,  Int64  )
53 import Data.Word        ( Word8, Word16, Word32, Word64 )
54 import Data.Typeable
55
56 #ifdef __GLASGOW_HASKELL__
57 import GHC.Base
58 import GHC.Float
59 import GHC.Enum
60 import GHC.Real
61 import GHC.Show
62 import GHC.Read
63 import GHC.Num
64 #else
65 import Control.Monad
66 import Foreign.Ptr
67 #endif
68
69 #include "Typeable.h"
70 #include "CTypes.h"
71
72 INTEGRAL_TYPE(CChar,tyConCChar,"CChar",HTYPE_CHAR)
73 INTEGRAL_TYPE(CSChar,tyConCSChar,"CSChar",HTYPE_SIGNED_CHAR)
74 INTEGRAL_TYPE(CUChar,tyConCUChar,"CUChar",HTYPE_UNSIGNED_CHAR)
75
76 INTEGRAL_TYPE(CShort,tyConCShort,"CShort",HTYPE_SHORT)
77 INTEGRAL_TYPE(CUShort,tyConCUShort,"CUShort",HTYPE_UNSIGNED_SHORT)
78
79 INTEGRAL_TYPE(CInt,tyConCInt,"CInt",HTYPE_INT)
80 INTEGRAL_TYPE(CUInt,tyConCUInt,"CUInt",HTYPE_UNSIGNED_INT)
81
82 INTEGRAL_TYPE(CLong,tyConCLong,"CLong",HTYPE_LONG)
83 INTEGRAL_TYPE(CULong,tyConCULong,"CULong",HTYPE_UNSIGNED_LONG)
84
85 INTEGRAL_TYPE(CLLong,tyConCLLong,"CLLong",HTYPE_LONG_LONG)
86 INTEGRAL_TYPE(CULLong,tyConCULLong,"CULLong",HTYPE_UNSIGNED_LONG_LONG)
87
88 {-# RULES
89 "fromIntegral/a->CChar"   fromIntegral = \x -> CChar   (fromIntegral x)
90 "fromIntegral/a->CSChar"  fromIntegral = \x -> CSChar  (fromIntegral x)
91 "fromIntegral/a->CUChar"  fromIntegral = \x -> CUChar  (fromIntegral x)
92 "fromIntegral/a->CShort"  fromIntegral = \x -> CShort  (fromIntegral x)
93 "fromIntegral/a->CUShort" fromIntegral = \x -> CUShort (fromIntegral x)
94 "fromIntegral/a->CInt"    fromIntegral = \x -> CInt    (fromIntegral x)
95 "fromIntegral/a->CUInt"   fromIntegral = \x -> CUInt   (fromIntegral x)
96 "fromIntegral/a->CLong"   fromIntegral = \x -> CLong   (fromIntegral x)
97 "fromIntegral/a->CULong"  fromIntegral = \x -> CULong  (fromIntegral x)
98 "fromIntegral/a->CLLong"  fromIntegral = \x -> CLLong  (fromIntegral x)
99 "fromIntegral/a->CULLong" fromIntegral = \x -> CULLong (fromIntegral x)
100
101 "fromIntegral/CChar->a"   fromIntegral = \(CChar   x) -> fromIntegral x
102 "fromIntegral/CSChar->a"  fromIntegral = \(CSChar  x) -> fromIntegral x
103 "fromIntegral/CUChar->a"  fromIntegral = \(CUChar  x) -> fromIntegral x
104 "fromIntegral/CShort->a"  fromIntegral = \(CShort  x) -> fromIntegral x
105 "fromIntegral/CUShort->a" fromIntegral = \(CUShort x) -> fromIntegral x
106 "fromIntegral/CInt->a"    fromIntegral = \(CInt    x) -> fromIntegral x
107 "fromIntegral/CUInt->a"   fromIntegral = \(CUInt   x) -> fromIntegral x
108 "fromIntegral/CLong->a"   fromIntegral = \(CLong   x) -> fromIntegral x
109 "fromIntegral/CULong->a"  fromIntegral = \(CULong  x) -> fromIntegral x
110 "fromIntegral/CLLong->a"  fromIntegral = \(CLLong  x) -> fromIntegral x
111 "fromIntegral/CULLong->a" fromIntegral = \(CULLong x) -> fromIntegral x
112  #-}
113
114 FLOATING_TYPE(CFloat,tyConCFloat,"CFloat",HTYPE_FLOAT)
115 FLOATING_TYPE(CDouble,tyConCDouble,"CDouble",HTYPE_DOUBLE)
116 -- HACK: Currently no long double in the FFI, so we simply re-use double
117 FLOATING_TYPE(CLDouble,tyConCLDouble,"CLDouble",HTYPE_DOUBLE)
118
119 {-# RULES
120 "realToFrac/a->CFloat"    realToFrac = \x -> CFloat   (realToFrac x)
121 "realToFrac/a->CDouble"   realToFrac = \x -> CDouble  (realToFrac x)
122 "realToFrac/a->CLDouble"  realToFrac = \x -> CLDouble (realToFrac x)
123
124 "realToFrac/CFloat->a"    realToFrac = \(CFloat   x) -> realToFrac x
125 "realToFrac/CDouble->a"   realToFrac = \(CDouble  x) -> realToFrac x
126 "realToFrac/CLDouble->a"  realToFrac = \(CLDouble x) -> realToFrac x
127  #-}
128
129 INTEGRAL_TYPE(CPtrdiff,tyConCPtrdiff,"CPtrdiff",HTYPE_PTRDIFF_T)
130 INTEGRAL_TYPE(CSize,tyConCSize,"CSize",HTYPE_SIZE_T)
131 INTEGRAL_TYPE(CWchar,tyConCWchar,"CWchar",HTYPE_WCHAR_T)
132 INTEGRAL_TYPE(CSigAtomic,tyConCSigAtomic,"CSigAtomic",HTYPE_SIG_ATOMIC_T)
133
134 {-# RULES
135 "fromIntegral/a->CPtrdiff"   fromIntegral = \x -> CPtrdiff   (fromIntegral x)
136 "fromIntegral/a->CSize"      fromIntegral = \x -> CSize      (fromIntegral x)
137 "fromIntegral/a->CWchar"     fromIntegral = \x -> CWchar     (fromIntegral x)
138 "fromIntegral/a->CSigAtomic" fromIntegral = \x -> CSigAtomic (fromIntegral x)
139
140 "fromIntegral/CPtrdiff->a"   fromIntegral = \(CPtrdiff   x) -> fromIntegral x
141 "fromIntegral/CSize->a"      fromIntegral = \(CSize      x) -> fromIntegral x
142 "fromIntegral/CWchar->a"     fromIntegral = \(CWchar     x) -> fromIntegral x
143 "fromIntegral/CSigAtomic->a" fromIntegral = \(CSigAtomic x) -> fromIntegral x
144  #-}
145
146 ARITHMETIC_TYPE(CClock,tyConCClock,"CClock",HTYPE_CLOCK_T)
147 ARITHMETIC_TYPE(CTime,tyConCTime,"CTime",HTYPE_TIME_T)
148
149 -- FIXME: Implement and provide instances for Eq and Storable
150 data CFile = CFile
151 data CFpos = CFpos
152 data CJmpBuf = CJmpBuf
153
154 -- C99 types which are still missing include:
155 -- intptr_t, uintptr_t, intmax_t, uintmax_t, wint_t, wctrans_t, wctype_t
156
157 #else   /* __NHC__ */
158
159 import NHC.FFI
160   ( CChar(..),    CSChar(..),  CUChar(..)
161   , CShort(..),   CUShort(..), CInt(..),   CUInt(..)
162   , CLong(..),    CULong(..),  CLLong(..), CULLong(..)
163   , CPtrdiff(..), CSize(..),   CWchar(..), CSigAtomic(..)
164   , CClock(..),   CTime(..)
165   , CFloat(..),   CDouble(..), CLDouble(..)
166   , CFile,        CFpos,       CJmpBuf
167   , Storable(..)
168   )
169 import Data.Bits
170 import NHC.SizedTypes
171
172 #define INSTANCE_BITS(T) \
173 instance Bits T where { \
174   (T x) .&.     (T y)   = T (x .&.   y) ; \
175   (T x) .|.     (T y)   = T (x .|.   y) ; \
176   (T x) `xor`   (T y)   = T (x `xor` y) ; \
177   complement    (T x)   = T (complement x) ; \
178   shift         (T x) n = T (shift x n) ; \
179   rotate        (T x) n = T (rotate x n) ; \
180   bit                 n = T (bit n) ; \
181   setBit        (T x) n = T (setBit x n) ; \
182   clearBit      (T x) n = T (clearBit x n) ; \
183   complementBit (T x) n = T (complementBit x n) ; \
184   testBit       (T x) n = testBit x n ; \
185   bitSize       (T x)   = bitSize x ; \
186   isSigned      (T x)   = isSigned x }
187
188 INSTANCE_BITS(CChar)
189 INSTANCE_BITS(CSChar)
190 INSTANCE_BITS(CUChar)
191 INSTANCE_BITS(CShort)
192 INSTANCE_BITS(CUShort)
193 INSTANCE_BITS(CInt)
194 INSTANCE_BITS(CUInt)
195 INSTANCE_BITS(CLong)
196 INSTANCE_BITS(CULong)
197 INSTANCE_BITS(CLLong)
198 INSTANCE_BITS(CULLong)
199 INSTANCE_BITS(CPtrdiff)
200 INSTANCE_BITS(CWchar)
201 INSTANCE_BITS(CSigAtomic)
202 INSTANCE_BITS(CSize)
203
204 #endif