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