\begin{code}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses      #-}
{-# LANGUAGE FunctionalDependencies     #-}
{-# LANGUAGE CPP                        #-}
#if __GLASGOW_HASKELL__ >= 800
{-# LANGUAGE TemplateHaskellQuotes      #-}
{-# LANGUAGE DeriveLift                 #-}
{-# LANGUAGE StandaloneDeriving         #-}
#else
{-# LANGUAGE QuasiQuotes                #-}
{-# LANGUAGE TemplateHaskell            #-}
#endif

module Text.RE.REOptions
  (
  -- * The Options Tutorial
  -- $tutorial

  -- * 'SimpleREOptions'
    SimpleREOptions(..)
  -- * 'REOptions_'
  , REOptions_(..)
  -- * The Macro Tables
  , Macros
  , MacroID(..)
  , emptyMacros
  ) where

import qualified Data.HashMap.Strict        as HM
import           Data.Hashable
import           Data.String
import           Language.Haskell.TH.Syntax
\end{code}


The RE Options
--------------

\begin{code}
-- | the default API uses these simple, universal RE options,
-- which get auto-converted into the appropriate back-end 'REOptions_'
data SimpleREOptions
  = MultilineSensitive        -- ^ case-sensitive with ^ and $ matching the start and end of a line
  | MultilineInsensitive      -- ^ case-insensitive with ^ and $ matsh the start and end of a line
  | BlockSensitive            -- ^ case-sensitive with ^ and $ matching the start and end of the input text
  | BlockInsensitive          -- ^ case-insensitive with ^ and $ matching the start and end of the input text
  deriving (SimpleREOptions
SimpleREOptions -> SimpleREOptions -> Bounded SimpleREOptions
forall a. a -> a -> Bounded a
maxBound :: SimpleREOptions
$cmaxBound :: SimpleREOptions
minBound :: SimpleREOptions
$cminBound :: SimpleREOptions
Bounded,Int -> SimpleREOptions
SimpleREOptions -> Int
SimpleREOptions -> [SimpleREOptions]
SimpleREOptions -> SimpleREOptions
SimpleREOptions -> SimpleREOptions -> [SimpleREOptions]
SimpleREOptions
-> SimpleREOptions -> SimpleREOptions -> [SimpleREOptions]
(SimpleREOptions -> SimpleREOptions)
-> (SimpleREOptions -> SimpleREOptions)
-> (Int -> SimpleREOptions)
-> (SimpleREOptions -> Int)
-> (SimpleREOptions -> [SimpleREOptions])
-> (SimpleREOptions -> SimpleREOptions -> [SimpleREOptions])
-> (SimpleREOptions -> SimpleREOptions -> [SimpleREOptions])
-> (SimpleREOptions
    -> SimpleREOptions -> SimpleREOptions -> [SimpleREOptions])
-> Enum SimpleREOptions
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: SimpleREOptions
-> SimpleREOptions -> SimpleREOptions -> [SimpleREOptions]
$cenumFromThenTo :: SimpleREOptions
-> SimpleREOptions -> SimpleREOptions -> [SimpleREOptions]
enumFromTo :: SimpleREOptions -> SimpleREOptions -> [SimpleREOptions]
$cenumFromTo :: SimpleREOptions -> SimpleREOptions -> [SimpleREOptions]
enumFromThen :: SimpleREOptions -> SimpleREOptions -> [SimpleREOptions]
$cenumFromThen :: SimpleREOptions -> SimpleREOptions -> [SimpleREOptions]
enumFrom :: SimpleREOptions -> [SimpleREOptions]
$cenumFrom :: SimpleREOptions -> [SimpleREOptions]
fromEnum :: SimpleREOptions -> Int
$cfromEnum :: SimpleREOptions -> Int
toEnum :: Int -> SimpleREOptions
$ctoEnum :: Int -> SimpleREOptions
pred :: SimpleREOptions -> SimpleREOptions
$cpred :: SimpleREOptions -> SimpleREOptions
succ :: SimpleREOptions -> SimpleREOptions
$csucc :: SimpleREOptions -> SimpleREOptions
Enum,SimpleREOptions -> SimpleREOptions -> Bool
(SimpleREOptions -> SimpleREOptions -> Bool)
-> (SimpleREOptions -> SimpleREOptions -> Bool)
-> Eq SimpleREOptions
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SimpleREOptions -> SimpleREOptions -> Bool
$c/= :: SimpleREOptions -> SimpleREOptions -> Bool
== :: SimpleREOptions -> SimpleREOptions -> Bool
$c== :: SimpleREOptions -> SimpleREOptions -> Bool
Eq,Eq SimpleREOptions
Eq SimpleREOptions
-> (SimpleREOptions -> SimpleREOptions -> Ordering)
-> (SimpleREOptions -> SimpleREOptions -> Bool)
-> (SimpleREOptions -> SimpleREOptions -> Bool)
-> (SimpleREOptions -> SimpleREOptions -> Bool)
-> (SimpleREOptions -> SimpleREOptions -> Bool)
-> (SimpleREOptions -> SimpleREOptions -> SimpleREOptions)
-> (SimpleREOptions -> SimpleREOptions -> SimpleREOptions)
-> Ord SimpleREOptions
SimpleREOptions -> SimpleREOptions -> Bool
SimpleREOptions -> SimpleREOptions -> Ordering
SimpleREOptions -> SimpleREOptions -> SimpleREOptions
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: SimpleREOptions -> SimpleREOptions -> SimpleREOptions
$cmin :: SimpleREOptions -> SimpleREOptions -> SimpleREOptions
max :: SimpleREOptions -> SimpleREOptions -> SimpleREOptions
$cmax :: SimpleREOptions -> SimpleREOptions -> SimpleREOptions
>= :: SimpleREOptions -> SimpleREOptions -> Bool
$c>= :: SimpleREOptions -> SimpleREOptions -> Bool
> :: SimpleREOptions -> SimpleREOptions -> Bool
$c> :: SimpleREOptions -> SimpleREOptions -> Bool
<= :: SimpleREOptions -> SimpleREOptions -> Bool
$c<= :: SimpleREOptions -> SimpleREOptions -> Bool
< :: SimpleREOptions -> SimpleREOptions -> Bool
$c< :: SimpleREOptions -> SimpleREOptions -> Bool
compare :: SimpleREOptions -> SimpleREOptions -> Ordering
$ccompare :: SimpleREOptions -> SimpleREOptions -> Ordering
$cp1Ord :: Eq SimpleREOptions
Ord,Int -> SimpleREOptions -> ShowS
[SimpleREOptions] -> ShowS
SimpleREOptions -> String
(Int -> SimpleREOptions -> ShowS)
-> (SimpleREOptions -> String)
-> ([SimpleREOptions] -> ShowS)
-> Show SimpleREOptions
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SimpleREOptions] -> ShowS
$cshowList :: [SimpleREOptions] -> ShowS
show :: SimpleREOptions -> String
$cshow :: SimpleREOptions -> String
showsPrec :: Int -> SimpleREOptions -> ShowS
$cshowsPrec :: Int -> SimpleREOptions -> ShowS
Show)
\end{code}

\begin{code}
-- | we need to use this in the quasi quoters to specify @SimpleREOptions@
-- selected by the quasi quoter
deriving instance Lift SimpleREOptions
\end{code}

\begin{code}
-- | the general options for an RE are dependent on which back end is
-- being used and are parameterised over the @RE@ type for the back end,
-- and its @CompOption@ and @ExecOption@ types (the compile-time and
-- execution time options, respectively); each back end will define an
-- @REOptions@ type that fills out these three type parameters with the
-- appropriate types (see, for example, "Text.RE.TDFA")
data REOptions_ r c e =
  REOptions
    { REOptions_ r c e -> Macros r
optionsMacs :: !(Macros r)    -- ^ the available TestBench RE macros
    , REOptions_ r c e -> c
optionsComp :: !c             -- ^ the back end compile-time options
    , REOptions_ r c e -> e
optionsExec :: !e             -- ^ the back end execution-time options
    }
  deriving (Int -> REOptions_ r c e -> ShowS
[REOptions_ r c e] -> ShowS
REOptions_ r c e -> String
(Int -> REOptions_ r c e -> ShowS)
-> (REOptions_ r c e -> String)
-> ([REOptions_ r c e] -> ShowS)
-> Show (REOptions_ r c e)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall r c e.
(Show r, Show c, Show e) =>
Int -> REOptions_ r c e -> ShowS
forall r c e.
(Show r, Show c, Show e) =>
[REOptions_ r c e] -> ShowS
forall r c e.
(Show r, Show c, Show e) =>
REOptions_ r c e -> String
showList :: [REOptions_ r c e] -> ShowS
$cshowList :: forall r c e.
(Show r, Show c, Show e) =>
[REOptions_ r c e] -> ShowS
show :: REOptions_ r c e -> String
$cshow :: forall r c e.
(Show r, Show c, Show e) =>
REOptions_ r c e -> String
showsPrec :: Int -> REOptions_ r c e -> ShowS
$cshowsPrec :: forall r c e.
(Show r, Show c, Show e) =>
Int -> REOptions_ r c e -> ShowS
Show)
\end{code}


The Macro Tables
----------------

\begin{code}
-- | our macro tables are parameterised over the back end @RE@ type and
-- and just associate each @MacroID@ with an @RE@ (which may in turn
-- contain macros to be expanded)
type Macros r = HM.HashMap MacroID r
\end{code}

\begin{code}
-- | @MacroID@ is just a wrapped @String@ type with an @IsString@
-- instance
newtype MacroID =
    MacroID { MacroID -> String
getMacroID :: String }
  deriving (String -> MacroID
(String -> MacroID) -> IsString MacroID
forall a. (String -> a) -> IsString a
fromString :: String -> MacroID
$cfromString :: String -> MacroID
IsString,Eq MacroID
Eq MacroID
-> (MacroID -> MacroID -> Ordering)
-> (MacroID -> MacroID -> Bool)
-> (MacroID -> MacroID -> Bool)
-> (MacroID -> MacroID -> Bool)
-> (MacroID -> MacroID -> Bool)
-> (MacroID -> MacroID -> MacroID)
-> (MacroID -> MacroID -> MacroID)
-> Ord MacroID
MacroID -> MacroID -> Bool
MacroID -> MacroID -> Ordering
MacroID -> MacroID -> MacroID
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: MacroID -> MacroID -> MacroID
$cmin :: MacroID -> MacroID -> MacroID
max :: MacroID -> MacroID -> MacroID
$cmax :: MacroID -> MacroID -> MacroID
>= :: MacroID -> MacroID -> Bool
$c>= :: MacroID -> MacroID -> Bool
> :: MacroID -> MacroID -> Bool
$c> :: MacroID -> MacroID -> Bool
<= :: MacroID -> MacroID -> Bool
$c<= :: MacroID -> MacroID -> Bool
< :: MacroID -> MacroID -> Bool
$c< :: MacroID -> MacroID -> Bool
compare :: MacroID -> MacroID -> Ordering
$ccompare :: MacroID -> MacroID -> Ordering
$cp1Ord :: Eq MacroID
Ord,MacroID -> MacroID -> Bool
(MacroID -> MacroID -> Bool)
-> (MacroID -> MacroID -> Bool) -> Eq MacroID
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: MacroID -> MacroID -> Bool
$c/= :: MacroID -> MacroID -> Bool
== :: MacroID -> MacroID -> Bool
$c== :: MacroID -> MacroID -> Bool
Eq,Int -> MacroID -> ShowS
[MacroID] -> ShowS
MacroID -> String
(Int -> MacroID -> ShowS)
-> (MacroID -> String) -> ([MacroID] -> ShowS) -> Show MacroID
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [MacroID] -> ShowS
$cshowList :: [MacroID] -> ShowS
show :: MacroID -> String
$cshow :: MacroID -> String
showsPrec :: Int -> MacroID -> ShowS
$cshowsPrec :: Int -> MacroID -> ShowS
Show)
\end{code}

\begin{code}
-- | @MacroID@ is used with @HM.HashMap@ to build macro lookup tables
instance Hashable MacroID where
  hashWithSalt :: Int -> MacroID -> Int
hashWithSalt Int
i = Int -> String -> Int
forall a. Hashable a => Int -> a -> Int
hashWithSalt Int
i (String -> Int) -> (MacroID -> String) -> MacroID -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MacroID -> String
getMacroID
\end{code}

\begin{code}
-- | a macro table containing no entries
emptyMacros :: Macros r
emptyMacros :: Macros r
emptyMacros = Macros r
forall k v. HashMap k v
HM.empty
\end{code}


\begin{code}
-- $tutorial
-- This API module provides the generic types used to specify the options
-- when compiling REs for each of the backl ends.
--
-- See the tutorials at http://re-tutorial-options.regex.uk
\end{code}