[project @ 1999-05-18 15:03:54 by simonpj]
[ghc-hetmet.git] / ghc / compiler / prelude / ThinAir.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
3 %
4 \section{Thin air Ids}
5
6 \begin{code}
7 module ThinAir (
8         thinAirIdNames, -- Names of non-wired-in Ids that may be used out of
9         setThinAirIds,  -- thin air in any compilation. If they are not wired in
10         thinAirModules, -- we must be sure to import them from some Prelude 
11                         -- interface file even if they are not overtly 
12                         -- mentioned.  Subset of builtinNames.
13         -- Here are the thin-air Ids themselves
14         addr2IntegerId,
15         packStringForCId, unpackCStringId, unpackCString2Id,
16         unpackCStringAppendId, unpackCStringFoldrId,
17         foldrId, buildId,
18
19         noRepIntegerIds,
20         noRepStrIds
21
22         ) where
23
24 #include "HsVersions.h"
25
26 import Var      ( Id, varUnique )
27 import Name     ( mkKnownKeyGlobal, varName )
28 import RdrName  ( mkPreludeQual )
29 import PrelMods
30 import UniqFM   ( UniqFM, listToUFM, lookupWithDefaultUFM ) 
31 import Unique
32 import Outputable
33 import IOExts
34 \end{code}
35
36
37 %************************************************************************
38 %*                                                                      *
39 \subsection{Thin air entities}
40 %*                                                                      *
41 %************************************************************************
42
43 These are Ids that we need to reference in various parts of the
44 system, and we'd like to pull them out of thin air rather than pass
45 them around.  We'd also like to have all the IdInfo available for each
46 one: i.e. everything that gets pulled out of the interface file.
47
48 The solution is to generate this map of global Ids after the
49 typechecker, and assign it to a global variable.  Any subsequent
50 pass may refer to the map to pull Ids out.  Any invalid
51 (i.e. pre-typechecker) access to the map will result in a panic.
52
53 \begin{code}
54 thinAirIdNames 
55   = map mkKnownKeyGlobal
56     [
57         -- Needed for converting literals to Integers (used in tidyCoreExpr)
58       (varQual pREL_BASE_Name SLIT("addr2Integer"), addr2IntegerIdKey)
59
60         -- String literals
61     , (varQual pREL_PACK_Name SLIT("packCString#"),   packCStringIdKey)
62     , (varQual pREL_PACK_Name SLIT("unpackCString#"), unpackCStringIdKey)
63     , (varQual pREL_PACK_Name SLIT("unpackNBytes#"),  unpackCString2IdKey)
64     , (varQual pREL_PACK_Name SLIT("unpackAppendCString#"), unpackCStringAppendIdKey)
65     , (varQual pREL_PACK_Name SLIT("unpackFoldrCString#"),  unpackCStringFoldrIdKey)
66
67         -- Folds and builds; introduced by desugaring list comprehensions
68     , (varQual pREL_BASE_Name SLIT("foldr"), foldrIdKey)
69     , (varQual pREL_BASE_Name SLIT("build"), buildIdKey)
70     ]
71
72 varQual = mkPreludeQual varName
73
74 thinAirModules = [pREL_PACK_Name,pREL_BASE_Name]        -- See notes with RnIfaces.findAndReadIface
75 \end{code}
76
77
78 \begin{code}
79 noRepIntegerIds = [addr2IntegerId]
80
81 noRepStrIds = [unpackCString2Id, unpackCStringId]
82
83 addr2IntegerId = lookupThinAirId addr2IntegerIdKey
84
85 packStringForCId = lookupThinAirId packCStringIdKey
86 unpackCStringId  = lookupThinAirId unpackCStringIdKey
87 unpackCString2Id = lookupThinAirId unpackCString2IdKey 
88 unpackCStringAppendId = lookupThinAirId unpackCStringAppendIdKey 
89 unpackCStringFoldrId  = lookupThinAirId unpackCStringFoldrIdKey 
90
91 foldrId = lookupThinAirId foldrIdKey
92 buildId = lookupThinAirId buildIdKey
93 \end{code}
94
95 \begin{code}
96 thinAirIdMapRef :: IORef (UniqFM Id)
97 thinAirIdMapRef = unsafePerformIO (newIORef (panic "thinAirIdMap: still empty"))
98
99 setThinAirIds :: [Id] -> IO ()
100 setThinAirIds thin_air_ids
101   = writeIORef thinAirIdMapRef the_map
102   where
103     the_map = listToUFM [(varUnique id, id) | id <- thin_air_ids]
104
105 thinAirIdMap :: UniqFM Id
106 thinAirIdMap = unsafePerformIO (readIORef thinAirIdMapRef)
107   -- Read it just once, the first time someone tugs on thinAirIdMap
108
109 lookupThinAirId :: Unique -> Id
110 lookupThinAirId uniq = lookupWithDefaultUFM thinAirIdMap
111                         (panic "lookupThinAirId: no mapping") uniq 
112 \end{code}
113