--	SrcRegActList.hs
--
--	Author: Yoshikuni Jujo <PAF01143@nifty.ne.jp>
--

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

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

plusesList :: [ (String, RegexAction -> RegexAction) ]
plusesList = [
   ( ""  , id )
 , ( "*" , Repeat          0 Nothing  )
 , ( "*?", RepeatNotGreedy 0 Nothing  )
 , ( "+" , Repeat          1 Nothing  )
 , ( "+?", RepeatNotGreedy 1 Nothing  )
 , ( "?" , Repeat          0 $ Just 1 )
 , ( "??", RepeatNotGreedy 0 $ Just 1 )
 ]

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

backSlashesList :: [ (Char, RegexAction) ]
backSlashesList = [
   ( 'w', Select isAlphaNum                                          )
 , ( 'W', Select (not . isAlphaNum)                                  )
 , ( 's', Select (flip elem " \t\n\r\f")                             )
 , ( 'S', Select (flip notElem " \t\n\r\f")                          )
 , ( 'd', Select isDigit                                             )
 , ( 'D', Select (not . isDigit)                                     )
 , ( 'A', BeginningOfInput                                           )
 , ( 'Z', RegexOr [EndOfInput] [Still [Select (=='\n'), EndOfInput]] )
 , ( 'z', EndOfInput                                                 )
 , ( 'b', regexOr [
            [ lookBehind [Select    isAlphaNum], Still [selectNot isAlphaNum] ]
	  , [ lookBehind [selectNot isAlphaNum], Still [Select    isAlphaNum] ]
	  , [ BeginningOfInput, Still [Select isAlphaNum] ]
	  , [ lookBehind [Select isAlphaNum], EndOfInput ]
	  ]                                                          )
 , ( 'B', RegActNot [ regexOr [
            [ lookBehind [Select    isAlphaNum], Still [selectNot isAlphaNum] ]
	  , [ lookBehind [selectNot isAlphaNum], Still [Select    isAlphaNum] ]
	  , [ BeginningOfInput, Still [Select isAlphaNum] ]
	  , [ lookBehind [Select isAlphaNum], EndOfInput ]
	  ] ]                                                        )
 , ( 'G', PreMatchPoint                                              )
 ]

parensesList :: [ (String, [RegexAction] -> RegexAction) ]
parensesList = [
   ( "?<=", Still . (:[]) . Backword . reverse . map reverseRegexAction )
 , ( "?=",  Still                                                       )
 , ( "?!",  Still . (:[]) . RegActNot                                   )
 , ( "?:",  Parens                                                      )
 ]

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

regexOr :: [[RegexAction]] -> RegexAction
regexOr = head . foldr1 (\ra1 ra2 -> [RegexOr ra1 ra2])

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

selectNot :: (Char -> Bool) -> RegexAction
selectNot s = Select (not . s)