content: {-# LANGUAGE PatternSynonyms #-}
  module Parsley.Internal.Core.Primitives (
      Parser,
      Reg,
      module Parsley.Internal.Core.Primitives
    ) where
  
  import Prelude hiding                      (pure, (<*>))
  import Parsley.Internal.Core.CombinatorAST (Combinator(..), ScopeRegister(..), Reg(..), Parser(..), PosSelector(..))
  import Parsley.Internal.Core.Defunc        (Defunc, charPred)
  
  import Parsley.Internal.Common.Indexed     (Fix(In), (:+:)(..))
  
  -- Core smart constructors
  {-# INLINE pure #-}
  pure :: Defunc a -> Parser a
  pure = Parser . In . L . Pure
  
  {-# INLINE satisfy #-}
  satisfy :: Defunc (Char -> Bool) -> Parser Char
  satisfy = Parser . In . L . Satisfy . charPred
  
  {-# INLINE conditional #-}
  conditional :: [(Defunc (a -> Bool), Parser b)] -> Parser a -> Parser b -> Parser b
  conditional cs (Parser p) (Parser def) =
    let (fs, qs) = unzip cs
    in Parser (In (L (Match p fs (map unParser qs) def)))
  
  {-# INLINE (<*>) #-}
  (<*>) :: Parser (a -> b) -> Parser a -> Parser b
  Parser p <*> Parser q = Parser (In (L (p :<*>: q)))
  
  {-# INLINE (<*) #-}
  (<*) :: Parser a -> Parser b -> Parser a
  Parser p <* Parser q = Parser (In (L (p :<*: q)))
  
  {-# INLINE (*>) #-}
  (*>) :: Parser a -> Parser b -> Parser b
  Parser p *> Parser q = Parser (In (L (p :*>: q)))
  
  {-# INLINE empty #-}
  empty :: Parser a
  empty = Parser (In (L Empty))
  
  {-# INLINE (<|>) #-}
  (<|>) :: Parser a -> Parser a -> Parser a
  Parser p <|> Parser q = Parser (In (L (p :<|>: q)))
  
  {-# INLINE lookAhead #-}
  lookAhead :: Parser a -> Parser a
  lookAhead = Parser . In . L . LookAhead . unParser
  
  {-# INLINE notFollowedBy #-}
  notFollowedBy :: Parser a -> Parser ()
  notFollowedBy = Parser . In . L . NotFollowedBy . unParser
  
  {-# INLINE try #-}
  try :: Parser a -> Parser a
  try = Parser . In . L . Try . unParser
  
  {-# INLINE branch #-}
  branch :: Parser (Either a b) -> Parser (a -> c) -> Parser (b -> c) -> Parser c
  branch (Parser c) (Parser p) (Parser q) = Parser (In (L (Branch c p q)))
  
  {-# INLINE loop #-}
  loop :: Parser () -> Parser a -> Parser a
  loop (Parser body) (Parser exit) = Parser (In (L (Loop body exit)))
  
  {-# INLINE newRegister #-}
  newRegister :: Parser a -> (forall r. Reg r a -> Parser b) -> Parser b
  newRegister (Parser p) f = Parser (In (R (ScopeRegister p (unParser . f))))
  
  {-# INLINE get #-}
  get :: Reg r a -> Parser a
  get (Reg reg) = Parser (In (L (GetRegister reg)))
  
  {-# INLINE put #-}
  put :: Reg r a -> Parser a -> Parser ()
  put (Reg reg) (Parser p) = Parser (In (L (PutRegister reg p)))
  
  {-# INLINE line #-}
  line :: Parser Int
  line = Parser (In (L (Position Line)))
  
  {-# INLINE col #-}
  col :: Parser Int
  col = Parser (In (L (Position Col)))
  
  {-# INLINE debug #-}
  debug :: String -> Parser a -> Parser a
  debug name (Parser p) = Parser (In (L (Debug name p)))
  