module Text.Syntax.Poly.Combinators (
this,
list,
none,
many,
some,
replicate,
sepBy, sepBy1,
chainl1,
count,
skipMany,
skipSome,
(*>),
(<*),
between,
(<+>), choice,
optional, bool,
(<$?>), (<?$>),
format
) where
#if __GLASGOW_HASKELL__ < 710
import Prelude hiding (foldl, succ, replicate, (.))
#else
import Prelude hiding (foldl, succ, replicate, (.), (<$>), (<*>), (<*), (*>))
#endif
import Control.Isomorphism.Partial.Ext
(nothing, just, nil, cons, left, right, foldl,
(.), Iso, (<$>), inverse, element, unit, commute, ignore,
mayAppend, mayPrepend, succ)
import Text.Syntax.Poly.Class
((<*>), (<|>), empty,
AbstractSyntax(syntax), Syntax(token))
none :: AbstractSyntax delta => delta [alpha]
none = nil <$> syntax ()
many :: AbstractSyntax delta => delta alpha -> delta [alpha]
many p = some p <|> none
some :: AbstractSyntax delta => delta alpha -> delta [alpha]
some p = cons <$> p <*> many p
replicate :: AbstractSyntax delta => Int -> delta alpha -> delta [alpha]
replicate n' p = rec n' where
rec n | n <= 0 = none
| otherwise = cons <$> p <*> rec (n 1)
infixl 4 <+>
(<+>) :: AbstractSyntax delta => delta alpha -> delta beta -> delta (Either alpha beta)
p <+> q = (left <$> p) <|> (right <$> q)
this :: (Syntax tok delta, Eq tok) => tok -> delta ()
this t = inverse (element t) <$> token
list :: (Syntax tok delta, Eq tok) => [tok] -> delta ()
list [] = syntax ()
list (c:cs) = inverse (element ((), ()))
<$> this c
<*> list cs
(*>) :: AbstractSyntax delta => delta () -> delta alpha -> delta alpha
p *> q = inverse unit . commute <$> p <*> q
(<*) :: AbstractSyntax delta => delta alpha -> delta () -> delta alpha
p <* q = inverse unit <$> p <*> q
infixl 7 *>, <*
between :: AbstractSyntax delta => delta () -> delta () -> delta alpha -> delta alpha
between p q r = p *> r <* q
chainl1 :: AbstractSyntax delta =>
delta alpha -> delta beta -> Iso (alpha, (beta, alpha)) alpha -> delta alpha
chainl1 arg op f
= foldl f <$> arg <*> many (op <*> arg)
count :: (Eq beta, Enum beta, AbstractSyntax delta) => delta () -> delta beta
count p = succ <$> p *> count p <|> syntax (toEnum 0)
skipMany :: AbstractSyntax delta => delta alpha -> delta ()
skipMany p = ignore [] <$> many p
skipSome :: AbstractSyntax delta => delta alpha -> delta alpha
skipSome p = p <* skipMany p
choice :: AbstractSyntax delta => [delta alpha] -> delta alpha
choice (s:ss) = s <|> choice ss
choice [] = empty
optional :: AbstractSyntax delta => delta alpha -> delta (Maybe alpha)
optional x = just <$> x <|> nothing <$> syntax ()
bool :: AbstractSyntax delta => delta () -> delta Bool
bool x = x *> syntax True <|> syntax False
sepBy :: AbstractSyntax delta => delta alpha -> delta () -> delta [alpha]
sepBy x sep
= x `sepBy1` sep
<|> none
sepBy1 :: AbstractSyntax delta => delta alpha -> delta () -> delta [alpha]
sepBy1 x sep = cons <$> x <*> many (sep *> x)
(<$?>) :: AbstractSyntax delta => Iso (a, b) a -> delta (a, Maybe b) -> delta a
cf <$?> pair = mayAppend cf <$> pair
(<?$>) :: AbstractSyntax delta => Iso (a, b) b -> delta (Maybe a, b) -> delta b
cf <?$> pair = mayPrepend cf <$> pair
infix 5 <$?>, <?$>
format :: (Syntax tok delta, Eq tok) => [tok] -> delta ()
format tks = ignore (Just ()) <$> optional (list tks)