module Text.Flow.Combinators where

import Control.Arrow
import Text.Flow.Parser
import Text.Flow.Token

empty :: (Token t) => AP t i o
empty = PEmpty

many :: (Token t) => AP t i o -> AP t i [o]
many = PStar

many1 :: (Token t) => AP t i o -> AP t i [o]
many1 x = (x &&& PStar x) >>> arr (\(b,bs) -> (b:bs))

notFollowedBy :: (Token t) => AP t i o -> AP t i o
notFollowedBy = PNot

sepBy1 :: (Token t) => AP t i o -> AP t i o' -> AP t i [o]
sepBy1 p s = (many (p &&& s >>^ fst) &&& p) >>^ (\(bs,b) -> bs++[b])

between :: (Token t) => AP t i p -> AP t p c -> AP t p o -> AP t i o
between open close p = open >>> (p &&& close) >>^ fst

optional :: (Token t) => AP t i o -> AP t i (Maybe o)
optional p = PChoice [p >>> PPrim Just, PPrim $ const Nothing]

(>>!) :: (Arrow a) => a b c -> a b d -> a b c
a >>! b = (a &&& b) >>^ fst
