{-# LANGUAGE BlockArguments #-} module Test.MockCat.TH (showExp) where import Language.Haskell.TH (Exp (..), Lit (..), Pat (..), Q, pprint) import Language.Haskell.TH.PprLib (Doc, hcat, parens, text) import Language.Haskell.TH.Syntax (nameBase) showExp :: Q Exp -> Q String showExp qexp = show . pprintExp <$> qexp pprintExp :: Exp -> Doc pprintExp (VarE name) = text (nameBase name) pprintExp (ConE name) = text (nameBase name) pprintExp (LitE lit) = pprintLit lit pprintExp (AppE e1 e2) = parens $ hcat [pprintExp e1, text " ", pprintExp e2] pprintExp (InfixE e1 e2 e3) = pprintInfixE e1 e2 e3 pprintExp (LamE pats body) = parens $ hcat [text "\\", pprintPats pats, text " -> ", pprintExp body] pprintExp (TupE exps) = parens $ hcat (map (maybe (text "") pprintExp) exps) pprintExp (ListE exps) = parens $ hcat (map pprintExp exps) pprintExp (SigE e _) = pprintExp e pprintExp x = text (pprint x) pprintInfixE :: Maybe Exp -> Exp -> Maybe Exp -> Doc pprintInfixE e1 e2 e3 = parens $ hcat [ maybe (text "") pprintExp e1, maybe (text "") (const (text " ")) e1, pprintExp e2, text " ", maybe (text "") pprintExp e3 ] pprintPats :: [Pat] -> Doc pprintPats = hcat . map pprintPat pprintPat :: Pat -> Doc pprintPat (VarP name) = text (nameBase name) pprintPat p = text (pprint p) pprintLit :: Lit -> Doc pprintLit (IntegerL n) = text (show n) pprintLit (RationalL r) = text (show r) pprintLit (StringL s) = text (show s) pprintLit (CharL c) = text (show c) pprintLit l = text (pprint l)