PageRenderTime 36ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/ghc-7.0.4/compiler/basicTypes/VarEnv.lhs

http://picorec.googlecode.com/
Haskell | 429 lines | 283 code | 60 blank | 86 comment | 5 complexity | 42c030b65e2b52013ff5388d2148a3b8 MD5 | raw file
Possible License(s): BSD-3-Clause, BSD-2-Clause
  1. %
  2. % (c) The University of Glasgow 2006
  3. % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
  4. %
  5. \begin{code}
  6. module VarEnv (
  7. -- * Var, Id and TyVar environments (maps)
  8. VarEnv, IdEnv, TyVarEnv,
  9. -- ** Manipulating these environments
  10. emptyVarEnv, unitVarEnv, mkVarEnv,
  11. elemVarEnv, varEnvElts, varEnvKeys,
  12. extendVarEnv, extendVarEnv_C, extendVarEnv_Acc, extendVarEnvList,
  13. plusVarEnv, plusVarEnv_C,
  14. delVarEnvList, delVarEnv,
  15. minusVarEnv, intersectsVarEnv,
  16. lookupVarEnv, lookupVarEnv_NF, lookupWithDefaultVarEnv,
  17. mapVarEnv, zipVarEnv,
  18. modifyVarEnv, modifyVarEnv_Directly,
  19. isEmptyVarEnv, foldVarEnv,
  20. elemVarEnvByKey, lookupVarEnv_Directly,
  21. filterVarEnv_Directly, restrictVarEnv,
  22. -- * The InScopeSet type
  23. InScopeSet,
  24. -- ** Operations on InScopeSets
  25. emptyInScopeSet, mkInScopeSet, delInScopeSet,
  26. extendInScopeSet, extendInScopeSetList, extendInScopeSetSet,
  27. getInScopeVars, lookupInScope, lookupInScope_Directly,
  28. unionInScope, elemInScopeSet, uniqAway,
  29. -- * The RnEnv2 type
  30. RnEnv2,
  31. -- ** Operations on RnEnv2s
  32. mkRnEnv2, rnBndr2, rnBndrs2, rnOccL, rnOccR, inRnEnvL, inRnEnvR,
  33. rnBndrL, rnBndrR, nukeRnEnvL, nukeRnEnvR,
  34. addRnInScopeSet,
  35. rnEtaL, rnEtaR,
  36. rnInScope, rnInScopeSet, lookupRnInScope,
  37. -- * TidyEnv and its operation
  38. TidyEnv,
  39. emptyTidyEnv
  40. ) where
  41. import OccName
  42. import Var
  43. import VarSet
  44. import UniqFM
  45. import Unique
  46. import Util
  47. import Maybes
  48. import Outputable
  49. import FastTypes
  50. import StaticFlags
  51. import FastString
  52. \end{code}
  53. %************************************************************************
  54. %* *
  55. In-scope sets
  56. %* *
  57. %************************************************************************
  58. \begin{code}
  59. -- | A set of variables that are in scope at some point
  60. data InScopeSet = InScope (VarEnv Var) FastInt
  61. -- The (VarEnv Var) is just a VarSet. But we write it like
  62. -- this to remind ourselves that you can look up a Var in
  63. -- the InScopeSet. Typically the InScopeSet contains the
  64. -- canonical version of the variable (e.g. with an informative
  65. -- unfolding), so this lookup is useful.
  66. --
  67. -- INVARIANT: the VarEnv maps (the Unique of) a variable to
  68. -- a variable with the same Uniqua. (This was not
  69. -- the case in the past, when we had a grevious hack
  70. -- mapping var1 to var2.
  71. --
  72. -- The FastInt is a kind of hash-value used by uniqAway
  73. -- For example, it might be the size of the set
  74. -- INVARIANT: it's not zero; we use it as a multiplier in uniqAway
  75. instance Outputable InScopeSet where
  76. ppr (InScope s _) = ptext (sLit "InScope") <+> ppr s
  77. emptyInScopeSet :: InScopeSet
  78. emptyInScopeSet = InScope emptyVarSet (_ILIT(1))
  79. getInScopeVars :: InScopeSet -> VarEnv Var
  80. getInScopeVars (InScope vs _) = vs
  81. mkInScopeSet :: VarEnv Var -> InScopeSet
  82. mkInScopeSet in_scope = InScope in_scope (_ILIT(1))
  83. extendInScopeSet :: InScopeSet -> Var -> InScopeSet
  84. extendInScopeSet (InScope in_scope n) v = InScope (extendVarEnv in_scope v v) (n +# _ILIT(1))
  85. extendInScopeSetList :: InScopeSet -> [Var] -> InScopeSet
  86. extendInScopeSetList (InScope in_scope n) vs
  87. = InScope (foldl (\s v -> extendVarEnv s v v) in_scope vs)
  88. (n +# iUnbox (length vs))
  89. extendInScopeSetSet :: InScopeSet -> VarEnv Var -> InScopeSet
  90. extendInScopeSetSet (InScope in_scope n) vs
  91. = InScope (in_scope `plusVarEnv` vs) (n +# iUnbox (sizeUFM vs))
  92. delInScopeSet :: InScopeSet -> Var -> InScopeSet
  93. delInScopeSet (InScope in_scope n) v = InScope (in_scope `delVarEnv` v) n
  94. elemInScopeSet :: Var -> InScopeSet -> Bool
  95. elemInScopeSet v (InScope in_scope _) = v `elemVarEnv` in_scope
  96. -- | Look up a variable the 'InScopeSet'. This lets you map from
  97. -- the variable's identity (unique) to its full value.
  98. lookupInScope :: InScopeSet -> Var -> Maybe Var
  99. lookupInScope (InScope in_scope _) v = lookupVarEnv in_scope v
  100. lookupInScope_Directly :: InScopeSet -> Unique -> Maybe Var
  101. lookupInScope_Directly (InScope in_scope _) uniq
  102. = lookupVarEnv_Directly in_scope uniq
  103. unionInScope :: InScopeSet -> InScopeSet -> InScopeSet
  104. unionInScope (InScope s1 _) (InScope s2 n2)
  105. = InScope (s1 `plusVarEnv` s2) n2
  106. \end{code}
  107. \begin{code}
  108. -- | @uniqAway in_scope v@ finds a unique that is not used in the
  109. -- in-scope set, and gives that to v.
  110. uniqAway :: InScopeSet -> Var -> Var
  111. -- It starts with v's current unique, of course, in the hope that it won't
  112. -- have to change, and thereafter uses a combination of that and the hash-code
  113. -- found in the in-scope set
  114. uniqAway in_scope var
  115. | var `elemInScopeSet` in_scope = uniqAway' in_scope var -- Make a new one
  116. | otherwise = var -- Nothing to do
  117. uniqAway' :: InScopeSet -> Var -> Var
  118. -- This one *always* makes up a new variable
  119. uniqAway' (InScope set n) var
  120. = try (_ILIT(1))
  121. where
  122. orig_unique = getUnique var
  123. try k
  124. | debugIsOn && (k ># _ILIT(1000))
  125. = pprPanic "uniqAway loop:" (ppr (iBox k) <+> text "tries" <+> ppr var <+> int (iBox n))
  126. | uniq `elemVarSetByKey` set = try (k +# _ILIT(1))
  127. | debugIsOn && opt_PprStyle_Debug && (k ># _ILIT(3))
  128. = pprTrace "uniqAway:" (ppr (iBox k) <+> text "tries" <+> ppr var <+> int (iBox n))
  129. setVarUnique var uniq
  130. | otherwise = setVarUnique var uniq
  131. where
  132. uniq = deriveUnique orig_unique (iBox (n *# k))
  133. \end{code}
  134. %************************************************************************
  135. %* *
  136. Dual renaming
  137. %* *
  138. %************************************************************************
  139. \begin{code}
  140. -- | When we are comparing (or matching) types or terms, we are faced with
  141. -- \"going under\" corresponding binders. E.g. when comparing:
  142. --
  143. -- > \x. e1 ~ \y. e2
  144. --
  145. -- Basically we want to rename [@x@ -> @y@] or [@y@ -> @x@], but there are lots of
  146. -- things we must be careful of. In particular, @x@ might be free in @e2@, or
  147. -- y in @e1@. So the idea is that we come up with a fresh binder that is free
  148. -- in neither, and rename @x@ and @y@ respectively. That means we must maintain:
  149. --
  150. -- 1. A renaming for the left-hand expression
  151. --
  152. -- 2. A renaming for the right-hand expressions
  153. --
  154. -- 3. An in-scope set
  155. --
  156. -- Furthermore, when matching, we want to be able to have an 'occurs check',
  157. -- to prevent:
  158. --
  159. -- > \x. f ~ \y. y
  160. --
  161. -- matching with [@f@ -> @y@]. So for each expression we want to know that set of
  162. -- locally-bound variables. That is precisely the domain of the mappings 1.
  163. -- and 2., but we must ensure that we always extend the mappings as we go in.
  164. --
  165. -- All of this information is bundled up in the 'RnEnv2'
  166. data RnEnv2
  167. = RV2 { envL :: VarEnv Var -- Renaming for Left term
  168. , envR :: VarEnv Var -- Renaming for Right term
  169. , in_scope :: InScopeSet } -- In scope in left or right terms
  170. -- The renamings envL and envR are *guaranteed* to contain a binding
  171. -- for every variable bound as we go into the term, even if it is not
  172. -- renamed. That way we can ask what variables are locally bound
  173. -- (inRnEnvL, inRnEnvR)
  174. mkRnEnv2 :: InScopeSet -> RnEnv2
  175. mkRnEnv2 vars = RV2 { envL = emptyVarEnv
  176. , envR = emptyVarEnv
  177. , in_scope = vars }
  178. addRnInScopeSet :: RnEnv2 -> VarEnv Var -> RnEnv2
  179. addRnInScopeSet env vs
  180. | isEmptyVarEnv vs = env
  181. | otherwise = env { in_scope = extendInScopeSetSet (in_scope env) vs }
  182. rnInScope :: Var -> RnEnv2 -> Bool
  183. rnInScope x env = x `elemInScopeSet` in_scope env
  184. rnInScopeSet :: RnEnv2 -> InScopeSet
  185. rnInScopeSet = in_scope
  186. rnBndrs2 :: RnEnv2 -> [Var] -> [Var] -> RnEnv2
  187. -- ^ Applies 'rnBndr2' to several variables: the two variable lists must be of equal length
  188. rnBndrs2 env bsL bsR = foldl2 rnBndr2 env bsL bsR
  189. rnBndr2 :: RnEnv2 -> Var -> Var -> RnEnv2
  190. -- ^ @rnBndr2 env bL bR@ goes under a binder @bL@ in the Left term,
  191. -- and binder @bR@ in the Right term.
  192. -- It finds a new binder, @new_b@,
  193. -- and returns an environment mapping @bL -> new_b@ and @bR -> new_b@
  194. rnBndr2 (RV2 { envL = envL, envR = envR, in_scope = in_scope }) bL bR
  195. = RV2 { envL = extendVarEnv envL bL new_b -- See Note
  196. , envR = extendVarEnv envR bR new_b -- [Rebinding]
  197. , in_scope = extendInScopeSet in_scope new_b }
  198. where
  199. -- Find a new binder not in scope in either term
  200. new_b | not (bL `elemInScopeSet` in_scope) = bL
  201. | not (bR `elemInScopeSet` in_scope) = bR
  202. | otherwise = uniqAway' in_scope bL
  203. -- Note [Rebinding]
  204. -- If the new var is the same as the old one, note that
  205. -- the extendVarEnv *deletes* any current renaming
  206. -- E.g. (\x. \x. ...) ~ (\y. \z. ...)
  207. --
  208. -- Inside \x \y { [x->y], [y->y], {y} }
  209. -- \x \z { [x->x], [y->y, z->x], {y,x} }
  210. rnBndrL :: RnEnv2 -> Var -> (RnEnv2, Var)
  211. -- ^ Similar to 'rnBndr2' but used when there's a binder on the left
  212. -- side only.
  213. rnBndrL (RV2 { envL = envL, envR = envR, in_scope = in_scope }) bL
  214. = (RV2 { envL = extendVarEnv envL bL new_b
  215. , envR = envR
  216. , in_scope = extendInScopeSet in_scope new_b }, new_b)
  217. where
  218. new_b = uniqAway in_scope bL
  219. rnBndrR :: RnEnv2 -> Var -> (RnEnv2, Var)
  220. -- ^ Similar to 'rnBndr2' but used when there's a binder on the right
  221. -- side only.
  222. rnBndrR (RV2 { envL = envL, envR = envR, in_scope = in_scope }) bR
  223. = (RV2 { envR = extendVarEnv envR bR new_b
  224. , envL = envL
  225. , in_scope = extendInScopeSet in_scope new_b }, new_b)
  226. where
  227. new_b = uniqAway in_scope bR
  228. rnEtaL :: RnEnv2 -> Var -> (RnEnv2, Var)
  229. -- ^ Similar to 'rnBndrL' but used for eta expansion
  230. -- See Note [Eta expansion]
  231. rnEtaL (RV2 { envL = envL, envR = envR, in_scope = in_scope }) bL
  232. = (RV2 { envL = extendVarEnv envL bL new_b
  233. , envR = extendVarEnv envR new_b new_b -- Note [Eta expansion]
  234. , in_scope = extendInScopeSet in_scope new_b }, new_b)
  235. where
  236. new_b = uniqAway in_scope bL
  237. rnEtaR :: RnEnv2 -> Var -> (RnEnv2, Var)
  238. -- ^ Similar to 'rnBndr2' but used for eta expansion
  239. -- See Note [Eta expansion]
  240. rnEtaR (RV2 { envL = envL, envR = envR, in_scope = in_scope }) bR
  241. = (RV2 { envL = extendVarEnv envL new_b new_b -- Note [Eta expansion]
  242. , envR = extendVarEnv envR bR new_b
  243. , in_scope = extendInScopeSet in_scope new_b }, new_b)
  244. where
  245. new_b = uniqAway in_scope bR
  246. rnOccL, rnOccR :: RnEnv2 -> Var -> Var
  247. -- ^ Look up the renaming of an occurrence in the left or right term
  248. rnOccL (RV2 { envL = env }) v = lookupVarEnv env v `orElse` v
  249. rnOccR (RV2 { envR = env }) v = lookupVarEnv env v `orElse` v
  250. inRnEnvL, inRnEnvR :: RnEnv2 -> Var -> Bool
  251. -- ^ Tells whether a variable is locally bound
  252. inRnEnvL (RV2 { envL = env }) v = v `elemVarEnv` env
  253. inRnEnvR (RV2 { envR = env }) v = v `elemVarEnv` env
  254. lookupRnInScope :: RnEnv2 -> Var -> Var
  255. lookupRnInScope env v = lookupInScope (in_scope env) v `orElse` v
  256. nukeRnEnvL, nukeRnEnvR :: RnEnv2 -> RnEnv2
  257. -- ^ Wipe the left or right side renaming
  258. nukeRnEnvL env = env { envL = emptyVarEnv }
  259. nukeRnEnvR env = env { envR = emptyVarEnv }
  260. \end{code}
  261. Note [Eta expansion]
  262. ~~~~~~~~~~~~~~~~~~~~
  263. When matching
  264. (\x.M) ~ N
  265. we rename x to x' with, where x' is not in scope in
  266. either term. Then we want to behave as if we'd seen
  267. (\x'.M) ~ (\x'.N x')
  268. Since x' isn't in scope in N, the form (\x'. N x') doesn't
  269. capture any variables in N. But we must nevertheless extend
  270. the envR with a binding [x' -> x'], to support the occurs check.
  271. For example, if we don't do this, we can get silly matches like
  272. forall a. (\y.a) ~ v
  273. succeeding with [a -> v y], which is bogus of course.
  274. %************************************************************************
  275. %* *
  276. Tidying
  277. %* *
  278. %************************************************************************
  279. \begin{code}
  280. -- | When tidying up print names, we keep a mapping of in-scope occ-names
  281. -- (the 'TidyOccEnv') and a Var-to-Var of the current renamings
  282. type TidyEnv = (TidyOccEnv, VarEnv Var)
  283. emptyTidyEnv :: TidyEnv
  284. emptyTidyEnv = (emptyTidyOccEnv, emptyVarEnv)
  285. \end{code}
  286. %************************************************************************
  287. %* *
  288. \subsection{@VarEnv@s}
  289. %* *
  290. %************************************************************************
  291. \begin{code}
  292. type VarEnv elt = UniqFM elt
  293. type IdEnv elt = VarEnv elt
  294. type TyVarEnv elt = VarEnv elt
  295. emptyVarEnv :: VarEnv a
  296. mkVarEnv :: [(Var, a)] -> VarEnv a
  297. zipVarEnv :: [Var] -> [a] -> VarEnv a
  298. unitVarEnv :: Var -> a -> VarEnv a
  299. extendVarEnv :: VarEnv a -> Var -> a -> VarEnv a
  300. extendVarEnv_C :: (a->a->a) -> VarEnv a -> Var -> a -> VarEnv a
  301. extendVarEnv_Acc :: (a->b->b) -> (a->b) -> VarEnv b -> Var -> a -> VarEnv b
  302. plusVarEnv :: VarEnv a -> VarEnv a -> VarEnv a
  303. extendVarEnvList :: VarEnv a -> [(Var, a)] -> VarEnv a
  304. lookupVarEnv_Directly :: VarEnv a -> Unique -> Maybe a
  305. filterVarEnv_Directly :: (Unique -> a -> Bool) -> VarEnv a -> VarEnv a
  306. restrictVarEnv :: VarEnv a -> VarSet -> VarEnv a
  307. delVarEnvList :: VarEnv a -> [Var] -> VarEnv a
  308. delVarEnv :: VarEnv a -> Var -> VarEnv a
  309. minusVarEnv :: VarEnv a -> VarEnv a -> VarEnv a
  310. intersectsVarEnv :: VarEnv a -> VarEnv a -> Bool
  311. plusVarEnv_C :: (a -> a -> a) -> VarEnv a -> VarEnv a -> VarEnv a
  312. mapVarEnv :: (a -> b) -> VarEnv a -> VarEnv b
  313. modifyVarEnv :: (a -> a) -> VarEnv a -> Var -> VarEnv a
  314. varEnvElts :: VarEnv a -> [a]
  315. varEnvKeys :: VarEnv a -> [Unique]
  316. isEmptyVarEnv :: VarEnv a -> Bool
  317. lookupVarEnv :: VarEnv a -> Var -> Maybe a
  318. lookupVarEnv_NF :: VarEnv a -> Var -> a
  319. lookupWithDefaultVarEnv :: VarEnv a -> a -> Var -> a
  320. elemVarEnv :: Var -> VarEnv a -> Bool
  321. elemVarEnvByKey :: Unique -> VarEnv a -> Bool
  322. foldVarEnv :: (a -> b -> b) -> b -> VarEnv a -> b
  323. \end{code}
  324. \begin{code}
  325. elemVarEnv = elemUFM
  326. elemVarEnvByKey = elemUFM_Directly
  327. extendVarEnv = addToUFM
  328. extendVarEnv_C = addToUFM_C
  329. extendVarEnv_Acc = addToUFM_Acc
  330. extendVarEnvList = addListToUFM
  331. plusVarEnv_C = plusUFM_C
  332. delVarEnvList = delListFromUFM
  333. delVarEnv = delFromUFM
  334. minusVarEnv = minusUFM
  335. intersectsVarEnv e1 e2 = not (isEmptyVarEnv (e1 `intersectUFM` e2))
  336. plusVarEnv = plusUFM
  337. lookupVarEnv = lookupUFM
  338. lookupWithDefaultVarEnv = lookupWithDefaultUFM
  339. mapVarEnv = mapUFM
  340. mkVarEnv = listToUFM
  341. emptyVarEnv = emptyUFM
  342. varEnvElts = eltsUFM
  343. varEnvKeys = keysUFM
  344. unitVarEnv = unitUFM
  345. isEmptyVarEnv = isNullUFM
  346. foldVarEnv = foldUFM
  347. lookupVarEnv_Directly = lookupUFM_Directly
  348. filterVarEnv_Directly = filterUFM_Directly
  349. restrictVarEnv env vs = filterVarEnv_Directly keep env
  350. where
  351. keep u _ = u `elemVarSetByKey` vs
  352. zipVarEnv tyvars tys = mkVarEnv (zipEqual "zipVarEnv" tyvars tys)
  353. lookupVarEnv_NF env id = case lookupVarEnv env id of
  354. Just xx -> xx
  355. Nothing -> panic "lookupVarEnv_NF: Nothing"
  356. \end{code}
  357. @modifyVarEnv@: Look up a thing in the VarEnv,
  358. then mash it with the modify function, and put it back.
  359. \begin{code}
  360. modifyVarEnv mangle_fn env key
  361. = case (lookupVarEnv env key) of
  362. Nothing -> env
  363. Just xx -> extendVarEnv env key (mangle_fn xx)
  364. modifyVarEnv_Directly :: (a -> a) -> UniqFM a -> Unique -> UniqFM a
  365. modifyVarEnv_Directly mangle_fn env key
  366. = case (lookupUFM_Directly env key) of
  367. Nothing -> env
  368. Just xx -> addToUFM_Directly env key (mangle_fn xx)
  369. \end{code}