-- SrcRegActList.hs
--
-- Author: Yoshikuni Jujo <PAF01143@nifty.ne.jp>
--
-- This file is part of regexpr library
--
-- regexpr is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Lesser General Public License as
-- published by the Free Software Foundation, either version 3 of the
-- License, or any later version.
--
-- regexpr is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANGY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU Lesser General Public License for more details.
--
-- You should have received a copy of the GNU Lesser General Public
-- License along with this program. If not, see
-- <http://www.gnu.org/licenses/>.

module Hidden.SrcRegActList (
  selfTest
, plusesList
, oneCharList
, backSlashesList
, parensesList
, charClassList
) where

import Hidden.RegexPRTypes ( RegexAction(..), reverseRegexAction )
import Data.Char           ( isAlphaNum, isAlpha, isUpper, isLower,
                             isDigit, isHexDigit, isSpace, isPrint, isControl )
import Hidden.Tools        ( (&&&), (|||), isSymbol, isBit7On )

selfTest :: Char -> Bool
selfTest :: Char -> Bool
selfTest
  = (Char -> [Char] -> Bool) -> [Char] -> Char -> Bool
forall a b c. (a -> b -> c) -> b -> a -> c
flip Char -> [Char] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
elem [Char]
"\b\n\f\r\t !\"#%&',-/:;<=>@]_'~}" (Char -> Bool) -> (Char -> Bool) -> Char -> Bool
forall a. (a -> Bool) -> (a -> Bool) -> a -> Bool
||| Char -> Bool
isAlphaNum (Char -> Bool) -> (Char -> Bool) -> Char -> Bool
forall a. (a -> Bool) -> (a -> Bool) -> a -> Bool
||| Char -> Bool
isBit7On

plusesList :: [ (String, RegexAction -> RegexAction) ]
plusesList :: [([Char], RegexAction -> RegexAction)]
plusesList = [
   ( [Char]
""  , RegexAction -> RegexAction
forall a. a -> a
id )
 , ( [Char]
"*" , Int -> Maybe Int -> RegexAction -> RegexAction
Repeat          Int
0 Maybe Int
forall a. Maybe a
Nothing  )
 , ( [Char]
"*?", Int -> Maybe Int -> RegexAction -> RegexAction
RepeatNotGreedy Int
0 Maybe Int
forall a. Maybe a
Nothing  )
 , ( [Char]
"+" , Int -> Maybe Int -> RegexAction -> RegexAction
Repeat          Int
1 Maybe Int
forall a. Maybe a
Nothing  )
 , ( [Char]
"+?", Int -> Maybe Int -> RegexAction -> RegexAction
RepeatNotGreedy Int
1 Maybe Int
forall a. Maybe a
Nothing  )
 , ( [Char]
"?" , Int -> Maybe Int -> RegexAction -> RegexAction
Repeat          Int
0 (Maybe Int -> RegexAction -> RegexAction)
-> Maybe Int -> RegexAction -> RegexAction
forall a b. (a -> b) -> a -> b
$ Int -> Maybe Int
forall a. a -> Maybe a
Just Int
1 )
 , ( [Char]
"??", Int -> Maybe Int -> RegexAction -> RegexAction
RepeatNotGreedy Int
0 (Maybe Int -> RegexAction -> RegexAction)
-> Maybe Int -> RegexAction -> RegexAction
forall a b. (a -> b) -> a -> b
$ Int -> Maybe Int
forall a. a -> Maybe a
Just Int
1 )
 ]

oneCharList :: [ (Char, RegexAction) ]
oneCharList :: [(Char, RegexAction)]
oneCharList = [
   (Char
'.', (Char -> Bool) -> RegexAction
Select (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/=Char
'\n'))
 , (Char
'$', [RegexAction] -> [RegexAction] -> RegexAction
RegexOr [RegexAction
EndOfInput] [[RegexAction] -> RegexAction
Still [(Char -> Bool) -> RegexAction
Select (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
==Char
'\n')]])
 , (Char
'^', [RegexAction] -> [RegexAction] -> RegexAction
RegexOr [RegexAction
BeginningOfInput] [[RegexAction] -> RegexAction
Still [[RegexAction] -> RegexAction
Backword [(Char -> Bool) -> RegexAction
Select (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
==Char
'\n')]]])
 ]

backSlashesList :: [ (Char, RegexAction) ]
backSlashesList :: [(Char, RegexAction)]
backSlashesList = [
   ( Char
'w', (Char -> Bool) -> RegexAction
Select Char -> Bool
isWord                                              )
 , ( Char
'W', (Char -> Bool) -> RegexAction
Select ((Char -> Bool) -> RegexAction) -> (Char -> Bool) -> RegexAction
forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
isWord                                      ) 
 , ( Char
's', (Char -> Bool) -> RegexAction
Select (Char -> [Char] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Char]
" \t\n\r\f")                             )
 , ( Char
'S', (Char -> Bool) -> RegexAction
Select (Char -> [Char] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [Char]
" \t\n\r\f")                          )
 , ( Char
'd', (Char -> Bool) -> RegexAction
Select Char -> Bool
isDigit                                             )
 , ( Char
'D', (Char -> Bool) -> RegexAction
Select (Bool -> Bool
not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
isDigit)                                     )
 , ( Char
'A', RegexAction
BeginningOfInput                                           )
 , ( Char
'Z', [RegexAction] -> [RegexAction] -> RegexAction
RegexOr [RegexAction
EndOfInput] [[RegexAction] -> RegexAction
Still [(Char -> Bool) -> RegexAction
Select (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
==Char
'\n'), RegexAction
EndOfInput]] )
 , ( Char
'z', RegexAction
EndOfInput                                                 )
 , ( Char
'b', [[RegexAction]] -> RegexAction
regexOr [
            [ [RegexAction] -> RegexAction
lookBehind [(Char -> Bool) -> RegexAction
Select    Char -> Bool
isWord], [RegexAction] -> RegexAction
Still [(Char -> Bool) -> RegexAction
selectNot Char -> Bool
isWord] ]
	  , [ [RegexAction] -> RegexAction
lookBehind [(Char -> Bool) -> RegexAction
selectNot Char -> Bool
isWord], [RegexAction] -> RegexAction
Still [(Char -> Bool) -> RegexAction
Select    Char -> Bool
isWord] ]
	  , [ RegexAction
BeginningOfInput,              [RegexAction] -> RegexAction
Still [(Char -> Bool) -> RegexAction
Select    Char -> Bool
isWord] ]
	  , [ [RegexAction] -> RegexAction
lookBehind [(Char -> Bool) -> RegexAction
Select    Char -> Bool
isWord], RegexAction
EndOfInput               ]
	  ]                                                          )
 , ( Char
'B', [RegexAction] -> RegexAction
RegActNot [ [[RegexAction]] -> RegexAction
regexOr [
            [ [RegexAction] -> RegexAction
lookBehind [(Char -> Bool) -> RegexAction
Select    Char -> Bool
isWord], [RegexAction] -> RegexAction
Still [(Char -> Bool) -> RegexAction
selectNot Char -> Bool
isWord] ]
	  , [ [RegexAction] -> RegexAction
lookBehind [(Char -> Bool) -> RegexAction
selectNot Char -> Bool
isWord], [RegexAction] -> RegexAction
Still [(Char -> Bool) -> RegexAction
Select    Char -> Bool
isWord] ]
	  , [ RegexAction
BeginningOfInput,              [RegexAction] -> RegexAction
Still [(Char -> Bool) -> RegexAction
Select    Char -> Bool
isWord] ]
	  , [ [RegexAction] -> RegexAction
lookBehind [(Char -> Bool) -> RegexAction
Select    Char -> Bool
isWord], RegexAction
EndOfInput               ]
	  ] ]                                                        )
 , ( Char
'G', RegexAction
PreMatchPoint                                              )
 ]

parensesList :: [ (String, [RegexAction] -> RegexAction) ]
parensesList :: [([Char], [RegexAction] -> RegexAction)]
parensesList = [
   ( [Char]
"?<=", [RegexAction] -> RegexAction
Still ([RegexAction] -> RegexAction)
-> ([RegexAction] -> [RegexAction]) -> [RegexAction] -> RegexAction
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (RegexAction -> [RegexAction] -> [RegexAction]
forall a. a -> [a] -> [a]
:[]) (RegexAction -> [RegexAction])
-> ([RegexAction] -> RegexAction) -> [RegexAction] -> [RegexAction]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [RegexAction] -> RegexAction
Backword ([RegexAction] -> RegexAction)
-> ([RegexAction] -> [RegexAction]) -> [RegexAction] -> RegexAction
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [RegexAction] -> [RegexAction]
forall a. [a] -> [a]
reverse ([RegexAction] -> [RegexAction])
-> ([RegexAction] -> [RegexAction])
-> [RegexAction]
-> [RegexAction]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (RegexAction -> RegexAction) -> [RegexAction] -> [RegexAction]
forall a b. (a -> b) -> [a] -> [b]
map RegexAction -> RegexAction
reverseRegexAction )
 , ( [Char]
"?<!", [RegexAction] -> RegexAction
Still ([RegexAction] -> RegexAction)
-> ([RegexAction] -> [RegexAction]) -> [RegexAction] -> RegexAction
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (RegexAction -> [RegexAction] -> [RegexAction]
forall a. a -> [a] -> [a]
:[]) (RegexAction -> [RegexAction])
-> ([RegexAction] -> RegexAction) -> [RegexAction] -> [RegexAction]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [RegexAction] -> RegexAction
RegActNot ([RegexAction] -> RegexAction)
-> ([RegexAction] -> [RegexAction]) -> [RegexAction] -> RegexAction
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (RegexAction -> [RegexAction] -> [RegexAction]
forall a. a -> [a] -> [a]
:[]) (RegexAction -> [RegexAction])
-> ([RegexAction] -> RegexAction) -> [RegexAction] -> [RegexAction]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [RegexAction] -> RegexAction
Backword ([RegexAction] -> RegexAction)
-> ([RegexAction] -> [RegexAction]) -> [RegexAction] -> RegexAction
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [RegexAction] -> [RegexAction]
forall a. [a] -> [a]
reverse
                                              ([RegexAction] -> [RegexAction])
-> ([RegexAction] -> [RegexAction])
-> [RegexAction]
-> [RegexAction]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (RegexAction -> RegexAction) -> [RegexAction] -> [RegexAction]
forall a b. (a -> b) -> [a] -> [b]
map RegexAction -> RegexAction
reverseRegexAction  )
 , ( [Char]
"?=",  [RegexAction] -> RegexAction
Still                                                       )
 , ( [Char]
"?!",  [RegexAction] -> RegexAction
Still ([RegexAction] -> RegexAction)
-> ([RegexAction] -> [RegexAction]) -> [RegexAction] -> RegexAction
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (RegexAction -> [RegexAction] -> [RegexAction]
forall a. a -> [a] -> [a]
:[]) (RegexAction -> [RegexAction])
-> ([RegexAction] -> RegexAction) -> [RegexAction] -> [RegexAction]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [RegexAction] -> RegexAction
RegActNot                                   )
 , ( [Char]
"?:",  [RegexAction] -> RegexAction
Parens                                                      )
 , ( [Char]
"?>",  [RegexAction] -> RegexAction
NoBacktrack                                                 )
 , ( [Char]
"$>",  [RegexAction] -> RegexAction
NoBacktrack                                                 )
 ]

charClassList :: [ (String, Char -> Bool) ]
charClassList :: [([Char], Char -> Bool)]
charClassList = [
   ( [Char]
"alnum" , Char -> Bool
isAlphaNum                 )
 , ( [Char]
"alpha" , Char -> Bool
isAlpha                    )
 , ( [Char]
"blank" , Char -> Bool
isSpace                    )
 , ( [Char]
"cntrl" , Char -> Bool
isControl                  )
 , ( [Char]
"digit" , Char -> Bool
isDigit                    )
 , ( [Char]
"graph" , Char -> Bool
isPrint (Char -> Bool) -> (Char -> Bool) -> Char -> Bool
forall a. (a -> Bool) -> (a -> Bool) -> a -> Bool
&&& (Bool -> Bool
not(Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) Char -> Bool
isSpace )
 , ( [Char]
"lower" , Char -> Bool
isLower                    )
 , ( [Char]
"print" , Char -> Bool
isPrint                    )
 , ( [Char]
"punct" , Char -> Bool
isSymbol                   )
 , ( [Char]
"space" , Char -> Bool
isSpace                    )
 , ( [Char]
"upper" , Char -> Bool
isUpper                    )
 , ( [Char]
"xdigit", Char -> Bool
isHexDigit                 )
 ]

isWord :: Char -> Bool
isWord :: Char -> Bool
isWord = Char -> Bool
isAlphaNum (Char -> Bool) -> (Char -> Bool) -> Char -> Bool
forall a. (a -> Bool) -> (a -> Bool) -> a -> Bool
||| (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
==Char
'_')

regexOr :: [[RegexAction]] -> RegexAction
regexOr :: [[RegexAction]] -> RegexAction
regexOr = [RegexAction] -> RegexAction
forall a. HasCallStack => [a] -> a
head ([RegexAction] -> RegexAction)
-> ([[RegexAction]] -> [RegexAction])
-> [[RegexAction]]
-> RegexAction
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([RegexAction] -> [RegexAction] -> [RegexAction])
-> [[RegexAction]] -> [RegexAction]
forall a. (a -> a -> a) -> [a] -> a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 (\[RegexAction]
ra1 [RegexAction]
ra2 -> [[RegexAction] -> [RegexAction] -> RegexAction
RegexOr [RegexAction]
ra1 [RegexAction]
ra2])

lookBehind :: [RegexAction] -> RegexAction
lookBehind :: [RegexAction] -> RegexAction
lookBehind [RegexAction]
ras = [RegexAction] -> RegexAction
Still [[RegexAction] -> RegexAction
Backword [RegexAction]
ras]

selectNot :: (Char -> Bool) -> RegexAction
selectNot :: (Char -> Bool) -> RegexAction
selectNot Char -> Bool
s = (Char -> Bool) -> RegexAction
Select (Bool -> Bool
not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
s)