{-# OPTIONS_GHC -fno-warn-missing-fields #-} {-# LANGUAGE DeriveFunctor #-} {-| `d`, `dd`, and `dump` are aliases of the same `QuasiQuoter`. you can choose to imort just one of them: @ import Debug.Dump (dd) @ Example usage: @ {-\# LANGUAGE QuasiQuotes \#-} import Debug.Dump main = print [d|a, a+1, map (+a) [1..3]|] where a = 2 @ which prints: @ (a) = 2 (a+1) = 3 (map (+a) [1..3]) = [3,4,5] @ by turnint this String @ "a, a+1, map (+a) [1..3]" @ into this expression @ ( "(a) = " ++ show (a) ++ "\t " ++ "(a+1) = " ++ show (a + 1) ++ "\t " ++ "(map (+a) [1..3]) = " ++ show (map (+ a) [1 .. 3]) ) @ -} module Debug.Dump (d, dd, dump) where import Internal.Utils (($>), (.>)) import qualified Internal.Utils as Utils import qualified Internal.Parser as Parser import Data.List import Debug.Trace import Language.Haskell.TH import Language.Haskell.TH.Quote import Language.Haskell.Meta.Parse import Text.InterpolatedString.Perl6 -- | This is the main `QuasiQuoter`. dump :: QuasiQuoter dump = QuasiQuoter {quoteExp = process} -- | Shorthand for `dump`. d = dump -- | Shorthand for `dump`. dd = dump newtype HsExp a = HsExp a deriving (Functor) unHsExp (HsExp s) = s instance Applicative HsExp where pure = HsExp (HsExp f) <*> (HsExp a) = HsExp $ f a process :: String -> Q Exp process = id .> splitOnCommas .> map nameAndValue .> joinAsColumns .> wrapInParens .> parseHsStrToQQExp .> return splitOnCommas :: String -> [HsExp String] splitOnCommas = Parser.splitOnCommas .> map HsExp nameAndValue :: HsExp String -> HsExp String nameAndValue = fmap $ \str-> [qq|"({Utils.strip str}) = " ++ show ($str)|] joinAsColumns :: [HsExp String] -> HsExp String joinAsColumns = sequenceA .> fmap (intercalate [q| ++ "\t " ++ |]) wrapInParens :: HsExp String -> HsExp String wrapInParens = fmap Utils.wrapInParens parseHsStrToQQExp :: HsExp String -> Exp parseHsStrToQQExp = unHsExp .> parseExp .> either error id