module Parser.Utils where

import Parser.Lexer
import Text.Megaparsec (between, choice, optional, try)

-- * Parser Utilities

-- ** Backtracking support

choice' :: (Foldable f, Functor f) => f (Parser a) -> Parser a
choice' :: forall (f :: * -> *) a.
(Foldable f, Functor f) =>
f (Parser a) -> Parser a
choice' f (Parser a)
ps = f (Parser a) -> Parser a
forall (f :: * -> *) (m :: * -> *) a.
(Foldable f, Alternative m) =>
f (m a) -> m a
choice (f (Parser a) -> Parser a) -> f (Parser a) -> Parser a
forall a b. (a -> b) -> a -> b
$ Parser a -> Parser a
forall a.
ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Parser a -> Parser a) -> f (Parser a) -> f (Parser a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f (Parser a)
ps

optional' :: Parser a -> Parser (Maybe a)
optional' :: forall a. Parser a -> Parser (Maybe a)
optional' = ParsecT Void Text Identity a
-> ParsecT Void Text Identity (Maybe a)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (ParsecT Void Text Identity a
 -> ParsecT Void Text Identity (Maybe a))
-> (ParsecT Void Text Identity a -> ParsecT Void Text Identity a)
-> ParsecT Void Text Identity a
-> ParsecT Void Text Identity (Maybe a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall a.
ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try

-- ** Parenthesis

-- | Wraps the given parser with parenthesis.
parens :: Parser a -> Parser a
parens :: forall a.
ParsecT Void Text Identity a -> ParsecT Void Text Identity a
parens = ParsecT Void Text Identity Text
-> ParsecT Void Text Identity Text
-> ParsecT Void Text Identity a
-> ParsecT Void Text Identity a
forall (m :: * -> *) open close a.
Applicative m =>
m open -> m close -> m a -> m a
between ParsecT Void Text Identity Text
leftPar ParsecT Void Text Identity Text
rightPar

manyParens :: Parser a -> Parser a
manyParens :: forall a.
ParsecT Void Text Identity a -> ParsecT Void Text Identity a
manyParens Parser a
p = [Parser a] -> Parser a
forall (f :: * -> *) a.
(Foldable f, Functor f) =>
f (Parser a) -> Parser a
choice' [Parser a
p, Parser a -> Parser a
forall a.
ParsecT Void Text Identity a -> ParsecT Void Text Identity a
someParens Parser a
p]

someParens :: Parser a -> Parser a
someParens :: forall a.
ParsecT Void Text Identity a -> ParsecT Void Text Identity a
someParens Parser a
p = Parser a -> Parser a
forall a.
ParsecT Void Text Identity a -> ParsecT Void Text Identity a
parens (Parser a -> Parser a) -> Parser a -> Parser a
forall a b. (a -> b) -> a -> b
$ [Parser a] -> Parser a
forall (f :: * -> *) a.
(Foldable f, Functor f) =>
f (Parser a) -> Parser a
choice' [Parser a
p, Parser a -> Parser a
forall a.
ParsecT Void Text Identity a -> ParsecT Void Text Identity a
someParens Parser a
p]