#if __GLASGOW_HASKELL__ >= 800
#else
#endif
module Text.RE.TDFA.RE
(
RE
, regexType
, reOptions
, reSource
, reCaptureNames
, reRegex
, REOptions
, defaultREOptions
, noPreludeREOptions
, compileRegex
, compileRegexWith
, compileRegexWithOptions
, compileSearchReplace
, compileSearchReplaceWith
, compileSearchReplaceWithREOptions
, escape
, escapeWith
, escapeWithOptions
, escapeREString
, prelude
, preludeEnv
, preludeTestsFailing
, preludeTable
, preludeSummary
, preludeSources
, preludeSource
, unpackSimpleREOptions
, re
, reMS
, reMI
, reBS
, reBI
, reMultilineSensitive
, reMultilineInsensitive
, reBlockSensitive
, reBlockInsensitive
, re_
, ed
, edMS
, edMI
, edBS
, edBI
, edMultilineSensitive
, edMultilineInsensitive
, edBlockSensitive
, edBlockInsensitive
, ed_
, cp
) where
import Data.Functor.Identity
import Language.Haskell.TH
import Language.Haskell.TH.Quote
import Prelude.Compat
import Text.RE.Internal.EscapeREString
import Text.RE.Internal.NamedCaptures
import Text.RE.Internal.PreludeMacros
import Text.RE.Internal.QQ
import Text.RE.SearchReplace
import Text.RE.TestBench
import Text.RE.Types.CaptureID
import Text.RE.Types.IsRegex
import Text.RE.Types.REOptions
import Text.RE.Types.Replace
import Text.Regex.TDFA
data RE =
RE
{ _re_options :: !REOptions
, _re_source :: !String
, _re_cnames :: !CaptureNames
, _re_regex :: !Regex
}
regexType :: RegexType
regexType =
mkTDFA $ \txt env md -> txt =~ mdRegexSource regexType ExclCaptures env md
reOptions :: RE -> REOptions
reOptions = _re_options
reSource :: RE -> String
reSource = _re_source
reCaptureNames :: RE -> CaptureNames
reCaptureNames = _re_cnames
reRegex :: RE -> Regex
reRegex = _re_regex
type REOptions = REOptions_ RE CompOption ExecOption
instance IsOption SimpleREOptions RE CompOption ExecOption where
makeREOptions = unpackSimpleREOptions
instance IsOption (Macros RE) RE CompOption ExecOption where
makeREOptions ms = REOptions ms def_comp_option def_exec_option
instance IsOption CompOption RE CompOption ExecOption where
makeREOptions co = REOptions prelude co def_exec_option
instance IsOption ExecOption RE CompOption ExecOption where
makeREOptions eo = REOptions prelude def_comp_option eo
instance IsOption REOptions RE CompOption ExecOption where
makeREOptions = id
instance IsOption () RE CompOption ExecOption where
makeREOptions _ = unpackSimpleREOptions minBound
defaultREOptions :: REOptions
defaultREOptions = makeREOptions (minBound::SimpleREOptions)
noPreludeREOptions :: REOptions
noPreludeREOptions = defaultREOptions { optionsMacs = emptyMacros }
unpackSimpleREOptions :: SimpleREOptions -> REOptions
unpackSimpleREOptions sro =
REOptions
{ optionsMacs = prelude
, optionsComp = comp
, optionsExec = defaultExecOpt
}
where
comp = defaultCompOpt
{ caseSensitive = cs
, multiline = ml
}
(ml,cs) = case sro of
MultilineSensitive -> (,) True True
MultilineInsensitive -> (,) True False
BlockSensitive -> (,) False True
BlockInsensitive -> (,) False False
compileRegex :: (Functor m,Monad m) => String -> m RE
compileRegex = compileRegexWithOptions ()
compileRegexWith :: (Functor m,Monad m) => SimpleREOptions -> String -> m RE
compileRegexWith = compileRegexWithOptions
compileRegexWithOptions :: ( IsOption o RE CompOption ExecOption
, Functor m
, Monad m
)
=> o
-> String
-> m RE
compileRegexWithOptions = compileRegex_ . makeREOptions
compileSearchReplace :: (Monad m,Functor m,IsRegex RE s)
=> String
-> String
-> m (SearchReplace RE s)
compileSearchReplace = compileSearchReplaceWith minBound
compileSearchReplaceWith :: (Monad m,Functor m,IsRegex RE s)
=> SimpleREOptions
-> String
-> String
-> m (SearchReplace RE s)
compileSearchReplaceWith sro = compileSearchAndReplace_ packR $ compileRegexWith sro
compileSearchReplaceWithREOptions :: (Monad m,Functor m,IsRegex RE s)
=> REOptions
-> String
-> String
-> m (SearchReplace RE s)
compileSearchReplaceWithREOptions os = compileSearchAndReplace_ packR $ compileRegexWithOptions os
escape :: (Functor m,Monad m)
=> (String->String)
-> String
-> m RE
escape = escapeWith minBound
escapeWith :: (Functor m,Monad m)
=> SimpleREOptions
-> (String->String)
-> String
-> m RE
escapeWith = escapeWithOptions
escapeWithOptions :: ( IsOption o RE CompOption ExecOption
, Functor m
, Monad m
)
=> o
-> (String->String)
-> String
-> m RE
escapeWithOptions o f = compileRegexWithOptions o . f . escapeREString
prelude :: Macros RE
prelude = runIdentity $ preludeMacros mk regexType ExclCaptures
where
mk = Identity . unsafeCompileRegex_ noPreludeREOptions
preludeEnv :: MacroEnv
preludeEnv = preludeMacroEnv regexType
preludeTestsFailing :: [MacroID]
preludeTestsFailing = badMacros $ preludeMacroEnv regexType
preludeTable :: String
preludeTable = preludeMacroTable regexType
preludeSummary :: PreludeMacro -> String
preludeSummary = preludeMacroSummary regexType
preludeSources :: String
preludeSources = preludeMacroSources regexType
preludeSource :: PreludeMacro -> String
preludeSource = preludeMacroSource regexType
re
, reMS
, reMI
, reBS
, reBI
, reMultilineSensitive
, reMultilineInsensitive
, reBlockSensitive
, reBlockInsensitive
, re_
, ed
, edMS
, edMI
, edBS
, edBI
, edMultilineSensitive
, edMultilineInsensitive
, edBlockSensitive
, edBlockInsensitive
, ed_ :: QuasiQuoter
re = re' $ Just minBound
reMS = reMultilineSensitive
reMI = reMultilineInsensitive
reBS = reBlockSensitive
reBI = reBlockInsensitive
reMultilineSensitive = re' $ Just MultilineSensitive
reMultilineInsensitive = re' $ Just MultilineInsensitive
reBlockSensitive = re' $ Just BlockSensitive
reBlockInsensitive = re' $ Just BlockInsensitive
re_ = re' Nothing
ed = ed' $ Just minBound
edMS = edMultilineSensitive
edMI = edMultilineInsensitive
edBS = edBlockSensitive
edBI = edBlockInsensitive
edMultilineSensitive = ed' $ Just MultilineSensitive
edMultilineInsensitive = ed' $ Just MultilineInsensitive
edBlockSensitive = ed' $ Just BlockSensitive
edBlockInsensitive = ed' $ Just BlockInsensitive
ed_ = ed' Nothing
re' :: Maybe SimpleREOptions -> QuasiQuoter
re' mb = case mb of
Nothing ->
(qq0 "re'")
{ quoteExp = parse minBound (\rs->[|flip unsafeCompileRegex rs|])
}
Just sro ->
(qq0 "re'")
{ quoteExp = parse sro (\rs->[|unsafeCompileRegexSimple sro rs|])
}
where
parse :: SimpleREOptions -> (String->Q Exp) -> String -> Q Exp
parse sro mk rs = either error (\_->mk rs) $ compileRegex_ os rs
where
os = unpackSimpleREOptions sro
unsafeCompileRegexSimple :: SimpleREOptions -> String -> RE
unsafeCompileRegexSimple sro re_s = unsafeCompileRegex_ os re_s
where
os = unpackSimpleREOptions sro
unsafeCompileRegex :: IsOption o RE CompOption ExecOption
=> o
-> String
-> RE
unsafeCompileRegex = unsafeCompileRegex_ . makeREOptions
unsafeCompileRegex_ :: REOptions -> String -> RE
unsafeCompileRegex_ os = either oops id . compileRegex_ os
where
oops = error . ("unsafeCompileRegex: " ++)
compileRegex' :: (Functor m,Monad m)
=> REOptions
-> String
-> m (CaptureNames,Regex)
compileRegex' REOptions{..} s0 = do
((_,cnms),s2) <- either fail return $ extractNamedCaptures s1
(,) cnms <$> makeRegexOptsM optionsComp optionsExec s2
where
s1 = expandMacros reSource optionsMacs s0
compileRegex_ :: (Functor m,Monad m)
=> REOptions
-> String
-> m RE
compileRegex_ os re_s = uncurry mk <$> compileRegex' os re_s
where
mk cnms rx =
RE
{ _re_options = os
, _re_source = re_s
, _re_cnames = cnms
, _re_regex = rx
}
ed' :: Maybe SimpleREOptions -> QuasiQuoter
ed' mb = case mb of
Nothing ->
(qq0 "ed'")
{ quoteExp = parse minBound (\rs->[|flip unsafeCompileSearchReplace rs|])
}
Just sro ->
(qq0 "ed'")
{ quoteExp = parse sro (\rs->[|unsafeCompileSearchReplaceSimple sro rs|])
}
where
parse :: SimpleREOptions -> (String->Q Exp) -> String -> Q Exp
parse sro mk ts = either error (\_->mk ts) ei
where
ei :: Either String (SearchReplace RE String)
ei = compileSearchReplace_ id (compileRegexWith sro) ts
unsafeCompileSearchReplaceSimple :: IsRegex RE s
=> SimpleREOptions
-> String
-> SearchReplace RE s
unsafeCompileSearchReplaceSimple sro re_s = unsafeCompileSearchReplace os re_s
where
os = unpackSimpleREOptions sro
unsafeCompileSearchReplace :: ( IsOption o RE CompOption ExecOption
, IsRegex RE s
)
=> o
-> String
-> SearchReplace RE s
unsafeCompileSearchReplace os =
unsafeCompileSearchReplace_ packR $ compileRegexWithOptions os
def_comp_option :: CompOption
def_comp_option = optionsComp defaultREOptions
def_exec_option :: ExecOption
def_exec_option = optionsExec defaultREOptions