[project @ 2000-07-24 14:29:55 by simonmar]
[ghc-hetmet.git] / ghc / compiler / prelude / TysWiredIn.lhs
1 %
2 % (c) The GRASP Project, Glasgow University, 1994-1998
3 %
4 \section[TysWiredIn]{Wired-in knowledge about {\em non-primitive} types}
5
6 This module is about types that can be defined in Haskell, but which
7 must be wired into the compiler nonetheless.
8
9 This module tracks the ``state interface'' document, ``GHC prelude:
10 types and operations.''
11
12 \begin{code}
13 module TysWiredIn (
14         addrDataCon,
15         addrTy,
16         addrTyCon,
17         boolTy,
18         boolTyCon,
19         charDataCon,
20         charTy,
21         charTyCon,
22         consDataCon,
23         doubleDataCon,
24         doubleTy,
25         isDoubleTy,
26         doubleTyCon,
27         falseDataCon, falseDataConId,
28         floatDataCon,
29         floatTy,
30         isFloatTy,
31         floatTyCon,
32
33         intDataCon,
34         intTy,
35         intTyCon,
36         isIntTy,
37
38         integerTy,
39         integerTyCon,
40         smallIntegerDataCon,
41         largeIntegerDataCon,
42         isIntegerTy,
43
44         listTyCon,
45
46         mkListTy,
47         nilDataCon,
48
49         -- tuples
50         mkTupleTy,
51         tupleTyCon, tupleCon, 
52         unitTyCon, unitDataConId, pairTyCon, 
53         unboxedSingletonTyCon, unboxedSingletonDataCon,
54         unboxedPairTyCon, unboxedPairDataCon,
55
56         stablePtrTyCon,
57         stringTy,
58         trueDataCon, trueDataConId,
59         unitTy,
60         voidTy,
61         wordDataCon,
62         wordTy,
63         wordTyCon,
64
65         isFFIArgumentTy,  -- :: Bool -> Type -> Bool
66         isFFIResultTy,    -- :: Type -> Bool
67         isFFIExternalTy,  -- :: Type -> Bool
68         isFFIDynResultTy, -- :: Type -> Bool
69         isFFILabelTy,     -- :: Type -> Bool
70         isAddrTy,         -- :: Type -> Bool
71         isForeignObjTy    -- :: Type -> Bool
72
73     ) where
74
75 #include "HsVersions.h"
76
77 import {-# SOURCE #-} MkId( mkDataConId, mkDataConWrapId )
78
79 -- friends:
80 import PrelNames
81 import TysPrim
82
83 -- others:
84 import Constants        ( mAX_TUPLE_SIZE )
85 import Module           ( Module, mkPrelModule )
86 import Name             ( mkWiredInTyConName, mkWiredInIdName, mkSrcOccFS, mkWorkerOcc, dataName )
87 import DataCon          ( DataCon, StrictnessMark(..),  mkDataCon, dataConId )
88 import Var              ( TyVar, tyVarKind )
89 import TyCon            ( TyCon, AlgTyConFlavour(..), ArgVrcs, tyConDataCons,
90                           mkAlgTyCon, mkSynTyCon, mkTupleTyCon, isUnLiftedTyCon
91                         )
92 import BasicTypes       ( Arity, RecFlag(..), Boxity(..), isBoxed )
93 import Type             ( Type, mkTyConTy, mkTyConApp, mkSigmaTy, mkTyVarTys, 
94                           mkArrowKinds, boxedTypeKind, unboxedTypeKind,
95                           mkFunTy, mkFunTys,
96                           splitTyConApp_maybe, repType,
97                           TauType, ClassContext )
98 import Unique
99 import CmdLineOpts      ( opt_GlasgowExts )
100 import Array
101
102 alpha_tyvar       = [alphaTyVar]
103 alpha_ty          = [alphaTy]
104 alpha_beta_tyvars = [alphaTyVar, betaTyVar]
105
106 pcRecDataTyCon, pcNonRecDataTyCon
107         :: Unique{-TyConKey-} -> Module -> FAST_STRING
108         -> [TyVar] -> ArgVrcs -> [DataCon] -> TyCon
109
110 pcRecDataTyCon    = pcTyCon DataTyCon Recursive
111 pcNonRecDataTyCon = pcTyCon DataTyCon NonRecursive
112
113 pcTyCon new_or_data is_rec key mod str tyvars argvrcs cons
114   = tycon
115   where
116     tycon = mkAlgTyCon name kind 
117                 tyvars 
118                 []              -- No context
119                 argvrcs
120                 cons
121                 (length cons)
122                 []              -- No derivings
123                 new_or_data
124                 is_rec
125
126     name = mkWiredInTyConName key mod str tycon
127     kind = mkArrowKinds (map tyVarKind tyvars) boxedTypeKind
128
129 pcSynTyCon key mod str kind arity tyvars expansion argvrcs  -- this fun never used!
130   = tycon
131   where
132     tycon = mkSynTyCon name kind arity tyvars expansion argvrcs
133     name  = mkWiredInTyConName key mod str tycon
134
135 pcDataCon :: Unique{-DataConKey-} -> Module -> FAST_STRING
136           -> [TyVar] -> ClassContext -> [TauType] -> TyCon -> DataCon
137 -- The unique is the first of two free uniques;
138 -- the first is used for the datacon itself and the worker; 
139 -- the second is used for the wrapper.
140 pcDataCon wrap_key mod str tyvars context arg_tys tycon
141   = data_con
142   where
143     data_con = mkDataCon wrap_name 
144                 [ NotMarkedStrict | a <- arg_tys ]
145                 [ {- no labelled fields -} ]
146                 tyvars context [] [] arg_tys tycon work_id wrap_id
147
148     work_occ  = mkWorkerOcc wrap_occ
149     work_key  = incrUnique wrap_key
150     work_name = mkWiredInIdName work_key mod work_occ work_id
151     work_id   = mkDataConId work_name data_con
152     
153     wrap_occ  = mkSrcOccFS dataName str
154     wrap_name = mkWiredInIdName wrap_key mod wrap_occ wrap_id
155     wrap_id   = mkDataConWrapId data_con
156 \end{code}
157
158
159 %************************************************************************
160 %*                                                                      *
161 \subsection[TysWiredIn-tuples]{The tuple types}
162 %*                                                                      *
163 %************************************************************************
164
165 \begin{code}
166 tupleTyCon :: Boxity -> Arity -> TyCon
167 tupleTyCon boxity i | i > mAX_TUPLE_SIZE = fst (mk_tuple boxity i)      -- Build one specially
168 tupleTyCon Boxed   i = fst (boxedTupleArr   ! i)
169 tupleTyCon Unboxed i = fst (unboxedTupleArr ! i)
170
171 tupleCon :: Boxity -> Arity -> DataCon
172 tupleCon boxity i | i > mAX_TUPLE_SIZE = snd (mk_tuple boxity i)        -- Build one specially
173 tupleCon Boxed   i = snd (boxedTupleArr   ! i)
174 tupleCon Unboxed i = snd (unboxedTupleArr ! i)
175
176 boxedTupleArr, unboxedTupleArr :: Array Int (TyCon,DataCon)
177 boxedTupleArr   = array (0,mAX_TUPLE_SIZE) [(i,mk_tuple Boxed i)   | i <- [0..mAX_TUPLE_SIZE]]
178 unboxedTupleArr = array (0,mAX_TUPLE_SIZE) [(i,mk_tuple Unboxed i) | i <- [0..mAX_TUPLE_SIZE]]
179
180 mk_tuple :: Boxity -> Int -> (TyCon,DataCon)
181 mk_tuple boxity arity = (tycon, tuple_con)
182   where
183         tycon   = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con boxity
184         tc_name = mkWiredInTyConName tc_uniq mod name_str tycon
185         tc_kind = mkArrowKinds (map tyVarKind tyvars) res_kind
186         res_kind | isBoxed boxity = boxedTypeKind
187                  | otherwise      = unboxedTypeKind
188
189         tyvars   | isBoxed boxity = take arity alphaTyVars
190                  | otherwise      = take arity openAlphaTyVars
191
192         tuple_con = pcDataCon dc_uniq mod name_str tyvars [] tyvar_tys tycon
193         tyvar_tys = mkTyVarTys tyvars
194         (mod_name, name_str) = mkTupNameStr boxity arity
195         tc_uniq   = mkTupleTyConUnique   boxity arity
196         dc_uniq   = mkTupleDataConUnique boxity arity
197         mod       = mkPrelModule mod_name
198
199 unitTyCon     = tupleTyCon Boxed 0
200 unitDataConId = dataConId (head (tyConDataCons unitTyCon))
201
202 pairTyCon = tupleTyCon Boxed 2
203
204 unboxedSingletonTyCon   = tupleTyCon Unboxed 1
205 unboxedSingletonDataCon = tupleCon   Unboxed 1
206
207 unboxedPairTyCon   = tupleTyCon Unboxed 2
208 unboxedPairDataCon = tupleCon   Unboxed 2
209 \end{code}
210
211 %************************************************************************
212 %*                                                                      *
213 \subsection[TysWiredIn-boxed-prim]{The ``boxed primitive'' types (@Char@, @Int@, etc)}
214 %*                                                                      *
215 %************************************************************************
216
217 \begin{code}
218 -- The Void type is represented as a data type with no constructors
219 -- It's a built in type (i.e. there's no way to define it in Haskell;
220 --      the nearest would be
221 --
222 --              data Void =             -- No constructors!
223 --
224 -- ) It's boxed; there is only one value of this
225 -- type, namely "void", whose semantics is just bottom.
226 --
227 -- Haskell 98 drops the definition of a Void type, so we just 'simulate'
228 -- voidTy using ().
229 voidTy = unitTy
230 \end{code}
231
232
233 \begin{code}
234 charTy = mkTyConTy charTyCon
235
236 charTyCon = pcNonRecDataTyCon charTyConKey  pREL_BASE  SLIT("Char") [] [] [charDataCon]
237 charDataCon = pcDataCon charDataConKey pREL_BASE SLIT("C#") [] [] [charPrimTy] charTyCon
238
239 stringTy = mkListTy charTy -- convenience only
240 \end{code}
241
242 \begin{code}
243 intTy = mkTyConTy intTyCon 
244
245 intTyCon = pcNonRecDataTyCon intTyConKey pREL_BASE SLIT("Int") [] [] [intDataCon]
246 intDataCon = pcDataCon intDataConKey pREL_BASE SLIT("I#") [] [] [intPrimTy] intTyCon
247
248 isIntTy :: Type -> Bool
249 isIntTy = isTyCon intTyConKey
250 \end{code}
251
252 \begin{code}
253
254 wordTy = mkTyConTy wordTyCon
255
256 wordTyCon = pcNonRecDataTyCon wordTyConKey   pREL_ADDR SLIT("Word") [] [] [wordDataCon]
257 wordDataCon = pcDataCon wordDataConKey pREL_ADDR SLIT("W#") [] [] [wordPrimTy] wordTyCon
258 \end{code}
259
260 \begin{code}
261 addrTy = mkTyConTy addrTyCon
262
263 addrTyCon = pcNonRecDataTyCon addrTyConKey   pREL_ADDR SLIT("Addr") [] [] [addrDataCon]
264 addrDataCon = pcDataCon addrDataConKey pREL_ADDR SLIT("A#") [] [] [addrPrimTy] addrTyCon
265
266 isAddrTy :: Type -> Bool
267 isAddrTy = isTyCon addrTyConKey
268 \end{code}
269
270 \begin{code}
271 floatTy = mkTyConTy floatTyCon
272
273 floatTyCon = pcNonRecDataTyCon floatTyConKey pREL_FLOAT SLIT("Float") [] [] [floatDataCon]
274 floatDataCon = pcDataCon floatDataConKey pREL_FLOAT SLIT("F#") [] [] [floatPrimTy] floatTyCon
275
276 isFloatTy :: Type -> Bool
277 isFloatTy = isTyCon floatTyConKey
278 \end{code}
279
280 \begin{code}
281 doubleTy = mkTyConTy doubleTyCon
282
283 isDoubleTy :: Type -> Bool
284 isDoubleTy = isTyCon doubleTyConKey
285
286 doubleTyCon = pcNonRecDataTyCon doubleTyConKey pREL_FLOAT SLIT("Double") [] [] [doubleDataCon]
287 doubleDataCon = pcDataCon doubleDataConKey pREL_FLOAT SLIT("D#") [] [] [doublePrimTy] doubleTyCon
288 \end{code}
289
290 \begin{code}
291 stablePtrTyCon
292   = pcNonRecDataTyCon stablePtrTyConKey pREL_STABLE SLIT("StablePtr")
293         alpha_tyvar [(True,False)] [stablePtrDataCon]
294   where
295     stablePtrDataCon
296       = pcDataCon stablePtrDataConKey pREL_STABLE SLIT("StablePtr")
297             alpha_tyvar [] [mkStablePtrPrimTy alphaTy] stablePtrTyCon
298 \end{code}
299
300 \begin{code}
301 foreignObjTyCon
302   = pcNonRecDataTyCon foreignObjTyConKey pREL_IO_BASE SLIT("ForeignObj")
303         [] [] [foreignObjDataCon]
304   where
305     foreignObjDataCon
306       = pcDataCon foreignObjDataConKey pREL_IO_BASE SLIT("ForeignObj")
307             [] [] [foreignObjPrimTy] foreignObjTyCon
308
309 isForeignObjTy :: Type -> Bool
310 isForeignObjTy = isTyCon foreignObjTyConKey
311 \end{code}
312
313 %************************************************************************
314 %*                                                                      *
315 \subsection[TysWiredIn-Integer]{@Integer@ and its related ``pairing'' types}
316 %*                                                                      *
317 %************************************************************************
318
319 @Integer@ and its pals are not really primitive.  @Integer@ itself, first:
320 \begin{code}
321 integerTy :: Type
322 integerTy = mkTyConTy integerTyCon
323
324 integerTyCon = pcNonRecDataTyCon integerTyConKey pREL_NUM SLIT("Integer")
325                    [] [] [smallIntegerDataCon, largeIntegerDataCon]
326
327 smallIntegerDataCon = pcDataCon smallIntegerDataConKey pREL_NUM SLIT("S#")
328                 [] [] [intPrimTy] integerTyCon
329 largeIntegerDataCon = pcDataCon largeIntegerDataConKey pREL_NUM SLIT("J#")
330                 [] [] [intPrimTy, byteArrayPrimTy] integerTyCon
331
332
333 isIntegerTy :: Type -> Bool
334 isIntegerTy = isTyCon integerTyConKey
335 \end{code}
336
337
338 %************************************************************************
339 %*                                                                      *
340 \subsection[TysWiredIn-ext-type]{External types}
341 %*                                                                      *
342 %************************************************************************
343
344 The compiler's foreign function interface supports the passing of a
345 restricted set of types as arguments and results (the restricting factor
346 being the )
347
348 \begin{code}
349 isFFIArgumentTy :: Bool -> Type -> Bool
350 -- Checks for valid argument type for a 'foreign import'
351 isFFIArgumentTy is_safe ty = checkRepTyCon (legalOutgoingTyCon is_safe) ty
352
353 isFFIExternalTy :: Type -> Bool
354 -- Types that are allowed as arguments of a 'foreign export'
355 isFFIExternalTy ty = checkRepTyCon legalIncomingTyCon ty
356
357 isFFIResultTy :: Type -> Bool
358 -- Types that are allowed as a result of a 'foreign import' or of a 'foreign export'
359 -- Maybe we should distinguish between import and export, but 
360 -- here we just choose the more restrictive 'incoming' predicate
361 -- But we allow () as well
362 isFFIResultTy ty = checkRepTyCon (\tc -> tc == unitTyCon || legalIncomingTyCon tc) ty
363
364 -- The result type of a foreign export dynamic must be either Addr, or
365 -- a newtype of Addr.
366 isFFIDynResultTy = checkRepTyCon (== addrTyCon)
367
368 -- The type of a foreign label must be either Addr, or
369 -- a newtype of Addr.
370 isFFILabelTy = checkRepTyCon (== addrTyCon)
371
372 checkRepTyCon :: (TyCon -> Bool) -> Type -> Bool
373         -- look through newtypes
374 checkRepTyCon check_tc ty = checkTyCon check_tc (repType ty)
375
376 checkTyCon :: (TyCon -> Bool) -> Type -> Bool
377 checkTyCon check_tc ty = case splitTyConApp_maybe ty of
378                                 Just (tycon, _) -> check_tc tycon
379                                 Nothing         -> False
380
381 isTyCon :: Unique -> Type -> Bool
382 isTyCon uniq ty = checkTyCon (\tc -> uniq == getUnique tc) ty
383 \end{code}
384
385 ----------------------------------------------
386 These chaps do the work; they are not exported
387 ----------------------------------------------
388
389 \begin{code}
390 legalIncomingTyCon :: TyCon -> Bool
391 -- It's illegal to return foreign objects and (mutable)
392 -- bytearrays from a _ccall_ / foreign declaration
393 -- (or be passed them as arguments in foreign exported functions).
394 legalIncomingTyCon tc
395   | getUnique tc `elem` [ foreignObjTyConKey, byteArrayTyConKey, mutableByteArrayTyConKey ] 
396   = False
397   -- It's also illegal to make foreign exports that take unboxed
398   -- arguments.  The RTS API currently can't invoke such things.  --SDM 7/2000
399   | otherwise
400   = boxedMarshalableTyCon tc
401
402 legalOutgoingTyCon :: Bool -> TyCon -> Bool
403 -- Checks validity of types going from Haskell -> external world
404 -- The boolean is true for a 'safe' call (when we don't want to
405 -- pass Haskell pointers to the world)
406 legalOutgoingTyCon be_safe tc
407   | be_safe && getUnique tc `elem` [byteArrayTyConKey, mutableByteArrayTyConKey]
408   = False
409   | otherwise
410   = marshalableTyCon tc
411
412 marshalableTyCon tc
413   =  (opt_GlasgowExts && isUnLiftedTyCon tc)
414   || boxedMarshalableTyCon tc
415
416 boxedMarshalableTyCon tc
417    = getUnique tc `elem` [ intTyConKey, int8TyConKey, int16TyConKey, int32TyConKey, int64TyConKey
418                          , wordTyConKey, word8TyConKey, word16TyConKey, word32TyConKey, word64TyConKey
419                          , floatTyConKey, doubleTyConKey
420                          , addrTyConKey, charTyConKey, foreignObjTyConKey
421                          , stablePtrTyConKey
422                          , byteArrayTyConKey, mutableByteArrayTyConKey
423                          , boolTyConKey
424                          ]
425 \end{code}
426
427
428 %************************************************************************
429 %*                                                                      *
430 \subsection[TysWiredIn-Bool]{The @Bool@ type}
431 %*                                                                      *
432 %************************************************************************
433
434 An ordinary enumeration type, but deeply wired in.  There are no
435 magical operations on @Bool@ (just the regular Prelude code).
436
437 {\em BEGIN IDLE SPECULATION BY SIMON}
438
439 This is not the only way to encode @Bool@.  A more obvious coding makes
440 @Bool@ just a boxed up version of @Bool#@, like this:
441 \begin{verbatim}
442 type Bool# = Int#
443 data Bool = MkBool Bool#
444 \end{verbatim}
445
446 Unfortunately, this doesn't correspond to what the Report says @Bool@
447 looks like!  Furthermore, we get slightly less efficient code (I
448 think) with this coding. @gtInt@ would look like this:
449
450 \begin{verbatim}
451 gtInt :: Int -> Int -> Bool
452 gtInt x y = case x of I# x# ->
453             case y of I# y# ->
454             case (gtIntPrim x# y#) of
455                 b# -> MkBool b#
456 \end{verbatim}
457
458 Notice that the result of the @gtIntPrim@ comparison has to be turned
459 into an integer (here called @b#@), and returned in a @MkBool@ box.
460
461 The @if@ expression would compile to this:
462 \begin{verbatim}
463 case (gtInt x y) of
464   MkBool b# -> case b# of { 1# -> e1; 0# -> e2 }
465 \end{verbatim}
466
467 I think this code is a little less efficient than the previous code,
468 but I'm not certain.  At all events, corresponding with the Report is
469 important.  The interesting thing is that the language is expressive
470 enough to describe more than one alternative; and that a type doesn't
471 necessarily need to be a straightforwardly boxed version of its
472 primitive counterpart.
473
474 {\em END IDLE SPECULATION BY SIMON}
475
476 \begin{code}
477 boolTy = mkTyConTy boolTyCon
478
479 boolTyCon = pcTyCon EnumTyCon NonRecursive boolTyConKey 
480                     pREL_BASE SLIT("Bool") [] [] [falseDataCon, trueDataCon]
481
482 falseDataCon = pcDataCon falseDataConKey pREL_BASE SLIT("False") [] [] [] boolTyCon
483 trueDataCon  = pcDataCon trueDataConKey  pREL_BASE SLIT("True")  [] [] [] boolTyCon
484
485 falseDataConId = dataConId falseDataCon
486 trueDataConId  = dataConId trueDataCon
487 \end{code}
488
489 %************************************************************************
490 %*                                                                      *
491 \subsection[TysWiredIn-List]{The @List@ type (incl ``build'' magic)}
492 %*                                                                      *
493 %************************************************************************
494
495 Special syntax, deeply wired in, but otherwise an ordinary algebraic
496 data types:
497 \begin{verbatim}
498 data [] a = [] | a : (List a)
499 data () = ()
500 data (,) a b = (,,) a b
501 ...
502 \end{verbatim}
503
504 \begin{code}
505 mkListTy :: Type -> Type
506 mkListTy ty = mkTyConApp listTyCon [ty]
507
508 alphaListTy = mkSigmaTy alpha_tyvar [] (mkTyConApp listTyCon alpha_ty)
509
510 listTyCon = pcRecDataTyCon listTyConKey pREL_BASE SLIT("[]") 
511                         alpha_tyvar [(True,False)] [nilDataCon, consDataCon]
512
513 nilDataCon  = pcDataCon nilDataConKey  pREL_BASE SLIT("[]") alpha_tyvar [] [] listTyCon
514 consDataCon = pcDataCon consDataConKey pREL_BASE SLIT(":")
515                 alpha_tyvar [] [alphaTy, mkTyConApp listTyCon alpha_ty] listTyCon
516 -- Interesting: polymorphic recursion would help here.
517 -- We can't use (mkListTy alphaTy) in the defn of consDataCon, else mkListTy
518 -- gets the over-specific type (Type -> Type)
519 \end{code}
520
521 %************************************************************************
522 %*                                                                      *
523 \subsection[TysWiredIn-Tuples]{The @Tuple@ types}
524 %*                                                                      *
525 %************************************************************************
526
527 The tuple types are definitely magic, because they form an infinite
528 family.
529
530 \begin{itemize}
531 \item
532 They have a special family of type constructors, of type @TyCon@
533 These contain the tycon arity, but don't require a Unique.
534
535 \item
536 They have a special family of constructors, of type
537 @Id@. Again these contain their arity but don't need a Unique.
538
539 \item
540 There should be a magic way of generating the info tables and
541 entry code for all tuples.
542
543 But at the moment we just compile a Haskell source
544 file\srcloc{lib/prelude/...} containing declarations like:
545 \begin{verbatim}
546 data Tuple0             = Tup0
547 data Tuple2  a b        = Tup2  a b
548 data Tuple3  a b c      = Tup3  a b c
549 data Tuple4  a b c d    = Tup4  a b c d
550 ...
551 \end{verbatim}
552 The print-names associated with the magic @Id@s for tuple constructors
553 ``just happen'' to be the same as those generated by these
554 declarations.
555
556 \item
557 The instance environment should have a magic way to know
558 that each tuple type is an instances of classes @Eq@, @Ix@, @Ord@ and
559 so on. \ToDo{Not implemented yet.}
560
561 \item
562 There should also be a way to generate the appropriate code for each
563 of these instances, but (like the info tables and entry code) it is
564 done by enumeration\srcloc{lib/prelude/InTup?.hs}.
565 \end{itemize}
566
567 \begin{code}
568 mkTupleTy :: Boxity -> Int -> [Type] -> Type
569 mkTupleTy boxity arity tys = mkTyConApp (tupleTyCon boxity arity) tys
570
571 unitTy    = mkTupleTy Boxed 0 []
572 \end{code}