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

/dph-plugin/DPH/Core/Pretty.hs

https://github.com/mchakravarty/packages-dph
Haskell | 259 lines | 176 code | 59 blank | 24 comment | 5 complexity | ea12ed00f2de0adb52c1d3bc12b04179 MD5 | raw file
  1. module DPH.Core.Pretty
  2. ( module DPH.Base.Pretty
  3. , pprModGuts
  4. , pprTopBinds)
  5. where
  6. import DPH.Base.Pretty
  7. import HscTypes
  8. import Avail
  9. import CoreSyn
  10. import Type
  11. import Coercion
  12. import Var
  13. import Name
  14. import OccName
  15. import DataCon
  16. import Literal
  17. import Id
  18. import Unique
  19. import qualified UniqFM as UFM
  20. -- Guts -----------------------------------------------------------------------
  21. pprModGuts :: ModGuts -> Doc
  22. pprModGuts guts
  23. = vcat
  24. [ text "Exports:"
  25. <+> ppr (mg_exports guts)
  26. , empty
  27. , text "VectInfo:"
  28. <+> ppr (mg_vect_info guts)
  29. , empty
  30. , pprTopBinds $ mg_binds guts]
  31. -- | An AvailInfo carries an exported name.
  32. instance Pretty AvailInfo where
  33. ppr aa
  34. = case aa of
  35. Avail n -> ppr n
  36. AvailTC n _ -> ppr n
  37. -- | The VectInfo maps names to their vectorised versions.
  38. instance Pretty VectInfo where
  39. ppr vi
  40. = ppr $ UFM.eltsUFM (vectInfoVar vi)
  41. -- Top Binds ------------------------------------------------------------------
  42. pprTopBinds :: Pretty a => [Bind a] -> Doc
  43. pprTopBinds binds
  44. = vcat $ map pprTopBind binds
  45. pprTopBind :: Pretty a => Bind a -> Doc
  46. pprTopBind (NonRec binder expr)
  47. = pprBinding (binder, expr)
  48. <$$> empty
  49. pprTopBind (Rec [])
  50. = text "Rec { }"
  51. pprTopBind (Rec bb@(b:bs))
  52. = vcat
  53. [ text "Rec {"
  54. , vcat [empty <$$> pprBinding b | b <- bb]
  55. , text "end Rec }"
  56. , empty ]
  57. -- Binding --------------------------------------------------------------------
  58. pprBinding :: Pretty a => (a, Expr a) -> Doc
  59. pprBinding (binder, x)
  60. = ppr binder
  61. <+> breakWhen (not $ isSimpleX x)
  62. <+> equals <+> align (ppr x)
  63. -- Expr -----------------------------------------------------------------------
  64. instance Pretty a => Pretty (Expr a) where
  65. pprPrec d xx
  66. = case xx of
  67. Var ident
  68. -> pprBound ident
  69. -- Discard types and coersions
  70. Type _ -> empty
  71. Coercion _ -> empty
  72. -- Literals.
  73. Lit ll -> ppr ll
  74. -- Suppress Casts completely.
  75. Cast x _co
  76. -> pprPrec d x
  77. -- Abstractions.
  78. Lam{}
  79. -> pprParen' (d > 2)
  80. $ let (bndrs, body) = collectBinders xx
  81. in text "\\" <> sep (map ppr bndrs)
  82. <> text "."
  83. <> (nest 2
  84. $ (breakWhen $ not $ isSimpleX body)
  85. <> ppr body)
  86. -- Applications.
  87. App x1 x2
  88. | isTypeArg x2
  89. -> pprPrec d x1
  90. | otherwise
  91. -> pprParen' (d > 10)
  92. $ ppr x1
  93. <> nest 2 (breakWhen (not $ isSimpleX x2)
  94. <> pprPrec 11 x2)
  95. -- Destructors.
  96. Case x1 var ty [(con, binds, x2)]
  97. -> pprParen' (d > 2)
  98. $ text "let"
  99. <+> (fill 12 (ppr con <+> hsep (map ppr binds)))
  100. -- <> breakWhen (not $ isSimpleX x1)
  101. <+> text "<-"
  102. <+> ppr x1
  103. <+> text "in"
  104. <$$> ppr x2
  105. Case x1 var ty alts
  106. -> pprParen' (d > 2)
  107. $ (nest 2
  108. $ text "case" <+> ppr x1 <+> text "of"
  109. <+> ppr var
  110. <+> lbrace <> line
  111. <> vcat (punctuate semi $ map pprAlt alts))
  112. <> line <> rbrace
  113. -- Binding.
  114. Let (NonRec b x1) x2
  115. -> pprParen' (d > 2)
  116. $ text "let"
  117. <+> fill 12 (ppr b)
  118. <+> equals
  119. <+> ppr x1
  120. <+> text "in"
  121. <$$> ppr x2
  122. Let (Rec bxs) x2
  123. -> pprParen' (d > 2)
  124. $ text "letrec {"
  125. <+> vcat [ fill 12 (ppr b)
  126. <+> equals
  127. <+> ppr x
  128. | (b, x) <- bxs]
  129. <+> text "} in"
  130. <$$> ppr x2
  131. _ -> text "DUNNO"
  132. -- Alt ------------------------------------------------------------------------
  133. pprAlt :: Pretty a => (AltCon, [a], Expr a) -> Doc
  134. pprAlt (con, binds, x)
  135. = ppr con <+> (hsep $ map ppr binds)
  136. <+> nest 1 (line <> nest 3 (text "->" <+> ppr x))
  137. instance Pretty AltCon where
  138. ppr con
  139. = case con of
  140. DataAlt con -> ppr con
  141. LitAlt lit -> ppr lit
  142. DEFAULT -> text "_"
  143. -- | Pretty print bound occurrences of an identifier
  144. pprBound :: Id -> Doc
  145. pprBound i
  146. -- Suppress uniqueids from primops, dictionary functions and data constructors
  147. -- These are unlikely to have conflicting base names.
  148. | isPrimOpId i || isDFunId i || isDataConWorkId i
  149. = ppr (idName i)
  150. | otherwise
  151. = ppr (idName i) <> text "_" <> text (show $ idUnique i)
  152. -- Literal --------------------------------------------------------------------
  153. instance Pretty Literal where
  154. ppr _ = text "<LITERAL>"
  155. -- Type -----------------------------------------------------------------------
  156. instance Pretty Type where
  157. ppr _ = empty
  158. -- Coercion -------------------------------------------------------------------
  159. instance Pretty Coercion where
  160. ppr _ = empty
  161. -- Names ----------------------------------------------------------------------
  162. instance Pretty CoreBndr where
  163. ppr bndr
  164. = ppr (idName bndr)
  165. <> text "_"
  166. <> text (show $ idUnique bndr)
  167. instance Pretty DataCon where
  168. ppr con
  169. = ppr (dataConName con)
  170. instance Pretty Name where
  171. ppr name
  172. = ppr (nameOccName name)
  173. instance Pretty OccName where
  174. ppr occName
  175. = text (occNameString occName)
  176. -- Utils ----------------------------------------------------------------------
  177. breakWhen :: Bool -> Doc
  178. breakWhen True = line
  179. breakWhen False = space
  180. isSimpleX :: Expr a -> Bool
  181. isSimpleX xx
  182. = case xx of
  183. Var{} -> True
  184. Lit{} -> True
  185. App x1 x2 -> isSimpleX x1 && isAtomX x2
  186. Cast x1 _ -> isSimpleX x1
  187. _ -> False
  188. isAtomX :: Expr a -> Bool
  189. isAtomX xx
  190. = case xx of
  191. Var{} -> True
  192. Lit{} -> True
  193. _ -> False
  194. parens' :: Doc -> Doc
  195. parens' d = lparen <> nest 1 d <> rparen
  196. -- | Wrap a `Doc` in parens if the predicate is true.
  197. pprParen' :: Bool -> Doc -> Doc
  198. pprParen' b c
  199. = if b then parens' c
  200. else c