{-# LANGUAGE DeriveDataTypeable         #-}

module Text.RE.ZeInternals.QQ where

import           Control.Exception
import           Data.Typeable
import           Language.Haskell.TH.Quote


-- | used to throw an exception reporting an abuse of a quasi quoter
data QQFailure =
  QQFailure
    { QQFailure -> String
_qqf_context   :: String  -- ^ in what context was the quasi quoter used
    , QQFailure -> String
_qqf_component :: String  -- ^ how was the quasi quoter being abused
    }
  deriving (Int -> QQFailure -> ShowS
[QQFailure] -> ShowS
QQFailure -> String
(Int -> QQFailure -> ShowS)
-> (QQFailure -> String)
-> ([QQFailure] -> ShowS)
-> Show QQFailure
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [QQFailure] -> ShowS
$cshowList :: [QQFailure] -> ShowS
show :: QQFailure -> String
$cshow :: QQFailure -> String
showsPrec :: Int -> QQFailure -> ShowS
$cshowsPrec :: Int -> QQFailure -> ShowS
Show,Typeable)

instance Exception QQFailure where

-- | a quasi quoter that can be used in no context (to be extended with
-- the appropriate quasi quoter parser)
qq0 :: String -> QuasiQuoter
qq0 :: String -> QuasiQuoter
qq0 String
ctx =
  QuasiQuoter :: (String -> Q Exp)
-> (String -> Q Pat)
-> (String -> Q Type)
-> (String -> Q [Dec])
-> QuasiQuoter
QuasiQuoter
    { quoteExp :: String -> Q Exp
quoteExp  = Q Exp -> String -> Q Exp
forall a b. a -> b -> a
const (Q Exp -> String -> Q Exp) -> Q Exp -> String -> Q Exp
forall a b. (a -> b) -> a -> b
$ QQFailure -> Q Exp
forall a e. Exception e => e -> a
throw (QQFailure -> Q Exp) -> QQFailure -> Q Exp
forall a b. (a -> b) -> a -> b
$ String -> String -> QQFailure
QQFailure String
ctx String
"expression"
    , quotePat :: String -> Q Pat
quotePat  = Q Pat -> String -> Q Pat
forall a b. a -> b -> a
const (Q Pat -> String -> Q Pat) -> Q Pat -> String -> Q Pat
forall a b. (a -> b) -> a -> b
$ QQFailure -> Q Pat
forall a e. Exception e => e -> a
throw (QQFailure -> Q Pat) -> QQFailure -> Q Pat
forall a b. (a -> b) -> a -> b
$ String -> String -> QQFailure
QQFailure String
ctx String
"pattern"
    , quoteType :: String -> Q Type
quoteType = Q Type -> String -> Q Type
forall a b. a -> b -> a
const (Q Type -> String -> Q Type) -> Q Type -> String -> Q Type
forall a b. (a -> b) -> a -> b
$ QQFailure -> Q Type
forall a e. Exception e => e -> a
throw (QQFailure -> Q Type) -> QQFailure -> Q Type
forall a b. (a -> b) -> a -> b
$ String -> String -> QQFailure
QQFailure String
ctx String
"type"
    , quoteDec :: String -> Q [Dec]
quoteDec  = Q [Dec] -> String -> Q [Dec]
forall a b. a -> b -> a
const (Q [Dec] -> String -> Q [Dec]) -> Q [Dec] -> String -> Q [Dec]
forall a b. (a -> b) -> a -> b
$ QQFailure -> Q [Dec]
forall a e. Exception e => e -> a
throw (QQFailure -> Q [Dec]) -> QQFailure -> Q [Dec]
forall a b. (a -> b) -> a -> b
$ String -> String -> QQFailure
QQFailure String
ctx String
"declaration"
    }