PageRenderTime 65ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/compiler/coreSyn/TrieMap.lhs

https://bitbucket.org/khibino/ghc-hack
Haskell | 613 lines | 485 code | 101 blank | 27 comment | 0 complexity | 8067a5a8eaf79fecbf40505063db0e2e MD5 | raw file
Possible License(s): BSD-3-Clause, BSD-2-Clause, LGPL-3.0
  1. %
  2. % (c) The University of Glasgow 2006
  3. % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
  4. %
  5. \begin{code}
  6. {-# OPTIONS -fno-warn-tabs #-}
  7. -- The above warning supression flag is a temporary kludge.
  8. -- While working on this module you are encouraged to remove it and
  9. -- detab the module (please do the detabbing in a separate patch). See
  10. -- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#TabsvsSpaces
  11. -- for details
  12. {-# LANGUAGE TypeFamilies #-}
  13. module TrieMap(
  14. CoreMap, emptyCoreMap, extendCoreMap, lookupCoreMap, foldCoreMap,
  15. TypeMap, foldTypeMap,
  16. CoercionMap,
  17. MaybeMap,
  18. ListMap,
  19. TrieMap(..)
  20. ) where
  21. import CoreSyn
  22. import Coercion
  23. import Literal
  24. import Name
  25. import Type
  26. import TypeRep
  27. import Var
  28. import UniqFM
  29. import Unique( Unique )
  30. import qualified Data.Map as Map
  31. import qualified Data.IntMap as IntMap
  32. import VarEnv
  33. import NameEnv
  34. import Outputable
  35. import Control.Monad( (>=>) )
  36. \end{code}
  37. This module implements TrieMaps, which are finite mappings
  38. whose key is a structured value like a CoreExpr or Type.
  39. The code is very regular and boilerplate-like, but there is
  40. some neat handling of *binders*. In effect they are deBruijn
  41. numbered on the fly.
  42. %************************************************************************
  43. %* *
  44. The TrieMap class
  45. %* *
  46. %************************************************************************
  47. \begin{code}
  48. type XT a = Maybe a -> Maybe a -- How to alter a non-existent elt (Nothing)
  49. -- or an existing elt (Just)
  50. class TrieMap m where
  51. type Key m :: *
  52. emptyTM :: m a
  53. lookupTM :: forall b. Key m -> m b -> Maybe b
  54. alterTM :: forall b. Key m -> XT b -> m b -> m b
  55. foldTM :: (a -> b -> b) -> m a -> b -> b
  56. -- The unusual argument order here makes
  57. -- it easy to compose calls to foldTM;
  58. -- see for example fdE below
  59. ----------------------
  60. -- Recall that
  61. -- Control.Monad.(>=>) :: (a -> Maybe b) -> (b -> Maybe c) -> a -> Maybe c
  62. (>.>) :: (a -> b) -> (b -> c) -> a -> c
  63. -- Reverse function composition (do f first, then g)
  64. infixr 1 >.>
  65. (f >.> g) x = g (f x)
  66. infixr 1 |>, |>>
  67. (|>) :: a -> (a->b) -> b -- Reverse application
  68. x |> f = f x
  69. ----------------------
  70. (|>>) :: TrieMap m2
  71. => (XT (m2 a) -> m1 (m2 a) -> m1 (m2 a))
  72. -> (m2 a -> m2 a)
  73. -> m1 (m2 a) -> m1 (m2 a)
  74. (|>>) f g = f (Just . g . deMaybe)
  75. deMaybe :: TrieMap m => Maybe (m a) -> m a
  76. deMaybe Nothing = emptyTM
  77. deMaybe (Just m) = m
  78. \end{code}
  79. %************************************************************************
  80. %* *
  81. IntMaps
  82. %* *
  83. %************************************************************************
  84. \begin{code}
  85. instance TrieMap IntMap.IntMap where
  86. type Key IntMap.IntMap = Int
  87. emptyTM = IntMap.empty
  88. lookupTM k m = IntMap.lookup k m
  89. alterTM = xtInt
  90. foldTM k m z = IntMap.fold k z m
  91. xtInt :: Int -> XT a -> IntMap.IntMap a -> IntMap.IntMap a
  92. xtInt k f m = IntMap.alter f k m
  93. instance Ord k => TrieMap (Map.Map k) where
  94. type Key (Map.Map k) = k
  95. emptyTM = Map.empty
  96. lookupTM = Map.lookup
  97. alterTM k f m = Map.alter f k m
  98. foldTM k m z = Map.fold k z m
  99. instance TrieMap UniqFM where
  100. type Key UniqFM = Unique
  101. emptyTM = emptyUFM
  102. lookupTM k m = lookupUFM m k
  103. alterTM k f m = alterUFM f m k
  104. foldTM k m z = foldUFM k z m
  105. \end{code}
  106. %************************************************************************
  107. %* *
  108. Lists
  109. %* *
  110. %************************************************************************
  111. If m is a map from k -> val
  112. then (MaybeMap m) is a map from (Maybe k) -> val
  113. \begin{code}
  114. data MaybeMap m a = MM { mm_nothing :: Maybe a, mm_just :: m a }
  115. instance TrieMap m => TrieMap (MaybeMap m) where
  116. type Key (MaybeMap m) = Maybe (Key m)
  117. emptyTM = MM { mm_nothing = Nothing, mm_just = emptyTM }
  118. lookupTM = lkMaybe lookupTM
  119. alterTM = xtMaybe alterTM
  120. foldTM = fdMaybe
  121. lkMaybe :: TrieMap m => (forall b. k -> m b -> Maybe b)
  122. -> Maybe k -> MaybeMap m a -> Maybe a
  123. lkMaybe _ Nothing = mm_nothing
  124. lkMaybe lk (Just x) = mm_just >.> lk x
  125. xtMaybe :: TrieMap m => (forall b. k -> XT b -> m b -> m b)
  126. -> Maybe k -> XT a -> MaybeMap m a -> MaybeMap m a
  127. xtMaybe _ Nothing f m = m { mm_nothing = f (mm_nothing m) }
  128. xtMaybe tr (Just x) f m = m { mm_just = mm_just m |> tr x f }
  129. fdMaybe :: TrieMap m => (a -> b -> b) -> MaybeMap m a -> b -> b
  130. fdMaybe k m = foldMaybe k (mm_nothing m)
  131. . foldTM k (mm_just m)
  132. --------------------
  133. data ListMap m a
  134. = LM { lm_nil :: Maybe a
  135. , lm_cons :: m (ListMap m a) }
  136. instance TrieMap m => TrieMap (ListMap m) where
  137. type Key (ListMap m) = [Key m]
  138. emptyTM = LM { lm_nil = Nothing, lm_cons = emptyTM }
  139. lookupTM = lkList lookupTM
  140. alterTM = xtList alterTM
  141. foldTM = fdList
  142. lkList :: TrieMap m => (forall b. k -> m b -> Maybe b)
  143. -> [k] -> ListMap m a -> Maybe a
  144. lkList _ [] = lm_nil
  145. lkList lk (x:xs) = lm_cons >.> lk x >=> lkList lk xs
  146. xtList :: TrieMap m => (forall b. k -> XT b -> m b -> m b)
  147. -> [k] -> XT a -> ListMap m a -> ListMap m a
  148. xtList _ [] f m = m { lm_nil = f (lm_nil m) }
  149. xtList tr (x:xs) f m = m { lm_cons = lm_cons m |> tr x |>> xtList tr xs f }
  150. fdList :: forall m a b. TrieMap m
  151. => (a -> b -> b) -> ListMap m a -> b -> b
  152. fdList k m = foldMaybe k (lm_nil m)
  153. . foldTM (fdList k) (lm_cons m)
  154. foldMaybe :: (a -> b -> b) -> Maybe a -> b -> b
  155. foldMaybe _ Nothing b = b
  156. foldMaybe k (Just a) b = k a b
  157. \end{code}
  158. %************************************************************************
  159. %* *
  160. Basic maps
  161. %* *
  162. %************************************************************************
  163. \begin{code}
  164. lkNamed :: NamedThing n => n -> NameEnv a -> Maybe a
  165. lkNamed n env = lookupNameEnv env (getName n)
  166. xtNamed :: NamedThing n => n -> XT a -> NameEnv a -> NameEnv a
  167. xtNamed tc f m = alterNameEnv f m (getName tc)
  168. ------------------------
  169. type LiteralMap a = Map.Map Literal a
  170. emptyLiteralMap :: LiteralMap a
  171. emptyLiteralMap = emptyTM
  172. lkLit :: Literal -> LiteralMap a -> Maybe a
  173. lkLit = lookupTM
  174. xtLit :: Literal -> XT a -> LiteralMap a -> LiteralMap a
  175. xtLit = alterTM
  176. \end{code}
  177. %************************************************************************
  178. %* *
  179. CoreMap
  180. %* *
  181. %************************************************************************
  182. Note [Binders]
  183. ~~~~~~~~~~~~~~
  184. * In general we check binders as late as possible because types are
  185. less likely to differ than expression structure. That's why
  186. cm_lam :: CoreMap (TypeMap a)
  187. rather than
  188. cm_lam :: TypeMap (CoreMap a)
  189. * We don't need to look at the type of some binders, notalby
  190. - the case binder in (Case _ b _ _)
  191. - the binders in an alternative
  192. because they are totally fixed by the context
  193. \begin{code}
  194. data CoreMap a
  195. = EmptyCM
  196. | CM { cm_var :: VarMap a
  197. , cm_lit :: LiteralMap a
  198. , cm_co :: CoercionMap a
  199. , cm_type :: TypeMap a
  200. , cm_cast :: CoreMap (CoercionMap a)
  201. , cm_source :: CoreMap (TickishMap a)
  202. , cm_app :: CoreMap (CoreMap a)
  203. , cm_lam :: CoreMap (TypeMap a)
  204. , cm_letn :: CoreMap (CoreMap (BndrMap a))
  205. , cm_letr :: ListMap CoreMap (CoreMap (ListMap BndrMap a))
  206. , cm_case :: CoreMap (ListMap AltMap a)
  207. -- Note [Binders]
  208. }
  209. wrapEmptyCM :: CoreMap a
  210. wrapEmptyCM = CM { cm_var = emptyTM, cm_lit = emptyLiteralMap
  211. , cm_co = emptyTM, cm_type = emptyTM
  212. , cm_cast = emptyTM, cm_app = emptyTM
  213. , cm_lam = emptyTM, cm_letn = emptyTM
  214. , cm_letr = emptyTM, cm_case = emptyTM
  215. , cm_source = emptyTM }
  216. instance TrieMap CoreMap where
  217. type Key CoreMap = CoreExpr
  218. emptyTM = EmptyCM
  219. lookupTM = lkE emptyCME
  220. alterTM = xtE emptyCME
  221. foldTM = fdE
  222. --------------------------
  223. lookupCoreMap :: CoreMap a -> CoreExpr -> Maybe a
  224. lookupCoreMap cm e = lkE emptyCME e cm
  225. extendCoreMap :: CoreMap a -> CoreExpr -> a -> CoreMap a
  226. extendCoreMap m e v = xtE emptyCME e (\_ -> Just v) m
  227. foldCoreMap :: (a -> b -> b) -> b -> CoreMap a -> b
  228. foldCoreMap k z m = fdE k m z
  229. emptyCoreMap :: CoreMap a
  230. emptyCoreMap = EmptyCM
  231. instance Outputable a => Outputable (CoreMap a) where
  232. ppr m = text "CoreMap elts" <+> ppr (foldCoreMap (:) [] m)
  233. -------------------------
  234. fdE :: (a -> b -> b) -> CoreMap a -> b -> b
  235. fdE _ EmptyCM = \z -> z
  236. fdE k m
  237. = foldTM k (cm_var m)
  238. . foldTM k (cm_lit m)
  239. . foldTM k (cm_co m)
  240. . foldTM k (cm_type m)
  241. . foldTM (foldTM k) (cm_cast m)
  242. . foldTM (foldTM k) (cm_source m)
  243. . foldTM (foldTM k) (cm_app m)
  244. . foldTM (foldTM k) (cm_lam m)
  245. . foldTM (foldTM (foldTM k)) (cm_letn m)
  246. . foldTM (foldTM (foldTM k)) (cm_letr m)
  247. . foldTM (foldTM k) (cm_case m)
  248. lkE :: CmEnv -> CoreExpr -> CoreMap a -> Maybe a
  249. -- lkE: lookup in trie for expressions
  250. lkE env expr cm
  251. | EmptyCM <- cm = Nothing
  252. | otherwise = go expr cm
  253. where
  254. go (Var v) = cm_var >.> lkVar env v
  255. go (Lit l) = cm_lit >.> lkLit l
  256. go (Type t) = cm_type >.> lkT env t
  257. go (Coercion c) = cm_co >.> lkC env c
  258. go (Cast e c) = cm_cast >.> lkE env e >=> lkC env c
  259. go (Tick tickish e) = cm_source >.> lkE env e >=> lkTickish tickish
  260. go (App e1 e2) = cm_app >.> lkE env e2 >=> lkE env e1
  261. go (Lam v e) = cm_lam >.> lkE (extendCME env v) e >=> lkBndr env v
  262. go (Let (NonRec b r) e) = cm_letn >.> lkE env r
  263. >=> lkE (extendCME env b) e >=> lkBndr env b
  264. go (Let (Rec prs) e) = let (bndrs,rhss) = unzip prs
  265. env1 = extendCMEs env bndrs
  266. in cm_letr
  267. >.> lkList (lkE env1) rhss >=> lkE env1 e
  268. >=> lkList (lkBndr env1) bndrs
  269. go (Case e b _ as) = cm_case >.> lkE env e
  270. >=> lkList (lkA (extendCME env b)) as
  271. xtE :: CmEnv -> CoreExpr -> XT a -> CoreMap a -> CoreMap a
  272. xtE env e f EmptyCM = xtE env e f wrapEmptyCM
  273. xtE env (Var v) f m = m { cm_var = cm_var m |> xtVar env v f }
  274. xtE env (Type t) f m = m { cm_type = cm_type m |> xtT env t f }
  275. xtE env (Coercion c) f m = m { cm_co = cm_co m |> xtC env c f }
  276. xtE _ (Lit l) f m = m { cm_lit = cm_lit m |> xtLit l f }
  277. xtE env (Cast e c) f m = m { cm_cast = cm_cast m |> xtE env e |>>
  278. xtC env c f }
  279. xtE env (Tick t e) f m = m { cm_source = cm_source m |> xtE env e |>> xtTickish t f }
  280. xtE env (App e1 e2) f m = m { cm_app = cm_app m |> xtE env e2 |>> xtE env e1 f }
  281. xtE env (Lam v e) f m = m { cm_lam = cm_lam m |> xtE (extendCME env v) e
  282. |>> xtBndr env v f }
  283. xtE env (Let (NonRec b r) e) f m = m { cm_letn = cm_letn m
  284. |> xtE (extendCME env b) e
  285. |>> xtE env r |>> xtBndr env b f }
  286. xtE env (Let (Rec prs) e) f m = m { cm_letr = let (bndrs,rhss) = unzip prs
  287. env1 = extendCMEs env bndrs
  288. in cm_letr m
  289. |> xtList (xtE env1) rhss
  290. |>> xtE env1 e
  291. |>> xtList (xtBndr env1) bndrs f }
  292. xtE env (Case e b _ as) f m = m { cm_case = cm_case m |> xtE env e
  293. |>> let env1 = extendCME env b
  294. in xtList (xtA env1) as f }
  295. type TickishMap a = Map.Map (Tickish Id) a
  296. lkTickish :: Tickish Id -> TickishMap a -> Maybe a
  297. lkTickish = lookupTM
  298. xtTickish :: Tickish Id -> XT a -> TickishMap a -> TickishMap a
  299. xtTickish = alterTM
  300. ------------------------
  301. data AltMap a -- A single alternative
  302. = AM { am_deflt :: CoreMap a
  303. , am_data :: NameEnv (CoreMap a)
  304. , am_lit :: LiteralMap (CoreMap a) }
  305. instance TrieMap AltMap where
  306. type Key AltMap = CoreAlt
  307. emptyTM = AM { am_deflt = emptyTM
  308. , am_data = emptyNameEnv
  309. , am_lit = emptyLiteralMap }
  310. lookupTM = lkA emptyCME
  311. alterTM = xtA emptyCME
  312. foldTM = fdA
  313. lkA :: CmEnv -> CoreAlt -> AltMap a -> Maybe a
  314. lkA env (DEFAULT, _, rhs) = am_deflt >.> lkE env rhs
  315. lkA env (LitAlt lit, _, rhs) = am_lit >.> lkLit lit >=> lkE env rhs
  316. lkA env (DataAlt dc, bs, rhs) = am_data >.> lkNamed dc >=> lkE (extendCMEs env bs) rhs
  317. xtA :: CmEnv -> CoreAlt -> XT a -> AltMap a -> AltMap a
  318. xtA env (DEFAULT, _, rhs) f m = m { am_deflt = am_deflt m |> xtE env rhs f }
  319. xtA env (LitAlt l, _, rhs) f m = m { am_lit = am_lit m |> xtLit l |>> xtE env rhs f }
  320. xtA env (DataAlt d, bs, rhs) f m = m { am_data = am_data m |> xtNamed d
  321. |>> xtE (extendCMEs env bs) rhs f }
  322. fdA :: (a -> b -> b) -> AltMap a -> b -> b
  323. fdA k m = foldTM k (am_deflt m)
  324. . foldTM (foldTM k) (am_data m)
  325. . foldTM (foldTM k) (am_lit m)
  326. \end{code}
  327. %************************************************************************
  328. %* *
  329. Coercions
  330. %* *
  331. %************************************************************************
  332. \begin{code}
  333. data CoercionMap a
  334. = EmptyKM
  335. | KM { km_refl :: TypeMap a
  336. , km_tc_app :: NameEnv (ListMap CoercionMap a)
  337. , km_app :: CoercionMap (CoercionMap a)
  338. , km_forall :: CoercionMap (TypeMap a)
  339. , km_var :: VarMap a
  340. , km_axiom :: NameEnv (ListMap CoercionMap a)
  341. , km_unsafe :: TypeMap (TypeMap a)
  342. , km_sym :: CoercionMap a
  343. , km_trans :: CoercionMap (CoercionMap a)
  344. , km_nth :: IntMap.IntMap (CoercionMap a)
  345. , km_inst :: CoercionMap (TypeMap a) }
  346. wrapEmptyKM :: CoercionMap a
  347. wrapEmptyKM = KM { km_refl = emptyTM, km_tc_app = emptyNameEnv
  348. , km_app = emptyTM, km_forall = emptyTM
  349. , km_var = emptyTM, km_axiom = emptyNameEnv
  350. , km_unsafe = emptyTM, km_sym = emptyTM, km_trans = emptyTM
  351. , km_nth = emptyTM, km_inst = emptyTM }
  352. instance TrieMap CoercionMap where
  353. type Key CoercionMap = Coercion
  354. emptyTM = EmptyKM
  355. lookupTM = lkC emptyCME
  356. alterTM = xtC emptyCME
  357. foldTM = fdC
  358. lkC :: CmEnv -> Coercion -> CoercionMap a -> Maybe a
  359. lkC env co m
  360. | EmptyKM <- m = Nothing
  361. | otherwise = go co m
  362. where
  363. go (Refl ty) = km_refl >.> lkT env ty
  364. go (TyConAppCo tc cs) = km_tc_app >.> lkNamed tc >=> lkList (lkC env) cs
  365. go (AxiomInstCo ax cs) = km_axiom >.> lkNamed ax >=> lkList (lkC env) cs
  366. go (AppCo c1 c2) = km_app >.> lkC env c1 >=> lkC env c2
  367. go (TransCo c1 c2) = km_trans >.> lkC env c1 >=> lkC env c2
  368. go (UnsafeCo t1 t2) = km_unsafe >.> lkT env t1 >=> lkT env t2
  369. go (InstCo c t) = km_inst >.> lkC env c >=> lkT env t
  370. go (ForAllCo v c) = km_forall >.> lkC (extendCME env v) c >=> lkBndr env v
  371. go (CoVarCo v) = km_var >.> lkVar env v
  372. go (SymCo c) = km_sym >.> lkC env c
  373. go (NthCo n c) = km_nth >.> lookupTM n >=> lkC env c
  374. xtC :: CmEnv -> Coercion -> XT a -> CoercionMap a -> CoercionMap a
  375. xtC env co f EmptyKM = xtC env co f wrapEmptyKM
  376. xtC env (Refl ty) f m = m { km_refl = km_refl m |> xtT env ty f }
  377. xtC env (TyConAppCo tc cs) f m = m { km_tc_app = km_tc_app m |> xtNamed tc |>> xtList (xtC env) cs f }
  378. xtC env (AxiomInstCo ax cs) f m = m { km_axiom = km_axiom m |> xtNamed ax |>> xtList (xtC env) cs f }
  379. xtC env (AppCo c1 c2) f m = m { km_app = km_app m |> xtC env c1 |>> xtC env c2 f }
  380. xtC env (TransCo c1 c2) f m = m { km_trans = km_trans m |> xtC env c1 |>> xtC env c2 f }
  381. xtC env (UnsafeCo t1 t2) f m = m { km_unsafe = km_unsafe m |> xtT env t1 |>> xtT env t2 f }
  382. xtC env (InstCo c t) f m = m { km_inst = km_inst m |> xtC env c |>> xtT env t f }
  383. xtC env (ForAllCo v c) f m = m { km_forall = km_forall m |> xtC (extendCME env v) c
  384. |>> xtBndr env v f }
  385. xtC env (CoVarCo v) f m = m { km_var = km_var m |> xtVar env v f }
  386. xtC env (SymCo c) f m = m { km_sym = km_sym m |> xtC env c f }
  387. xtC env (NthCo n c) f m = m { km_nth = km_nth m |> xtInt n |>> xtC env c f }
  388. fdC :: (a -> b -> b) -> CoercionMap a -> b -> b
  389. fdC _ EmptyKM = \z -> z
  390. fdC k m = foldTM k (km_refl m)
  391. . foldTM (foldTM k) (km_tc_app m)
  392. . foldTM (foldTM k) (km_app m)
  393. . foldTM (foldTM k) (km_forall m)
  394. . foldTM k (km_var m)
  395. . foldTM (foldTM k) (km_axiom m)
  396. . foldTM (foldTM k) (km_unsafe m)
  397. . foldTM k (km_sym m)
  398. . foldTM (foldTM k) (km_trans m)
  399. . foldTM (foldTM k) (km_nth m)
  400. . foldTM (foldTM k) (km_inst m)
  401. \end{code}
  402. %************************************************************************
  403. %* *
  404. Types
  405. %* *
  406. %************************************************************************
  407. \begin{code}
  408. data TypeMap a
  409. = EmptyTM
  410. | TM { tm_var :: VarMap a
  411. , tm_app :: TypeMap (TypeMap a)
  412. , tm_fun :: TypeMap (TypeMap a)
  413. , tm_tc_app :: NameEnv (ListMap TypeMap a)
  414. , tm_forall :: TypeMap (BndrMap a) }
  415. instance Outputable a => Outputable (TypeMap a) where
  416. ppr m = text "TypeMap elts" <+> ppr (foldTypeMap (:) [] m)
  417. foldTypeMap :: (a -> b -> b) -> b -> TypeMap a -> b
  418. foldTypeMap k z m = fdT k m z
  419. wrapEmptyTypeMap :: TypeMap a
  420. wrapEmptyTypeMap = TM { tm_var = emptyTM
  421. , tm_app = EmptyTM
  422. , tm_fun = EmptyTM
  423. , tm_tc_app = emptyNameEnv
  424. , tm_forall = EmptyTM }
  425. instance TrieMap TypeMap where
  426. type Key TypeMap = Type
  427. emptyTM = EmptyTM
  428. lookupTM = lkT emptyCME
  429. alterTM = xtT emptyCME
  430. foldTM = fdT
  431. -----------------
  432. lkT :: CmEnv -> Type -> TypeMap a -> Maybe a
  433. lkT env ty m
  434. | EmptyTM <- m = Nothing
  435. | otherwise = go ty m
  436. where
  437. go ty | Just ty' <- coreView ty = go ty'
  438. go (TyVarTy v) = tm_var >.> lkVar env v
  439. go (AppTy t1 t2) = tm_app >.> lkT env t1 >=> lkT env t2
  440. go (FunTy t1 t2) = tm_fun >.> lkT env t1 >=> lkT env t2
  441. go (TyConApp tc tys) = tm_tc_app >.> lkNamed tc >=> lkList (lkT env) tys
  442. go (ForAllTy tv ty) = tm_forall >.> lkT (extendCME env tv) ty >=> lkBndr env tv
  443. -----------------
  444. xtT :: CmEnv -> Type -> XT a -> TypeMap a -> TypeMap a
  445. xtT env ty f m
  446. | EmptyTM <- m = xtT env ty f wrapEmptyTypeMap
  447. | Just ty' <- coreView ty = xtT env ty' f m
  448. xtT env (TyVarTy v) f m = m { tm_var = tm_var m |> xtVar env v f }
  449. xtT env (AppTy t1 t2) f m = m { tm_app = tm_app m |> xtT env t1 |>> xtT env t2 f }
  450. xtT env (FunTy t1 t2) f m = m { tm_fun = tm_fun m |> xtT env t1 |>> xtT env t2 f }
  451. xtT env (ForAllTy tv ty) f m = m { tm_forall = tm_forall m |> xtT (extendCME env tv) ty
  452. |>> xtBndr env tv f }
  453. xtT env (TyConApp tc tys) f m = m { tm_tc_app = tm_tc_app m |> xtNamed tc
  454. |>> xtList (xtT env) tys f }
  455. fdT :: (a -> b -> b) -> TypeMap a -> b -> b
  456. fdT _ EmptyTM = \z -> z
  457. fdT k m = foldTM k (tm_var m)
  458. . foldTM (foldTM k) (tm_app m)
  459. . foldTM (foldTM k) (tm_fun m)
  460. . foldTM (foldTM k) (tm_tc_app m)
  461. . foldTM (foldTM k) (tm_forall m)
  462. \end{code}
  463. %************************************************************************
  464. %* *
  465. Variables
  466. %* *
  467. %************************************************************************
  468. \begin{code}
  469. type BoundVar = Int -- Bound variables are deBruijn numbered
  470. type BoundVarMap a = IntMap.IntMap a
  471. data CmEnv = CME { cme_next :: BoundVar
  472. , cme_env :: VarEnv BoundVar }
  473. emptyCME :: CmEnv
  474. emptyCME = CME { cme_next = 0, cme_env = emptyVarEnv }
  475. extendCME :: CmEnv -> Var -> CmEnv
  476. extendCME (CME { cme_next = bv, cme_env = env }) v
  477. = CME { cme_next = bv+1, cme_env = extendVarEnv env v bv }
  478. extendCMEs :: CmEnv -> [Var] -> CmEnv
  479. extendCMEs env vs = foldl extendCME env vs
  480. lookupCME :: CmEnv -> Var -> Maybe BoundVar
  481. lookupCME (CME { cme_env = env }) v = lookupVarEnv env v
  482. --------- Variable binders -------------
  483. type BndrMap = TypeMap
  484. lkBndr :: CmEnv -> Var -> BndrMap a -> Maybe a
  485. lkBndr env v m = lkT env (varType v) m
  486. xtBndr :: CmEnv -> Var -> XT a -> BndrMap a -> BndrMap a
  487. xtBndr env v f = xtT env (varType v) f
  488. --------- Variable occurrence -------------
  489. data VarMap a = VM { vm_bvar :: BoundVarMap a -- Bound variable
  490. , vm_fvar :: VarEnv a } -- Free variable
  491. instance TrieMap VarMap where
  492. type Key VarMap = Var
  493. emptyTM = VM { vm_bvar = IntMap.empty, vm_fvar = emptyVarEnv }
  494. lookupTM = lkVar emptyCME
  495. alterTM = xtVar emptyCME
  496. foldTM = fdVar
  497. lkVar :: CmEnv -> Var -> VarMap a -> Maybe a
  498. lkVar env v
  499. | Just bv <- lookupCME env v = vm_bvar >.> lookupTM bv
  500. | otherwise = vm_fvar >.> lkFreeVar v
  501. xtVar :: CmEnv -> Var -> XT a -> VarMap a -> VarMap a
  502. xtVar env v f m
  503. | Just bv <- lookupCME env v = m { vm_bvar = vm_bvar m |> xtInt bv f }
  504. | otherwise = m { vm_fvar = vm_fvar m |> xtFreeVar v f }
  505. fdVar :: (a -> b -> b) -> VarMap a -> b -> b
  506. fdVar k m = foldTM k (vm_bvar m)
  507. . foldTM k (vm_fvar m)
  508. lkFreeVar :: Var -> VarEnv a -> Maybe a
  509. lkFreeVar var env = lookupVarEnv env var
  510. xtFreeVar :: Var -> XT a -> VarEnv a -> VarEnv a
  511. xtFreeVar v f m = alterVarEnv f m v
  512. \end{code}