module Text.Syntax.Combinators
(
text
, comma
, dot
, many
, many1
, sepBy
, chainl1
, (*>)
, (<*)
, between
, (<+>)
, optional
, skipSpace
, sepSpace
, optSpace) where
import Prelude (String)
import Control.Category ((.))
import Control.Isomorphism.Partial.Constructors (nothing, just, nil, cons, left, right)
import Control.Isomorphism.Partial.Derived (foldl)
import Control.Isomorphism.Partial.Prim (Iso, (<$>), inverse, element, unit, commute, ignore)
import Data.Maybe (Maybe)
import Data.Either (Either)
import Text.Syntax.Classes
many :: Syntax delta => delta alpha -> delta [alpha]
many p
= nil <$> pure ()
<|> cons <$> p
<*> many p
many1 :: Syntax delta => delta alpha -> delta [alpha]
many1 p = cons <$> p <*> many p
infixl 4 <+>
(<+>) :: Syntax delta => delta alpha -> delta beta -> delta (Either alpha beta)
p <+> q = (left <$> p) <|> (right <$> q)
text :: Syntax delta => String -> delta ()
text [] = pure ()
text (c:cs) = inverse (element ((), ()))
<$> (inverse (element c) <$> token)
<*> text cs
(*>) :: Syntax delta => delta () -> delta alpha -> delta alpha
p *> q = inverse unit . commute <$> p <*> q
(<*) :: Syntax delta => delta alpha -> delta () -> delta alpha
p <* q = inverse unit <$> p <*> q
between :: Syntax delta => delta () -> delta () -> delta alpha -> delta alpha
between p q r = p *> r <* q
chainl1 :: Syntax delta => delta alpha -> delta beta -> Iso (alpha, (beta, alpha)) alpha -> delta alpha
chainl1 arg op f
= foldl f <$> arg <*> many (op <*> arg)
optional :: Syntax delta => delta alpha -> delta (Maybe alpha)
optional x = just <$> x <|> nothing <$> text ""
sepBy :: Syntax delta => delta alpha -> delta () -> delta [alpha]
sepBy x sep
= nil <$> text ""
<|> cons <$> x <*> many (sep *> x)
comma :: Syntax delta => delta ()
comma = text ","
dot :: Syntax delta => delta ()
dot = text "."
skipSpace :: Syntax delta => delta ()
skipSpace = ignore [] <$> many (text " ")
optSpace :: Syntax delta => delta ()
optSpace = ignore [()] <$> many (text " ")
sepSpace :: Syntax delta => delta ()
sepSpace = text " " <* skipSpace