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