[project @ 1996-01-08 20:28:12 by partain]
[ghc.git] / ghc / compiler / rename / RenameMonad3.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1995
3 %
4 \section[RenameMonad3]{The monad used by the third renamer pass}
5
6 \begin{code}
7 #include "HsVersions.h"
8
9 module RenameMonad3 (
10         Rn3M(..),
11         initRn3, thenRn3, andRn3, returnRn3, mapRn3, fixRn3,
12
13         putInfoDownM3,
14
15         newFullNameM3, newInvisibleNameM3,
16
17         -- for completeness
18         IE, FullName, ExportFlag, ProtoName, Unique,
19         SplitUniqSupply
20         IF_ATTACK_PRAGMAS(COMMA splitUniqSupply)
21     ) where
22
23 import AbsSyn           -- including, IE, getIEStrings, ...
24 import FiniteMap
25 import Maybes           ( Maybe(..), assocMaybe )
26 import NameTypes
27 import Outputable
28 import ProtoName
29 import RenameMonad4     ( GlobalNameFun(..) )
30 import SplitUniq
31 import Unique
32 import Util
33
34 infixr 9 `thenRn3`
35 \end{code}
36
37 %************************************************************************
38 %*                                                                      *
39 \subsection{Plain @Rename3@ monadery}
40 %*                                                                      *
41 %************************************************************************
42
43 \begin{code}
44 type Rn3M result
45   =  ImExportListInfo -> FAST_STRING{-ModuleName-} -> SplitUniqSupply
46   -> result
47
48 #ifdef __GLASGOW_HASKELL__
49 {-# INLINE andRn3 #-}
50 {-# INLINE thenRn3 #-}
51 {-# INLINE returnRn3 #-}
52 #endif
53
54 initRn3 :: Rn3M a -> SplitUniqSupply -> a
55
56 initRn3 m us = m (emptyFM,emptySet) (panic "initRn3: uninitialised module name") us
57
58 thenRn3 :: Rn3M a -> (a -> Rn3M b) -> Rn3M b
59 andRn3  :: (a -> a -> a) -> Rn3M a -> Rn3M a -> Rn3M a
60
61 thenRn3 expr continuation exps mod_name uniqs
62   = case splitUniqSupply uniqs      of { (s1, s2) ->
63     case (expr exps mod_name s1)    of { res1 ->
64     continuation res1 exps mod_name s2 }}
65
66 andRn3 combiner m1 m2 exps mod_name uniqs
67   = case splitUniqSupply uniqs      of { (s1, s2) ->
68     case (m1 exps mod_name s1)      of { res1 ->
69     case (m2 exps mod_name s2)      of { res2 ->
70     combiner res1 res2 }}}
71
72 returnRn3 :: a -> Rn3M a
73 returnRn3 result exps mod_name uniqs = result
74
75 mapRn3 :: (a -> Rn3M b) -> [a] -> Rn3M [b]
76
77 mapRn3 f []     = returnRn3 []
78 mapRn3 f (x:xs)
79   = f x         `thenRn3` \ r ->
80     mapRn3 f xs `thenRn3` \ rs ->
81     returnRn3 (r:rs)
82
83 fixRn3 :: (a -> Rn3M a) -> Rn3M a
84
85 fixRn3 m exps mod_name us
86   = result
87   where
88     result = m result exps mod_name us
89
90 putInfoDownM3 :: FAST_STRING{-ModuleName-} -> [IE] -> Rn3M a -> Rn3M a
91
92 putInfoDownM3 mod_name exports cont _ _ uniqs
93   = cont (getIEStrings exports) mod_name uniqs
94 \end{code}
95
96 %************************************************************************
97 %*                                                                      *
98 \subsection[RenameMonad3-new-names]{Making new names}
99 %*                                                                      *
100 %************************************************************************
101
102 @newFullNameM3@ makes a new user-visible FullName (the usual);
103 @newInvisibleNameM3@ is the odd case.  @new_name@ does all the work.
104
105 \begin{code}
106 newFullNameM3, newInvisibleNameM3
107         :: ProtoName            -- input
108         -> SrcLoc               -- where it started life
109         -> Bool                 -- if it is "TyCon"ish (rather than "val"ish)
110         -> Maybe ExportFlag     -- Just flag => force the use of that exportness
111         -> Rn3M (Unique, FullName)
112
113 newFullNameM3 pn src_loc is_tycon_ish frcd_exp exps mod_name uniqs
114   = new_name pn src_loc is_tycon_ish frcd_exp False{-visible-} exps mod_name uniqs
115
116 newInvisibleNameM3 pn src_loc is_tycon_ish frcd_exp exps mod_name uniqs
117   = new_name pn src_loc is_tycon_ish frcd_exp True{-invisible-} exps mod_name uniqs
118 \end{code}
119
120 \begin{code}
121 new_name pn src_loc is_tycon_ish frcd_export_flag want_invisible exps mod_name uniqs
122   = (uniq, name)
123   where
124     uniq = getSUnique uniqs
125
126     mk_name = if want_invisible then mkPrivateFullName else mkFullName
127
128     name = case pn of
129
130         Unk s     -> mk_name mod_name s
131                         (if fromPrelude mod_name
132                            && is_tycon_ish then -- & tycon/clas/datacon => Core
133                             HereInPreludeCore
134                          else
135                             ThisModule
136                         )
137                         (case frcd_export_flag of
138                            Just fl -> fl
139                            Nothing -> mk_export_flag True [mod_name] s exps)
140                         src_loc
141
142         -- note: the assigning of prelude-ness is most dubious (ToDo)
143
144         Imp m d informant_mods l
145           -> mk_name m d
146                (if fromPrelude m then   -- as above
147                    if is_tycon_ish then
148                        ExportedByPreludeCore
149                    else
150                        OtherPrelude l
151                 else if m == mod_name then -- pretty dang weird... (ToDo: anything?)
152                    ThisModule
153                 else
154                    OtherModule l informant_mods -- for Other*, we save its occurrence name
155                )
156                (case frcd_export_flag of
157                   Just fl -> fl
158                   Nothing -> mk_export_flag (m==mod_name) informant_mods l exps)
159                src_loc
160
161         Prel n    -> panic "RenameMonad3.new_name: prelude name"
162 \end{code}
163
164 In deciding the ``exportness'' of something, there are these cases to
165 consider:
166 \begin{description}
167 \item[No explicit export list:]
168 Everything defined in this module goes out.
169
170 \item[Matches a non-\tr{M..} item in the export list:]
171 Then it's exported as its @name_pr@ item suggests.
172
173 \item[Matches a \tr{M..} item in the export list:]
174
175 (Note: the module \tr{M} may be {\em this} module!)  It's exported if
176 we got it from \tr{M}'s interface; {\em most emphatically not} the
177 same thing as ``it originally came from \tr{M}''.
178
179 \item[Otherwise:]
180 It isn't exported.
181 \end{description}
182
183 \begin{code}
184 mk_export_flag  :: Bool         -- True <=> originally from the module we're compiling
185                 -> [FAST_STRING] -- modules that told us about this thing
186                 -> FAST_STRING  -- name of the thing we're looking at
187                 -> ImExportListInfo
188                 -> ExportFlag   -- result
189
190 mk_export_flag this_module informant_mods thing (exports_alist, dotdot_modules)
191   | isEmptyFM exports_alist && isEmptySet dotdot_modules
192   = if this_module then ExportAll else NotExported
193
194   | otherwise
195   = case (lookupFM exports_alist thing) of
196       Just how_to_export -> how_to_export
197       Nothing            -> if (or [ im `elementOf` dotdot_modules | im <- informant_mods ])
198                             then ExportAll
199                             else NotExported
200 \end{code}