{-# LANGUAGE NoImplicitPrelude          #-}
{-# LANGUAGE FlexibleContexts           #-}
{-# LANGUAGE CPP                        #-}
#if __GLASGOW_HASKELL__ >= 800
{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}
{-# LANGUAGE TemplateHaskellQuotes      #-}
#else
{-# LANGUAGE QuasiQuotes                #-}
{-# LANGUAGE TemplateHaskell            #-}
#endif

module Text.RE.ZeInternals.SearchReplace.TDFAEdPrime
  ( ed'
  ) where

import           Language.Haskell.TH
import           Language.Haskell.TH.Quote
import           Prelude.Compat
import           Text.RE.REOptions
import           Text.RE.Replace
import           Text.RE.Tools.IsRegex
import           Text.RE.ZeInternals
import           Text.RE.ZeInternals.TDFA
import           Text.RE.ZeInternals.Types.Poss


-- | construct a quasi quoter from a casting function and @Just sro@
-- if the options are known, otherwise a function take takes the
-- 'SimpleREOptions' and constructs the 'SearchReplace' template
ed' :: Q Exp -> Maybe SimpleREOptions -> QuasiQuoter
ed' :: Q Exp -> Maybe SimpleREOptions -> QuasiQuoter
ed' Q Exp
qe Maybe SimpleREOptions
mb = case Maybe SimpleREOptions
mb of
  Maybe SimpleREOptions
Nothing  ->
    (String -> QuasiQuoter
qq0 String
"ed'")
      { quoteExp :: String -> Q Exp
quoteExp = SimpleREOptions -> (String -> Q Exp) -> String -> Q Exp
parse SimpleREOptions
forall a. Bounded a => a
minBound ((String -> Q Exp) -> String -> Q Exp)
-> (String -> Q Exp) -> String -> Q Exp
forall a b. (a -> b) -> a -> b
$ \String
rs -> Exp -> Exp -> Exp
AppE (Exp -> Exp -> Exp) -> Q Exp -> Q (Exp -> Exp)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Q Exp
qe Q (Exp -> Exp) -> Q Exp -> Q Exp
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [|flip unsafe_compile_sr rs|]
      }
  Just SimpleREOptions
sro ->
    (String -> QuasiQuoter
qq0 String
"ed'")
      { quoteExp :: String -> Q Exp
quoteExp = SimpleREOptions -> (String -> Q Exp) -> String -> Q Exp
parse SimpleREOptions
sro ((String -> Q Exp) -> String -> Q Exp)
-> (String -> Q Exp) -> String -> Q Exp
forall a b. (a -> b) -> a -> b
$ \String
rs -> Exp -> Exp -> Exp
AppE (Exp -> Exp -> Exp) -> Q Exp -> Q (Exp -> Exp)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Q Exp
qe Q (Exp -> Exp) -> Q Exp -> Q Exp
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [|unsafe_compile_sr_simple sro rs|]
      }
  where
    parse :: SimpleREOptions -> (String->Q Exp) -> String -> Q Exp
    parse :: SimpleREOptions -> (String -> Q Exp) -> String -> Q Exp
parse SimpleREOptions
sro String -> Q Exp
mk String
ts = (String -> Q Exp)
-> (SearchReplace RE String -> Q Exp)
-> Either String (SearchReplace RE String)
-> Q Exp
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> Q Exp
forall a. HasCallStack => String -> a
error (\SearchReplace RE String
_->String -> Q Exp
mk String
ts) Either String (SearchReplace RE String)
ei
      where
        ei :: Either String (SearchReplace RE String)
        ei :: Either String (SearchReplace RE String)
ei = Poss (SearchReplace RE String)
-> Either String (SearchReplace RE String)
forall a. Poss a -> Either String a
poss2either (Poss (SearchReplace RE String)
 -> Either String (SearchReplace RE String))
-> Poss (SearchReplace RE String)
-> Either String (SearchReplace RE String)
forall a b. (a -> b) -> a -> b
$ (String -> String)
-> (String -> Either String RE)
-> String
-> Poss (SearchReplace RE String)
forall (m :: * -> *) s re.
(Monad m, MonadFail m, Functor m) =>
(String -> s)
-> (String -> Either String re) -> String -> m (SearchReplace re s)
compileSearchReplace_ String -> String
forall a. a -> a
id (Poss RE -> Either String RE
forall a. Poss a -> Either String a
poss2either (Poss RE -> Either String RE)
-> (String -> Poss RE) -> String -> Either String RE
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SimpleREOptions -> String -> Poss RE
forall (m :: * -> *).
(Functor m, Monad m, MonadFail m) =>
SimpleREOptions -> String -> m RE
compileRegexWith SimpleREOptions
sro) String
ts

unsafe_compile_sr_simple :: IsRegex RE s
                         => SimpleREOptions
                         -> String
                         -> SearchReplace RE s
unsafe_compile_sr_simple :: SimpleREOptions -> String -> SearchReplace RE s
unsafe_compile_sr_simple SimpleREOptions
sro =
    REOptions -> String -> SearchReplace RE s
forall o s.
(IsOption o, IsRegex RE s) =>
o -> String -> SearchReplace RE s
unsafe_compile_sr (REOptions -> String -> SearchReplace RE s)
-> REOptions -> String -> SearchReplace RE s
forall a b. (a -> b) -> a -> b
$ SimpleREOptions -> REOptions
unpackSimpleREOptions SimpleREOptions
sro

unsafe_compile_sr :: (IsOption o, IsRegex RE s)
                  => o
                  -> String
                  -> SearchReplace RE s
unsafe_compile_sr :: o -> String -> SearchReplace RE s
unsafe_compile_sr o
os =
    (String -> s)
-> (String -> Either String RE) -> String -> SearchReplace RE s
forall s re.
(String -> s)
-> (String -> Either String re) -> String -> SearchReplace re s
unsafeCompileSearchReplace_ String -> s
forall a. Replace a => String -> a
packR ((String -> Either String RE) -> String -> SearchReplace RE s)
-> (String -> Either String RE) -> String -> SearchReplace RE s
forall a b. (a -> b) -> a -> b
$ Poss RE -> Either String RE
forall a. Poss a -> Either String a
poss2either (Poss RE -> Either String RE)
-> (String -> Poss RE) -> String -> Either String RE
forall b c a. (b -> c) -> (a -> b) -> a -> c
. o -> String -> Poss RE
forall o (m :: * -> *).
(IsOption o, Functor m, Monad m, MonadFail m) =>
o -> String -> m RE
compileRegexWithOptionsForQQ o
os