module Text.Regex.Less
( (=~),(<<),
truth,subs,subg,derefs,bref,matchN)
where
import qualified Text.Regex.PCRE as R
import qualified Data.Array.IArray as A
import Text.Regex.Less.Quackers
type Match = (String,[R.MatchArray])
infixl 4 =~
(=~) :: QLR a => String -> a -> Match
a =~ b = a << execute b a
infixl 5 <<
(<<) :: a -> b -> (a,b)
a << b = (a,b)
truth :: Match -> Bool
truth (_,a) = not (null a)
subs :: Match -> String -> String
subs a b = s ++ derefs (bref a) b ++ f
where o = fst a
(i,c) = head (snd a) A.! 0
(s,r) = splitAt i o
f = drop c r
subg :: Match -> String -> String
subg a b = subg' o (decay (map A.elems m)) b
where (o,m) = a
subg' :: String -> [[(Int,Int)]] -> String -> String
subg' ors (cur@((ini,chs):_):ms) sub =
take ini ors ++ derefs bref' sub
++ subg' (drop (ini + chs) ors) ms sub
where bref' a = R.extract (cur !! a) ors
subg' _ _ _ = []
decay :: [[(Int,Int)]] -> [[(Int,Int)]]
decay (x:xs) = x : decay rest
where rest = map (map proc) xs
proc (a,b) = a uncurry (+) (head x) << b
decay [] = []
derefs :: (Int -> String) -> String -> String
derefs f ('`':'`':bs) = '`' : derefs f bs
derefs f ('`':'.':bs) = derefs f bs
derefs f ('`':bs) =
case reads bs of
[(c,d)] -> f c ++ derefs f d
_ -> undefined
derefs f (b:bs) = b : derefs f bs
derefs _ [] = []
bref :: Match -> Int -> String
bref a i = R.extract (head (snd a) A.! i) (fst a)
matchN :: Match -> Int -> Match
matchN (a,b) i = (a,[b !! i])