-- | 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