2012-04-27 08:29:13 +00:00
|
|
|
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
2012-11-24 21:00:00 +00:00
|
|
|
module Rename (renameModule, derename, deprime) where
|
2012-04-19 06:32:10 +00:00
|
|
|
|
|
|
|
import Ast
|
2012-12-25 08:39:18 +00:00
|
|
|
import Context
|
2012-04-19 06:32:10 +00:00
|
|
|
import Control.Arrow (first)
|
2012-07-28 18:46:14 +00:00
|
|
|
import Control.Monad (ap, liftM, foldM, mapM, Monad, zipWithM)
|
2012-04-27 08:29:13 +00:00
|
|
|
import Control.Monad.State (evalState, State, get, put)
|
2012-08-09 14:38:18 +00:00
|
|
|
import Data.Char (isLower,isDigit)
|
2012-05-12 04:27:59 +00:00
|
|
|
import Guid
|
2012-04-19 06:32:10 +00:00
|
|
|
|
2012-08-09 14:38:18 +00:00
|
|
|
derename var
|
|
|
|
| isDigit (last var) = reverse . tail . dropWhile isDigit $ reverse var
|
|
|
|
| otherwise = var
|
|
|
|
|
2012-11-23 03:48:54 +00:00
|
|
|
renameModule :: Module -> Module
|
|
|
|
renameModule modul = run (rename deprime modul)
|
|
|
|
|
|
|
|
class Rename a where
|
|
|
|
rename :: (String -> String) -> a -> GuidCounter a
|
|
|
|
|
|
|
|
instance Rename Module where
|
|
|
|
rename env (Module name ex im stmts) = do stmts' <- renameStmts env stmts
|
|
|
|
return (Module name ex im stmts')
|
|
|
|
|
|
|
|
instance Rename Def where
|
|
|
|
rename env (OpDef op a1 a2 e) =
|
|
|
|
do env' <- extends env [a1,a2]
|
|
|
|
OpDef op (env' a1) (env' a2) `liftM` rename env' e
|
|
|
|
rename env (FnDef f args e) =
|
|
|
|
do env' <- extends env args
|
|
|
|
FnDef (env f) (map env' args) `liftM` rename env' e
|
|
|
|
|
|
|
|
instance Rename Statement where
|
2013-02-04 10:56:22 +00:00
|
|
|
rename env stmt =
|
|
|
|
case stmt of
|
|
|
|
Definition def -> Definition `liftM` rename env def
|
|
|
|
Datatype name args tcs ->
|
|
|
|
return $ Datatype name args $ map (first env) tcs
|
2013-02-06 11:04:55 +00:00
|
|
|
TypeAlias n xs t -> return (TypeAlias n xs t)
|
2013-02-04 10:56:22 +00:00
|
|
|
TypeAnnotation n t -> return (TypeAnnotation (env n) t)
|
|
|
|
ImportEvent js base elm tipe ->
|
|
|
|
do base' <- rename env base
|
|
|
|
return $ ImportEvent js base' (env elm) tipe
|
|
|
|
ExportEvent js elm tipe ->
|
|
|
|
return $ ExportEvent js (env elm) tipe
|
2012-11-23 03:48:54 +00:00
|
|
|
|
|
|
|
renameStmts env stmts = do env' <- extends env $ concatMap getNames stmts
|
|
|
|
mapM (rename env') stmts
|
|
|
|
where getNames stmt = case stmt of
|
|
|
|
Definition (FnDef n _ _) -> [n]
|
|
|
|
Datatype _ _ tcs -> map fst tcs
|
|
|
|
ImportEvent _ _ n _ -> [n]
|
|
|
|
_ -> []
|
|
|
|
|
2012-12-25 08:39:18 +00:00
|
|
|
instance Rename a => Rename (Context a) where
|
|
|
|
rename env (C t s e) = C t s `liftM` rename env e
|
|
|
|
|
2012-11-23 03:48:54 +00:00
|
|
|
instance Rename Expr where
|
|
|
|
rename env expr =
|
|
|
|
let rnm = rename env in
|
2012-04-19 06:32:10 +00:00
|
|
|
case expr of
|
2012-04-27 08:29:13 +00:00
|
|
|
|
|
|
|
Range e1 e2 -> Range `liftM` rnm e1
|
|
|
|
`ap` rnm e2
|
|
|
|
|
|
|
|
Access e x -> Access `liftM` rnm e
|
|
|
|
`ap` return x
|
|
|
|
|
2012-12-26 22:07:09 +00:00
|
|
|
Remove e x -> flip Remove x `liftM` rnm e
|
|
|
|
|
|
|
|
Insert e x v -> flip Insert x `liftM` rnm e
|
|
|
|
`ap` rnm v
|
|
|
|
|
|
|
|
Modify e fs -> Modify `liftM` rnm e
|
|
|
|
`ap` mapM (\(x,e) -> (,) x `liftM` rnm e) fs
|
2012-12-25 09:45:02 +00:00
|
|
|
|
|
|
|
Record fs -> Record `liftM` mapM frnm fs
|
|
|
|
where frnm (f,as,e) = do env' <- extends env as
|
|
|
|
e' <- rename env' e
|
|
|
|
return (f, map env' as, e')
|
|
|
|
|
2012-04-27 08:29:13 +00:00
|
|
|
Binop op@(h:_) e1 e2 ->
|
|
|
|
let rop = if isLower h || '_' == h
|
|
|
|
then env op
|
|
|
|
else op
|
|
|
|
in Binop rop `liftM` rnm e1
|
|
|
|
`ap` rnm e2
|
|
|
|
|
|
|
|
Lambda x e -> do
|
|
|
|
(rx, env') <- extend env x
|
2012-11-23 03:48:54 +00:00
|
|
|
Lambda rx `liftM` rename env' e
|
2012-04-27 08:29:13 +00:00
|
|
|
|
|
|
|
App e1 e2 -> App `liftM` rnm e1
|
|
|
|
`ap` rnm e2
|
|
|
|
|
|
|
|
If e1 e2 e3 -> If `liftM` rnm e1
|
|
|
|
`ap` rnm e2
|
|
|
|
`ap` rnm e3
|
|
|
|
|
2012-12-25 08:39:18 +00:00
|
|
|
MultiIf ps -> MultiIf `liftM` mapM grnm ps
|
2012-11-25 04:49:56 +00:00
|
|
|
where grnm (b,e) = (,) `liftM` rnm b
|
|
|
|
`ap` rnm e
|
|
|
|
|
2012-08-01 23:37:37 +00:00
|
|
|
Let defs e -> renameLet env defs e
|
2012-04-27 08:29:13 +00:00
|
|
|
|
2012-04-19 06:32:10 +00:00
|
|
|
Var x -> return . Var $ env x
|
2012-04-27 08:29:13 +00:00
|
|
|
|
|
|
|
Data name es -> Data name `liftM` mapM rnm es
|
|
|
|
|
|
|
|
Case e cases -> Case `liftM` rnm e
|
|
|
|
`ap` mapM (patternRename env) cases
|
|
|
|
|
2012-04-19 06:32:10 +00:00
|
|
|
_ -> return expr
|
|
|
|
|
2013-01-06 00:27:36 +00:00
|
|
|
deprime = map (\c -> if c == '\'' then '$' else c)
|
2012-09-26 18:29:53 +00:00
|
|
|
|
2012-04-27 08:29:13 +00:00
|
|
|
extend :: (String -> String) -> String -> GuidCounter (String, String -> String)
|
2012-04-19 06:32:10 +00:00
|
|
|
extend env x = do
|
|
|
|
n <- guid
|
2012-09-26 18:29:53 +00:00
|
|
|
let rx = deprime x ++ "_" ++ show n
|
2012-04-27 08:29:13 +00:00
|
|
|
return (rx, \y -> if y == x then rx else env y)
|
2012-04-19 06:32:10 +00:00
|
|
|
|
2012-07-28 18:46:14 +00:00
|
|
|
extends :: (String -> String) -> [String] -> GuidCounter (String -> String)
|
|
|
|
extends env xs = foldM (\e x -> liftM snd $ extend e x) env xs
|
|
|
|
|
2012-04-27 08:29:13 +00:00
|
|
|
patternExtend :: Pattern -> (String -> String) -> GuidCounter (Pattern, String -> String)
|
|
|
|
patternExtend pattern env =
|
2012-04-19 06:32:10 +00:00
|
|
|
case pattern of
|
|
|
|
PAnything -> return (PAnything, env)
|
2012-04-27 08:29:13 +00:00
|
|
|
PVar x -> first PVar `liftM` extend env x
|
2012-04-19 06:32:10 +00:00
|
|
|
PData name ps ->
|
2012-04-27 08:29:13 +00:00
|
|
|
first (PData name . reverse) `liftM` foldM f ([], env) ps
|
|
|
|
where f (rps,env') p = do (rp,env'') <- patternExtend p env'
|
2012-04-19 06:32:10 +00:00
|
|
|
return (rp:rps, env'')
|
2013-04-07 13:46:46 +00:00
|
|
|
PRecord fs ->
|
|
|
|
return (pattern, foldr (\f e n -> if n == f then f else env n) env fs)
|
2012-04-19 06:32:10 +00:00
|
|
|
|
2012-12-25 08:39:18 +00:00
|
|
|
patternRename :: (String -> String) -> (Pattern, CExpr) -> GuidCounter (Pattern, CExpr)
|
2012-04-27 08:29:13 +00:00
|
|
|
patternRename env (p,e) = do
|
|
|
|
(rp,env') <- patternExtend p env
|
2012-11-23 03:48:54 +00:00
|
|
|
re <- rename env' e
|
2012-04-27 08:29:13 +00:00
|
|
|
return (rp,re)
|
2012-08-01 23:37:37 +00:00
|
|
|
|
2012-11-23 03:48:54 +00:00
|
|
|
renameLet env defs e = do env' <- extends env $ concatMap getNames defs
|
|
|
|
defs' <- mapM (rename env') defs
|
|
|
|
Let defs' `liftM` rename env' e
|
|
|
|
where getNames (FnDef n _ _) = [n]
|
2013-02-06 11:04:55 +00:00
|
|
|
getNames (OpDef _ _ _ _) = []
|