{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
module Retrie.Query
( QuerySpec(..)
, parseQuerySpecs
, genericQ
) where
import Retrie.ExactPrint
import Retrie.Fixity
import Retrie.GHC
import Retrie.Quantifiers
import Retrie.Substitution
import Retrie.SYB
import Retrie.Types
import Retrie.Universe
data QuerySpec
= QExpr String
| QType String
| QStmt String
parseQuerySpecs
:: FixityEnv
-> [(Quantifiers, QuerySpec, v)]
-> IO [Query Universe v]
parseQuerySpecs fixityEnv =
mapM $ \(qQuantifiers, querySpec, qResult) -> do
qPattern <- parse querySpec
return Query{..}
where
parse (QExpr s) = do
e <- parseExpr s
fmap inject <$> transformA e (fix fixityEnv)
parse (QType s) = fmap inject <$> parseType s
parse (QStmt s) = do
stmt <- parseStmt s
fmap inject <$> transformA stmt (fix fixityEnv)
genericQ
:: Typeable a
=> Matcher v
-> Context
-> a
-> TransformT IO [(Context, Substitution, v)]
genericQ m ctxt =
mkQ (return []) (genericQImpl @(LHsExpr GhcPs) m ctxt)
`extQ` (genericQImpl @(LStmt GhcPs (LHsExpr GhcPs)) m ctxt)
`extQ` (genericQImpl @(LHsType GhcPs) m ctxt)
genericQImpl
:: forall ast v. Matchable ast
=> Matcher v
-> Context
-> ast
-> TransformT IO [(Context, Substitution, v)]
genericQImpl m ctxt ast = do
pairs <- runMatcher ctxt m ast
return [ (ctxt, sub, v) | (sub, v) <- pairs ]