-- |
--
-- Module:      Language.Egison.Parser.Pattern.Combinator
-- Description: Useful combinators to build lexeme parsers
-- Stability:   experimental
--
-- A helper module to build lexeme parsers.
--
-- Note that functions exported from this module produce lexeme parsers (i.e. skip spaces after that),
-- while parsers from 'Language.Egison.Pattern.Parser.Prim' do not.

module Language.Egison.Parser.Pattern.Combinator
  ( token
  , symbol
  , parens
  )
where

import           Control.Monad.Combinators      ( between )
import           Data.Functor                   ( void )

import           Language.Egison.Parser.Pattern.Prim
                                                ( Parse
                                                , Source
                                                , Token
                                                , Tokens
                                                , lexeme
                                                , single
                                                , chunk
                                                )
import qualified Language.Egison.Parser.Pattern.Token
                                               as Token
                                                ( parenLeft
                                                , parenRight
                                                )


-- | Parser for a single token.
token :: Source s => Token s -> Parse n v e s ()
token :: Token s -> Parse n v e s ()
token = Parse n v e s (Token s) -> Parse n v e s ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (Parse n v e s (Token s) -> Parse n v e s ())
-> (Token s -> Parse n v e s (Token s))
-> Token s
-> Parse n v e s ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Parse n v e s (Token s) -> Parse n v e s (Token s)
forall s n v e a. Source s => Parse n v e s a -> Parse n v e s a
lexeme (Parse n v e s (Token s) -> Parse n v e s (Token s))
-> (Token s -> Parse n v e s (Token s))
-> Token s
-> Parse n v e s (Token s)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Token s -> Parse n v e s (Token s)
forall e s (m :: * -> *).
MonadParsec e s m =>
Token s -> m (Token s)
single

-- | Parser for a chunk of tokens.
symbol :: Source s => Tokens s -> Parse n v e s ()
symbol :: Tokens s -> Parse n v e s ()
symbol = Parse n v e s (Tokens s) -> Parse n v e s ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (Parse n v e s (Tokens s) -> Parse n v e s ())
-> (Tokens s -> Parse n v e s (Tokens s))
-> Tokens s
-> Parse n v e s ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Parse n v e s (Tokens s) -> Parse n v e s (Tokens s)
forall s n v e a. Source s => Parse n v e s a -> Parse n v e s a
lexeme (Parse n v e s (Tokens s) -> Parse n v e s (Tokens s))
-> (Tokens s -> Parse n v e s (Tokens s))
-> Tokens s
-> Parse n v e s (Tokens s)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Tokens s -> Parse n v e s (Tokens s)
forall e s (m :: * -> *).
MonadParsec e s m =>
Tokens s -> m (Tokens s)
chunk

-- | Wrap a parser with parentheses.
parens :: Source s => Parse n v e s a -> Parse n v e s a
parens :: Parse n v e s a -> Parse n v e s a
parens = Parse n v e s ()
-> Parse n v e s () -> Parse n v e s a -> Parse n v e s a
forall (m :: * -> *) open close a.
Applicative m =>
m open -> m close -> m a -> m a
between (Token s -> Parse n v e s ()
forall s n v e. Source s => Token s -> Parse n v e s ()
token Token s
forall c. IsToken c => c
Token.parenLeft) (Token s -> Parse n v e s ()
forall s n v e. Source s => Token s -> Parse n v e s ()
token Token s
forall c. IsToken c => c
Token.parenRight)