{-# LANGUAGE ScopedTypeVariables #-} module Tip.Pass.UniqLocals where import Tip.Core import Tip.Scope as Scope import Tip.Fresh import Control.Monad import Control.Monad.State import Control.Applicative import qualified Data.Traversable as T import qualified Data.Map as M import qualified Data.Set as S uniqLocals :: forall a . Name a => Theory a -> Fresh (Theory a) uniqLocals thy = fmap declsToTheory . mapM (flip evalStateT M.empty . T.traverse uq) . theoryDecls $ thy where nonlocals = M.keys (types scp) ++ M.keys (Scope.globals scp) scp = scope thy uq :: a -> StateT (M.Map a a) Fresh a uq a | a `elem` nonlocals = do return a | otherwise = do mb <- gets (M.lookup a) case mb of Nothing -> do b <- lift (refresh a) modify (M.insert a b) return b Just b -> do return b