purescript-0.15.1: src/Language/PureScript/CoreImp/Optimizer/Common.hs
-- | Common functions used by the various optimizer phases
module Language.PureScript.CoreImp.Optimizer.Common where
import Prelude.Compat
import Data.Text (Text)
import Data.List (foldl')
import Data.Maybe (fromMaybe)
import Language.PureScript.Crash
import Language.PureScript.CoreImp.AST
import Language.PureScript.Names (ModuleName)
import Language.PureScript.PSString (PSString)
applyAll :: [a -> a] -> a -> a
applyAll = foldl' (.) id
replaceIdent :: Text -> AST -> AST -> AST
replaceIdent var1 js = everywhere replace
where
replace (Var _ var2) | var1 == var2 = js
replace other = other
replaceIdents :: [(Text, AST)] -> AST -> AST
replaceIdents vars = everywhere replace
where
replace v@(Var _ var) = fromMaybe v $ lookup var vars
replace other = other
isReassigned :: Text -> AST -> Bool
isReassigned var1 = everything (||) check
where
check :: AST -> Bool
check (Function _ _ args _) | var1 `elem` args = True
check (VariableIntroduction _ arg _) | var1 == arg = True
check (Assignment _ (Var _ arg) _) | var1 == arg = True
check (For _ arg _ _ _) | var1 == arg = True
check (ForIn _ arg _ _) | var1 == arg = True
check _ = False
isRebound :: AST -> AST -> Bool
isRebound js d = any (\v -> isReassigned v d || isUpdated v d) (everything (++) variablesOf js)
where
variablesOf (Var _ var) = [var]
variablesOf _ = []
targetVariable :: AST -> Text
targetVariable (Var _ var) = var
targetVariable (Indexer _ _ tgt) = targetVariable tgt
targetVariable _ = internalError "Invalid argument to targetVariable"
isUpdated :: Text -> AST -> Bool
isUpdated var1 = everything (||) check
where
check :: AST -> Bool
check (Assignment _ target _) | var1 == targetVariable target = True
check _ = False
removeFromBlock :: ([AST] -> [AST]) -> AST -> AST
removeFromBlock go (Block ss sts) = Block ss (go sts)
removeFromBlock _ js = js
isDict :: (ModuleName, PSString) -> AST -> Bool
isDict (moduleName, dictName) (ModuleAccessor _ x y) =
x == moduleName && y == dictName
isDict _ _ = False
isDict' :: [(ModuleName, PSString)] -> AST -> Bool
isDict' xs js = any (`isDict` js) xs