PageRenderTime 49ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/ghc-7.4.1/testsuite/tests/plugins/simple-plugin/Simple/Plugin.hs

#
Haskell | 82 lines | 63 code | 16 blank | 3 comment | 3 complexity | fce662bf1f9ea86163264fc7ad2d0127 MD5 | raw file
Possible License(s): LGPL-3.0, BSD-3-Clause, BSD-2-Clause
  1. {-# LANGUAGE TemplateHaskell #-}
  2. module Simple.Plugin(plugin) where
  3. import UniqFM
  4. import GhcPlugins
  5. import qualified ErrUtils
  6. -- For annotation tests
  7. import Simple.DataStructures
  8. import Control.Monad
  9. import Data.Monoid
  10. import Data.Dynamic
  11. import qualified Language.Haskell.TH as TH
  12. plugin :: Plugin
  13. plugin = defaultPlugin {
  14. installCoreToDos = install
  15. }
  16. install :: [CommandLineOption] -> [CoreToDo] -> CoreM [CoreToDo]
  17. install options todos = do
  18. putMsgS $ "Simple Plugin Passes Queried"
  19. putMsgS $ "Got options: " ++ unwords options
  20. -- Create some actual passes to continue the test.
  21. return $ CoreDoPluginPass "Main pass" mainPass
  22. : todos
  23. findNameBinds :: String -> [CoreBind] -> First Name
  24. findNameBinds target = mconcat . map (findNameBind target)
  25. findNameBind :: String -> CoreBind -> First Name
  26. findNameBind target (NonRec b e) = findNameBndr target b
  27. findNameBind target (Rec bes) = mconcat (map (findNameBndr target . fst) bes)
  28. findNameBndr :: String -> CoreBndr -> First Name
  29. findNameBndr target b
  30. = if getOccString (varName b) == target
  31. then First (Just (varName b))
  32. else First Nothing
  33. mainPass :: ModGuts -> CoreM ModGuts
  34. mainPass guts = do
  35. putMsgS "Simple Plugin Pass Run"
  36. anns <- getAnnotations deserializeWithData guts
  37. bindsOnlyPass (mapM (changeBind anns Nothing)) guts
  38. changeBind :: UniqFM [ReplaceWith] -> Maybe String -> CoreBind -> CoreM CoreBind
  39. changeBind anns mb_replacement (NonRec b e) = changeBindPr anns mb_replacement b e >>= (return . uncurry NonRec)
  40. changeBind anns mb_replacement (Rec bes) = liftM Rec $ mapM (uncurry (changeBindPr anns mb_replacement)) bes
  41. changeBindPr :: UniqFM [ReplaceWith] -> Maybe String -> CoreBndr -> CoreExpr -> CoreM (CoreBndr, CoreExpr)
  42. changeBindPr anns mb_replacement b e = do
  43. case lookupWithDefaultUFM anns [] b of
  44. [] -> do
  45. e' <- changeExpr anns mb_replacement e
  46. return (b, e')
  47. [ReplaceWith replace_string] -> do
  48. e' <- changeExpr anns (Just replace_string) e
  49. return (b, e')
  50. _ -> error $ "Too many change_anns on one binder:" ++ showSDoc (ppr b)
  51. changeExpr :: UniqFM [ReplaceWith] -> Maybe String -> CoreExpr -> CoreM CoreExpr
  52. changeExpr anns mb_replacement e = let go = changeExpr anns mb_replacement in case e of
  53. Lit (MachStr _) -> case mb_replacement of
  54. Nothing -> return e
  55. Just replacement -> do
  56. putMsgS "Performing Replacement"
  57. return $ Lit (MachStr (mkFastString replacement))
  58. App e1 e2 -> liftM2 App (go e1) (go e2)
  59. Lam b e -> liftM (Lam b) (go e)
  60. Let bind e -> liftM2 Let (changeBind anns mb_replacement bind) (go e)
  61. Case e b ty alts -> liftM4 Case (go e) (return b) (return ty) (mapM (changeAlt anns mb_replacement) alts)
  62. Cast e coerce -> liftM2 Cast (go e) (return coerce)
  63. Tick t e -> liftM (Tick t) (go e)
  64. _ -> return e
  65. changeAlt :: UniqFM [ReplaceWith] -> Maybe String -> CoreAlt -> CoreM CoreAlt
  66. changeAlt anns mb_replacement (con, bs, e) = liftM (\e' -> (con, bs, e')) (changeExpr anns mb_replacement e)