2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1995
4 \section[DesugarMonad]{@DesugarMonad@: monadery used in desugaring}
7 #include "HsVersions.h"
11 initDs, returnDs, thenDs, andDs, mapDs, listDs,
12 mapAndUnzipDs, zipWithDs,
14 newTyVarsDs, cloneTyVarsDs,
15 duplicateLocalDs, newSysLocalDs, newSysLocalsDs,
17 getSrcLocDs, putSrcLocDs,
18 getSwitchCheckerDs, ifSwitchSetDs,
20 extendEnvDs, lookupEnvDs, lookupEnvWithDefaultDs,
25 DsMatchContext(..), DsMatchKind(..), pprDsWarnings,
31 -- and to make the interface self-sufficient...
32 Id, DataCon(..), SrcLoc, TyVar, TyVarTemplate, UniType, TauType(..),
33 ThetaType(..), SigmaType(..), SplitUniqSupply, UniqSM(..),
34 PlainCoreExpr(..), CoreExpr, GlobalSwitch, SwitchResult
36 IF_ATTACK_PRAGMAS(COMMA lookupUFM COMMA lookupIdEnv)
37 IF_ATTACK_PRAGMAS(COMMA mkIdWithNewUniq COMMA mkSysLocal)
38 IF_ATTACK_PRAGMAS(COMMA unpackSrcLoc COMMA mkUniqueSupplyGrimily)
39 IF_ATTACK_PRAGMAS(COMMA mkUniqueGrimily)
40 IF_ATTACK_PRAGMAS(COMMA splitUniqSupply COMMA getSUnique)
44 import AbsUniType ( cloneTyVarFromTemplate, cloneTyVar,
45 TyVar, TyVarTemplate, UniType, TauType(..),
46 ThetaType(..), SigmaType(..), Class
47 IF_ATTACK_PRAGMAS(COMMA cmpTyVar)
50 import CmdLineOpts -- ( GlobalSwitch(..), SwitchResult(..), switchIsOn )
51 import Id ( mkIdWithNewUniq, mkSysLocal, Id, DataCon(..) )
52 import IdEnv -- ( mkIdEnv, IdEnv )
53 import Maybes ( assocMaybe, Maybe(..) )
57 import SrcLoc ( unpackSrcLoc, mkUnknownSrcLoc, SrcLoc )
58 import TyVarEnv -- ( nullTyVarEnv, TyVarEnv )
66 Now the mondo monad magic (yes, @DsM@ is a silly name)---carry around
67 a @UniqueSupply@ and some annotations, which
68 presumably include source-file location information:
72 -> SrcLoc -- to put in pattern-matching error msgs
73 -> (GlobalSwitch -> SwitchResult) -- so we can consult global switches
74 -> (FAST_STRING, FAST_STRING) -- "module"+"group" : for SCC profiling
77 -> (result, DsWarnings)
79 type DsWarnings = Bag DsMatchContext -- The desugarer reports matches which are
80 -- completely shadowed
82 #ifdef __GLASGOW_HASKELL__
85 {-# INLINE returnDs #-}
88 -- initDs returns the UniqSupply out the end (not just the result)
90 initDs :: SplitUniqSupply
92 -> (GlobalSwitch -> SwitchResult)
93 -> FAST_STRING -- module name: for profiling; (group name: from switches)
97 initDs init_us env sw_chkr mod_name action
98 = action init_us mkUnknownSrcLoc sw_chkr module_and_group env emptyBag
100 module_and_group = (mod_name, grp_name)
101 grp_name = case (stringSwitchSet sw_chkr SccGroup) of
103 Nothing -> mod_name -- default: module name
105 thenDs :: DsM a -> (a -> DsM b) -> DsM b
106 andDs :: (a -> a -> a) -> DsM a -> DsM a -> DsM a
108 thenDs expr cont us loc sw_chkr mod_and_grp env warns
109 = case splitUniqSupply us of { (s1, s2) ->
110 case (expr s1 loc sw_chkr mod_and_grp env warns) of { (result, warns1) ->
111 cont result s2 loc sw_chkr mod_and_grp env warns1}}
113 andDs combiner m1 m2 us loc sw_chkr mod_and_grp env warns
114 = case splitUniqSupply us of { (s1, s2) ->
115 case (m1 s1 loc sw_chkr mod_and_grp env warns) of { (result1, warns1) ->
116 case (m2 s2 loc sw_chkr mod_and_grp env warns1) of { (result2, warns2) ->
117 (combiner result1 result2, warns2) }}}
119 returnDs :: a -> DsM a
120 returnDs result us loc sw_chkr mod_and_grp env warns = (result, warns)
122 listDs :: [DsM a] -> DsM [a]
123 listDs [] = returnDs []
126 listDs xs `thenDs` \ rs ->
129 mapDs :: (a -> DsM b) -> [a] -> DsM [b]
131 mapDs f [] = returnDs []
133 = f x `thenDs` \ r ->
134 mapDs f xs `thenDs` \ rs ->
137 mapAndUnzipDs :: (a -> DsM (b, c)) -> [a] -> DsM ([b], [c])
139 mapAndUnzipDs f [] = returnDs ([], [])
140 mapAndUnzipDs f (x:xs)
141 = f x `thenDs` \ (r1, r2) ->
142 mapAndUnzipDs f xs `thenDs` \ (rs1, rs2) ->
143 returnDs (r1:rs1, r2:rs2)
145 zipWithDs :: (a -> b -> DsM c) -> [a] -> [b] -> DsM [c]
147 zipWithDs f [] [] = returnDs []
148 zipWithDs f (x:xs) (y:ys)
149 = f x y `thenDs` \ r ->
150 zipWithDs f xs ys `thenDs` \ rs ->
154 And all this mysterious stuff is so we can occasionally reach out and
155 grab one or more names. @newLocalDs@ isn't exported---exported
156 functions are defined with it. The difference in name-strings makes
157 it easier to read debugging output.
159 newLocalDs :: FAST_STRING -> UniType -> DsM Id
160 newLocalDs nm ty us loc sw_chkr mod_and_grp env warns
161 = case (getSUnique us) of { assigned_uniq ->
162 (mkSysLocal nm assigned_uniq ty loc, warns) }
164 newSysLocalDs = newLocalDs SLIT("ds")
165 newSysLocalsDs tys = mapDs (newLocalDs SLIT("ds")) tys
166 newFailLocalDs = newLocalDs SLIT("fail")
168 duplicateLocalDs :: Id -> DsM Id
169 duplicateLocalDs old_local us loc sw_chkr mod_and_grp env warns
170 = case (getSUnique us) of { assigned_uniq ->
171 (mkIdWithNewUniq old_local assigned_uniq, warns) }
173 cloneTyVarsDs :: [TyVar] -> DsM [TyVar]
174 cloneTyVarsDs tyvars us loc sw_chkr mod_and_grp env warns
175 = case (getSUniques (length tyvars) us) of { uniqs ->
176 (zipWith cloneTyVar tyvars uniqs, warns) }
180 newTyVarsDs :: [TyVarTemplate] -> DsM [TyVar]
182 newTyVarsDs tyvar_tmpls us loc sw_chkr mod_and_grp env warns
183 = case (getSUniques (length tyvar_tmpls) us) of { uniqs ->
184 (zipWith cloneTyVarFromTemplate tyvar_tmpls uniqs, warns) }
187 We can also reach out and either set/grab location information from
188 the @SrcLoc@ being carried around.
190 uniqSMtoDsM :: UniqSM a -> DsM a
192 uniqSMtoDsM u_action us loc sw_chkr mod_and_grp env warns
194 us_to_use = mkUniqueSupplyGrimily us
196 (snd (u_action us_to_use), warns)
198 getSrcLocDs :: DsM (String, String)
199 getSrcLocDs us loc sw_chkr mod_and_grp env warns
200 = case (unpackSrcLoc loc) of { (x,y) ->
201 ((_UNPK_ x, _UNPK_ y), warns) }
203 putSrcLocDs :: SrcLoc -> DsM a -> DsM a
204 putSrcLocDs new_loc expr us old_loc sw_chkr mod_and_grp env warns
205 = expr us new_loc sw_chkr mod_and_grp env warns
207 dsShadowError :: DsMatchContext -> DsM ()
208 dsShadowError cxt us loc sw_chkr mod_and_grp env warns
209 = ((), warns `snocBag` cxt)
213 getSwitchCheckerDs :: DsM (GlobalSwitch -> Bool)
214 getSwitchCheckerDs us loc sw_chkr mod_and_grp env warns
215 = (switchIsOn sw_chkr, warns)
217 ifSwitchSetDs :: GlobalSwitch -> DsM a -> DsM a -> DsM a
218 ifSwitchSetDs switch then_ else_ us loc sw_chkr mod_and_grp env warns
219 = (if switchIsOn sw_chkr switch then then_ else else_)
220 us loc sw_chkr mod_and_grp env warns
222 getModuleAndGroupDs :: DsM (FAST_STRING, FAST_STRING)
223 getModuleAndGroupDs us loc sw_chkr mod_and_grp env warns
224 = (mod_and_grp, warns)
228 type DsIdEnv = IdEnv PlainCoreExpr
230 extendEnvDs :: [(Id, PlainCoreExpr)] -> DsM a -> DsM a
232 extendEnvDs pairs expr us loc sw_chkr mod_and_grp old_env warns
233 = case splitUniqSupply us of { (s1, s2) ->
234 case (mapAccumL subst s1 pairs) of { (_, revised_pairs) ->
235 expr s2 loc sw_chkr mod_and_grp (growIdEnvList old_env revised_pairs) warns
239 = case splitUniqSupply us of { (s1, s2) ->
241 us_to_use = mkUniqueSupplyGrimily s1
243 case (substCoreExpr us_to_use old_env nullTyVarEnv expr) of { (_, expr2) ->
246 lookupEnvDs :: Id -> DsM (Maybe PlainCoreExpr)
247 lookupEnvDs id us loc sw_chkr mod_and_grp env warns
248 = (lookupIdEnv env id, warns)
249 -- Note: we don't assert anything about the Id
250 -- being looked up. There's not really anything
251 -- much to say about it. (WDP 94/06)
253 lookupEnvWithDefaultDs :: Id -> PlainCoreExpr -> DsM PlainCoreExpr
254 lookupEnvWithDefaultDs id deflt us loc sw_chkr mod_and_grp env warns
255 = (case (lookupIdEnv env id) of
260 lookupId :: [(Id, a)] -> Id -> a
262 = assoc "lookupId" env id
265 %************************************************************************
267 %* type synonym EquationInfo and access functions for its pieces *
269 %************************************************************************
273 = DsMatchContext DsMatchKind [TypecheckedPat] SrcLoc
282 pprDsWarnings :: PprStyle -> Bag DsMatchContext -> Pretty
283 pprDsWarnings sty warns
284 = ppAboves (map pp_cxt (bagToList warns))
286 pp_cxt NoMatchContext = ppPStr SLIT("Some match is shadowed; I don't know what")
287 pp_cxt (DsMatchContext kind pats loc)
288 = ppHang (ppBesides [ppr PprForUser loc, ppPStr SLIT(": ")])
289 4 (ppHang (ppPStr SLIT("Pattern match(es) completely overlapped:"))
290 4 (pp_match kind pats))
292 pp_match (FunMatch fun) pats
293 = ppHang (ppr sty fun)
294 4 (ppSep [ppSep (map (ppr sty) pats), ppPStr SLIT("= ...")])
296 pp_match CaseMatch pats
297 = ppHang (ppPStr SLIT("in a case alternative:"))
298 4 (ppSep [ppSep (map (ppr sty) pats), pp_arrow_dotdotdot])
300 pp_match PatBindMatch pats
301 = ppHang (ppPStr SLIT("in a pattern binding:"))
302 4 (ppSep [ppSep (map (ppr sty) pats), pp_arrow_dotdotdot])
304 pp_match LambdaMatch pats
305 = ppHang (ppPStr SLIT("in a lambda abstraction:"))
306 4 (ppSep [ppSep (map (ppr sty) pats), pp_arrow_dotdotdot])
308 pp_arrow_dotdotdot = ppPStr SLIT("-> ...")