1{-# LANGUAGE GeneralizedNewtypeDeriving #-}
2module SourceSyntax.Rename (renameModule, derename, deprime) where
4import Control.Arrow (first)
5import Control.Monad (ap, liftM, foldM, mapM, Monad, zipWithM)
6import Control.Monad.State (evalState, State, get, put)
7import Data.Char (isLower,isDigit)
8import qualified Data.Map as Map
10import SourceSyntax.Location
11import SourceSyntax.Pattern
12import SourceSyntax.Expression
13import SourceSyntax.Declaration hiding (Assoc(..))
14import SourceSyntax.Module
17 | isDigit (last var) = reverse . tail . dropWhile isDigit $ reverse var
20renameModule :: Module t v -> Module t v
21renameModule modul = run (rename Map.empty modul)
23type Env = Map.Map String String
25replace :: Env -> String -> String
27 Map.findWithDefault (deprime v) v env
30 rename :: Env -> a -> Unique a
32instance Rename (Module t v) where
33 rename env (Module name ex im stmts) = do stmts' <- renameStmts env stmts
34 return (Module name ex im stmts')
36instance Rename (Def t v) where
37 rename env (OpDef op a1 a2 e) =
38 do env' <- extends env [a1,a2]
39 OpDef op (replace env' a1) (replace env' a2) `liftM` rename env' e
40 rename env (FnDef f args e) =
41 do env' <- extends env args
42 FnDef (replace env f) (map (replace env') args) `liftM` rename env' e
43 rename env (TypeAnnotation n t) = return (TypeAnnotation (replace env n) t)
46instance Rename (Declaration t v) where
49 Definition def -> Definition `liftM` rename env def
50 Datatype name args tcs ->
51 return $ Datatype name args $ map (first $ replace env) tcs
52 TypeAlias n xs t -> return (TypeAlias n xs t)
53 ImportEvent js base elm tipe ->
54 do base' <- rename env base
55 return $ ImportEvent js base' (replace env elm) tipe
56 ExportEvent js elm tipe ->
57 return $ ExportEvent js (replace env elm) tipe
59renameStmts env stmts = do env' <- extends env $ concatMap getNames stmts
60 mapM (rename env') stmts
61 where getNames stmt = case stmt of
62 Definition (FnDef n _ _) -> [n]
63 Datatype _ _ tcs -> map fst tcs
64 ImportEvent _ _ n _ -> [n]
67instance Rename a => Rename (Located a) where
68 rename env (L t s e) = L t s `liftM` rename env e
70instance Rename (Expr t v) where
72 let rnm = rename env in
75 Range e1 e2 -> Range `liftM` rnm e1
78 Access e x -> Access `liftM` rnm e
81 Remove e x -> flip Remove x `liftM` rnm e
83 Insert e x v -> flip Insert x `liftM` rnm e
86 Modify e fs -> Modify `liftM` rnm e
87 `ap` mapM (\(x,e) -> (,) x `liftM` rnm e) fs
89 Record fs -> Record `liftM` mapM frnm fs
90 where frnm (f,as,e) = do
91 env' <- extends env as
93 return (f, map (replace env') as, e')
95 Binop op@(h:_) e1 e2 ->
96 let rop = if isLower h || '_' == h
99 in Binop rop `liftM` rnm e1
103 (rx, env') <- extend env x
104 Lambda rx `liftM` rename env' e
106 App e1 e2 -> App `liftM` rnm e1
109 MultiIf ps -> MultiIf `liftM` mapM grnm ps
110 where grnm (b,e) = (,) `liftM` rnm b
113 Let defs e -> renameLet env defs e
115 Var x -> return $ Var (replace env x)
117 Data name es -> Data name `liftM` mapM rnm es
119 ExplicitList es -> ExplicitList `liftM` mapM rnm es
121 Case e cases -> Case `liftM` rnm e
122 `ap` mapM (patternRename env) cases
126deprime = map (\c -> if c == '\'' then '$' else c)
128extend :: Env -> String -> Unique (String, Env)
131 let rx = deprime x ++ "_" ++ show n
132 return (rx, Map.insert x rx env)
134extends :: Env -> [String] -> Unique Env
135extends env xs = foldM (\e x -> liftM snd $ extend e x) env xs
137patternExtend :: Pattern -> Env -> Unique (Pattern, Env)
138patternExtend pattern env =
140 PLiteral _ -> return (pattern, env)
141 PAnything -> return (pattern, env)
142 PVar x -> first PVar `liftM` extend env x
144 (x', env') <- extend env x
145 (p', env'') <- patternExtend p env'
146 return (PAlias x' p', env'')
148 first (PData name . reverse) `liftM` foldM f ([], env) ps
149 where f (rps,env') p = do (rp,env'') <- patternExtend p env'
150 return (rp:rps, env'')
152 return (pattern, Map.union (Map.fromList $ map (\f -> (f,f)) fs) env)
154patternRename :: Env -> (Pattern, LExpr t v) -> Unique (Pattern, LExpr t v)
155patternRename env (p,e) = do
156 (rp,env') <- patternExtend p env
160renameLet env defs e = do env' <- extends env $ concatMap getNames defs
161 defs' <- mapM (rename env') defs
162 Let defs' `liftM` rename env' e
163 where getNames (FnDef n _ _) = [n]
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list