{-# LANGUAGE PatternSynonyms, CPP #-}
{-|
Module      : Parsley.Fold
Description : The "folding" combinators: chains and iterators
License     : BSD-3-Clause
Maintainer  : Jamie Willis
Stability   : stable

This module contains the combinator concerned with some form of iteration or input folding. Notably,
this includes the traditional `many` and `some` combinators.

@since 0.1.0.0
-}
module Parsley.Fold (
    many, some, manyN,
    skipMany, skipSome, skipManyN, --loop,
    sepBy, sepBy1, endBy, endBy1, sepEndBy, sepEndBy1,
    chainl1, chainr1, chainl, chainr,
    chainl1', chainr1', chainPre, chainPost,
    pfoldr, pfoldl,
    pfoldr1, pfoldl1
  ) where

import Prelude hiding           (pure, (<*>), (<$>), (*>), (<*))
import Parsley.Alternative      ((<|>), option)
import Parsley.Applicative      (pure, (<*>), (<$>), (*>), (<*), (<:>), (<**>), void)
import Parsley.Defunctionalized (Defunc(FLIP, ID, COMPOSE, EMPTY, CONS, CONST), pattern FLIP_H, pattern COMPOSE_H, pattern UNIT)
import Parsley.Internal         (Parser)
import Parsley.ParserOps        (ParserOps)
#if MIN_VERSION_parsley_core(1,7,1)
import Parsley.Register         (bind, get, put, modify, newRegister, newRegister_)
#else
import Parsley.Register         (bind, get, modify, newRegister_)
#endif

#if MIN_VERSION_parsley_core(1,7,1)
import qualified Parsley.Internal as Internal (loop)
#else
import qualified Parsley.Internal as Internal (chainPre, chainPost)
#endif

#if MIN_VERSION_parsley_core(1,7,1)
{-|
The combinator @loop body exit@ parses @body@ zero or more times until it fails. If the final @body@
failed having not consumed input, @exit@ is performed, otherwise the combinator fails:

> loop body exit = let go = body *> go <|> exit in go

@since 1.1.0.0
-}
loop :: Parser () -> Parser a -> Parser a
loop :: Parser () -> Parser a -> Parser a
loop = Parser () -> Parser a -> Parser a
forall a. Parser () -> Parser a -> Parser a
Internal.loop

{-|
This combinator parses repeated applications of an operator to a single final operand. This is
primarily used to parse prefix operators in expressions.

@since 0.1.0.0
-}
chainPre :: Parser (a -> a) -> Parser a -> Parser a
chainPre :: Parser (a -> a) -> Parser a -> Parser a
chainPre Parser (a -> a)
op Parser a
p =
  Parser (a -> a)
-> (forall r. Reg r (a -> a) -> Parser (a -> a)) -> Parser (a -> a)
forall a b. Parser a -> (forall r. Reg r a -> Parser b) -> Parser b
newRegister (Defunc (a -> a) -> Parser (a -> a)
forall (rep :: Type -> Type) a. ParserOps rep => rep a -> Parser a
pure Defunc (a -> a)
forall a1. Defunc (a1 -> a1)
ID) (\Reg r (a -> a)
r ->
    Parser () -> Parser (a -> a) -> Parser (a -> a)
forall a. Parser () -> Parser a -> Parser a
loop (Reg r (a -> a) -> Parser (a -> a) -> Parser ()
forall r a. Reg r a -> Parser a -> Parser ()
put Reg r (a -> a)
r (Defunc ((a -> a) -> (a -> a) -> a -> a)
-> Parser ((a -> a) -> (a -> a) -> a -> a)
forall (rep :: Type -> Type) a. ParserOps rep => rep a -> Parser a
pure (Defunc ((a -> a) -> (a -> a) -> a -> a)
-> Defunc ((a -> a) -> (a -> a) -> a -> a)
forall y x a b c.
((x -> y) ~ ((a -> b -> c) -> b -> a -> c)) =>
Defunc x -> Defunc y
FLIP_H Defunc ((a -> a) -> (a -> a) -> a -> a)
forall b c a1. Defunc ((b -> c) -> (a1 -> b) -> a1 -> c)
COMPOSE) Parser ((a -> a) -> (a -> a) -> a -> a)
-> Parser (a -> a) -> Parser ((a -> a) -> a -> a)
forall a b. Parser (a -> b) -> Parser a -> Parser b
<*> Parser (a -> a)
op Parser ((a -> a) -> a -> a) -> Parser (a -> a) -> Parser (a -> a)
forall a b. Parser (a -> b) -> Parser a -> Parser b
<*> Reg r (a -> a) -> Parser (a -> a)
forall r a. Reg r a -> Parser a
get Reg r (a -> a)
r))
         (Reg r (a -> a) -> Parser (a -> a)
forall r a. Reg r a -> Parser a
get Reg r (a -> a)
r))
  Parser (a -> a) -> Parser a -> Parser a
forall a b. Parser (a -> b) -> Parser a -> Parser b
<*> Parser a
p

{-|
This combinator parses repeated applications of an operator to a single initial operand. This is
primarily used to parse postfix operators in expressions.

@since 0.1.0.0
-}
chainPost :: Parser a -> Parser (a -> a) -> Parser a
chainPost :: Parser a -> Parser (a -> a) -> Parser a
chainPost Parser a
p Parser (a -> a)
op =
  Parser a -> (forall r. Reg r a -> Parser a) -> Parser a
forall a b. Parser a -> (forall r. Reg r a -> Parser b) -> Parser b
newRegister Parser a
p ((forall r. Reg r a -> Parser a) -> Parser a)
-> (forall r. Reg r a -> Parser a) -> Parser a
forall a b. (a -> b) -> a -> b
$ \Reg r a
r ->
    Parser () -> Parser a -> Parser a
forall a. Parser () -> Parser a -> Parser a
loop (Reg r a -> Parser a -> Parser ()
forall r a. Reg r a -> Parser a -> Parser ()
put Reg r a
r (Parser (a -> a)
op Parser (a -> a) -> Parser a -> Parser a
forall a b. Parser (a -> b) -> Parser a -> Parser b
<*> Reg r a -> Parser a
forall r a. Reg r a -> Parser a
get Reg r a
r))
         (Reg r a -> Parser a
forall r a. Reg r a -> Parser a
get Reg r a
r)
#else
{-|
This combinator parses repeated applications of an operator to a single final operand. This is
primarily used to parse prefix operators in expressions.

@since 0.1.0.0
-}
chainPre :: Parser (a -> a) -> Parser a -> Parser a
chainPre = Internal.chainPre

{-|
This combinator parses repeated applications of an operator to a single initial operand. This is
primarily used to parse postfix operators in expressions.

@since 0.1.0.0
-}
chainPost :: Parser a -> Parser (a -> a) -> Parser a
chainPost = Internal.chainPost
#endif

-- Parser Folds
{-|
@pfoldr f k p@ parses __zero__ or more @p@s and combines the results using the function @f@. When @p@
fails without consuming input, the terminal result @k@ is returned.

> many = pfoldr CONS EMPTY

@since 0.1.0.0
-}
pfoldr :: (ParserOps repf, ParserOps repk) => repf (a -> b -> b) -> repk b -> Parser a -> Parser b
pfoldr :: repf (a -> b -> b) -> repk b -> Parser a -> Parser b
pfoldr repf (a -> b -> b)
f repk b
k Parser a
p = Parser (b -> b) -> Parser b -> Parser b
forall a. Parser (a -> a) -> Parser a -> Parser a
chainPre (repf (a -> b -> b)
f repf (a -> b -> b) -> Parser a -> Parser (b -> b)
forall (rep :: Type -> Type) a b.
ParserOps rep =>
rep (a -> b) -> Parser a -> Parser b
<$> Parser a
p) (repk b -> Parser b
forall (rep :: Type -> Type) a. ParserOps rep => rep a -> Parser a
pure repk b
k)

{-|
@pfoldr1 f k p@ parses __one__ or more @p@s and combines the results using the function @f@. When @p@
fails without consuming input, the terminal result @k@ is returned.

> some = pfoldr1 CONS EMPTY

@since 0.1.0.0
-}
pfoldr1 :: (ParserOps repf, ParserOps repk) => repf (a -> b -> b) -> repk b -> Parser a -> Parser b
pfoldr1 :: repf (a -> b -> b) -> repk b -> Parser a -> Parser b
pfoldr1 repf (a -> b -> b)
f repk b
k Parser a
p = repf (a -> b -> b)
f repf (a -> b -> b) -> Parser a -> Parser (b -> b)
forall (rep :: Type -> Type) a b.
ParserOps rep =>
rep (a -> b) -> Parser a -> Parser b
<$> Parser a
p Parser (b -> b) -> Parser b -> Parser b
forall a b. Parser (a -> b) -> Parser a -> Parser b
<*> repf (a -> b -> b) -> repk b -> Parser a -> Parser b
forall (repf :: Type -> Type) (repk :: Type -> Type) a b.
(ParserOps repf, ParserOps repk) =>
repf (a -> b -> b) -> repk b -> Parser a -> Parser b
pfoldr repf (a -> b -> b)
f repk b
k Parser a
p

{-|
@pfoldl f k p@ parses __zero__ or more @p@s and combines the results using the function @f@. The
accumulator is initialised with the value @k@.

@since 0.1.0.0
-}
pfoldl :: (ParserOps repf, ParserOps repk) => repf (b -> a -> b) -> repk b -> Parser a -> Parser b
pfoldl :: repf (b -> a -> b) -> repk b -> Parser a -> Parser b
pfoldl repf (b -> a -> b)
f repk b
k Parser a
p = Parser b -> Parser (b -> b) -> Parser b
forall a. Parser a -> Parser (a -> a) -> Parser a
chainPost (repk b -> Parser b
forall (rep :: Type -> Type) a. ParserOps rep => rep a -> Parser a
pure repk b
k) ((Defunc ((b -> a -> b) -> a -> b -> b)
forall a1 b c. Defunc ((a1 -> b -> c) -> b -> a1 -> c)
FLIP Defunc ((b -> a -> b) -> a -> b -> b)
-> Parser (b -> a -> b) -> Parser (a -> b -> b)
forall (rep :: Type -> Type) a b.
ParserOps rep =>
rep (a -> b) -> Parser a -> Parser b
<$> repf (b -> a -> b) -> Parser (b -> a -> b)
forall (rep :: Type -> Type) a. ParserOps rep => rep a -> Parser a
pure repf (b -> a -> b)
f) Parser (a -> b -> b) -> Parser a -> Parser (b -> b)
forall a b. Parser (a -> b) -> Parser a -> Parser b
<*> Parser a
p)

{-|
@pfoldl1 f k p@ parses __one__ or more @p@s and combines the results using the function @f@. The
accumulator is initialised with the value @k@.

@since 0.1.0.0
-}
pfoldl1 :: (ParserOps repf, ParserOps repk) => repf (b -> a -> b) -> repk b -> Parser a -> Parser b
pfoldl1 :: repf (b -> a -> b) -> repk b -> Parser a -> Parser b
pfoldl1 repf (b -> a -> b)
f repk b
k Parser a
p = Parser b -> Parser (b -> b) -> Parser b
forall a. Parser a -> Parser (a -> a) -> Parser a
chainPost (repf (b -> a -> b)
f repf (b -> a -> b) -> Parser b -> Parser (a -> b)
forall (rep :: Type -> Type) a b.
ParserOps rep =>
rep (a -> b) -> Parser a -> Parser b
<$> repk b -> Parser b
forall (rep :: Type -> Type) a. ParserOps rep => rep a -> Parser a
pure repk b
k Parser (a -> b) -> Parser a -> Parser b
forall a b. Parser (a -> b) -> Parser a -> Parser b
<*> Parser a
p) ((Defunc ((b -> a -> b) -> a -> b -> b)
forall a1 b c. Defunc ((a1 -> b -> c) -> b -> a1 -> c)
FLIP Defunc ((b -> a -> b) -> a -> b -> b)
-> Parser (b -> a -> b) -> Parser (a -> b -> b)
forall (rep :: Type -> Type) a b.
ParserOps rep =>
rep (a -> b) -> Parser a -> Parser b
<$> repf (b -> a -> b) -> Parser (b -> a -> b)
forall (rep :: Type -> Type) a. ParserOps rep => rep a -> Parser a
pure repf (b -> a -> b)
f) Parser (a -> b -> b) -> Parser a -> Parser (b -> b)
forall a b. Parser (a -> b) -> Parser a -> Parser b
<*> Parser a
p)

-- Chain Combinators
{-|
@chainl1' wrap p op @ parses one or more occurrences of @p@, separated by @op@. Returns a value obtained
by a /left/ associative application of all functions returned by @op@ to the values returned by @p@.
The function @wrap@ is used to transform the initial value from @p@ into the correct form.

@since 0.1.0.0
-}
chainl1' :: ParserOps rep => rep (a -> b) -> Parser a -> Parser (b -> a -> b) -> Parser b
chainl1' :: rep (a -> b) -> Parser a -> Parser (b -> a -> b) -> Parser b
chainl1' rep (a -> b)
f Parser a
p Parser (b -> a -> b)
op = Parser b -> Parser (b -> b) -> Parser b
forall a. Parser a -> Parser (a -> a) -> Parser a
chainPost (rep (a -> b)
f rep (a -> b) -> Parser a -> Parser b
forall (rep :: Type -> Type) a b.
ParserOps rep =>
rep (a -> b) -> Parser a -> Parser b
<$> Parser a
p) (Defunc ((b -> a -> b) -> a -> b -> b)
forall a1 b c. Defunc ((a1 -> b -> c) -> b -> a1 -> c)
FLIP Defunc ((b -> a -> b) -> a -> b -> b)
-> Parser (b -> a -> b) -> Parser (a -> b -> b)
forall (rep :: Type -> Type) a b.
ParserOps rep =>
rep (a -> b) -> Parser a -> Parser b
<$> Parser (b -> a -> b)
op Parser (a -> b -> b) -> Parser a -> Parser (b -> b)
forall a b. Parser (a -> b) -> Parser a -> Parser b
<*> Parser a
p)

{-|
The classic version of the left-associative chain combinator. See 'chainl1''.

> chainl1 p op = chainl1' ID p op

@since 0.1.0.0
-}
chainl1 :: Parser a -> Parser (a -> a -> a) -> Parser a
chainl1 :: Parser a -> Parser (a -> a -> a) -> Parser a
chainl1 = Defunc (a -> a) -> Parser a -> Parser (a -> a -> a) -> Parser a
forall (rep :: Type -> Type) a b.
ParserOps rep =>
rep (a -> b) -> Parser a -> Parser (b -> a -> b) -> Parser b
chainl1' Defunc (a -> a)
forall a1. Defunc (a1 -> a1)
ID

{-|
@chainr1' wrap p op @ parses one or more occurrences of @p@, separated by @op@. Returns a value obtained
by a /right/ associative application of all functions returned by @op@ to the values returned by @p@.
The function @wrap@ is used to transform the final value from @p@ into the correct form.

@since 0.1.0.0
-}
chainr1' :: ParserOps rep => rep (a -> b) -> Parser a -> Parser (a -> b -> b) -> Parser b
chainr1' :: rep (a -> b) -> Parser a -> Parser (a -> b -> b) -> Parser b
chainr1' rep (a -> b)
f Parser a
p Parser (a -> b -> b)
op = Defunc (b -> b)
-> (forall r. Reg r (b -> b) -> Parser b) -> Parser b
forall (rep :: Type -> Type) a b.
ParserOps rep =>
rep a -> (forall r. Reg r a -> Parser b) -> Parser b
newRegister_ Defunc (b -> b)
forall a1. Defunc (a1 -> a1)
ID ((forall r. Reg r (b -> b) -> Parser b) -> Parser b)
-> (forall r. Reg r (b -> b) -> Parser b) -> Parser b
forall a b. (a -> b) -> a -> b
$ \Reg r (b -> b)
acc ->
  let go :: Parser b
go = Parser a -> (Parser a -> Parser b) -> Parser b
forall a b. Parser a -> (Parser a -> Parser b) -> Parser b
bind Parser a
p ((Parser a -> Parser b) -> Parser b)
-> (Parser a -> Parser b) -> Parser b
forall a b. (a -> b) -> a -> b
$ \Parser a
x ->
           Reg r (b -> b) -> Parser ((b -> b) -> b -> b) -> Parser ()
forall r a. Reg r a -> Parser (a -> a) -> Parser ()
modify Reg r (b -> b)
acc (Defunc ((b -> b) -> (b -> b) -> b -> b)
-> Defunc ((b -> b) -> (b -> b) -> b -> b)
forall y x a b c.
((x -> y) ~ ((a -> b -> c) -> b -> a -> c)) =>
Defunc x -> Defunc y
FLIP_H Defunc ((b -> b) -> (b -> b) -> b -> b)
forall b c a1. Defunc ((b -> c) -> (a1 -> b) -> a1 -> c)
COMPOSE Defunc ((b -> b) -> (b -> b) -> b -> b)
-> Parser (b -> b) -> Parser ((b -> b) -> b -> b)
forall (rep :: Type -> Type) a b.
ParserOps rep =>
rep (a -> b) -> Parser a -> Parser b
<$> (Parser (a -> b -> b)
op Parser (a -> b -> b) -> Parser a -> Parser (b -> b)
forall a b. Parser (a -> b) -> Parser a -> Parser b
<*> Parser a
x)) Parser () -> Parser b -> Parser b
forall a b. Parser a -> Parser b -> Parser b
*> Parser b
go
       Parser b -> Parser b -> Parser b
forall a. Parser a -> Parser a -> Parser a
<|> rep (a -> b)
f rep (a -> b) -> Parser a -> Parser b
forall (rep :: Type -> Type) a b.
ParserOps rep =>
rep (a -> b) -> Parser a -> Parser b
<$> Parser a
x
  in Parser b
go Parser b -> Parser (b -> b) -> Parser b
forall a b. Parser a -> Parser (a -> b) -> Parser b
<**> Reg r (b -> b) -> Parser (b -> b)
forall r a. Reg r a -> Parser a
get Reg r (b -> b)
acc

{-|
The classic version of the right-associative chain combinator. See 'chainr1''.

> chainr1 p op = chainr1' ID p op

@since 0.1.0.0
-}
chainr1 :: Parser a -> Parser (a -> a -> a) -> Parser a
chainr1 :: Parser a -> Parser (a -> a -> a) -> Parser a
chainr1 = Defunc (a -> a) -> Parser a -> Parser (a -> a -> a) -> Parser a
forall (rep :: Type -> Type) a b.
ParserOps rep =>
rep (a -> b) -> Parser a -> Parser (a -> b -> b) -> Parser b
chainr1' Defunc (a -> a)
forall a1. Defunc (a1 -> a1)
ID

{-|
Like `chainr1`, but may parse zero occurences of @p@ in which case the value is returned.

@since 0.1.0.0
-}
chainr :: ParserOps rep => Parser a -> Parser (a -> a -> a) -> rep a -> Parser a
chainr :: Parser a -> Parser (a -> a -> a) -> rep a -> Parser a
chainr Parser a
p Parser (a -> a -> a)
op rep a
x = rep a -> Parser a -> Parser a
forall (rep :: Type -> Type) a.
ParserOps rep =>
rep a -> Parser a -> Parser a
option rep a
x (Parser a -> Parser (a -> a -> a) -> Parser a
forall a. Parser a -> Parser (a -> a -> a) -> Parser a
chainr1 Parser a
p Parser (a -> a -> a)
op)

{-|
Like `chainl1`, but may parse zero occurences of @p@ in which case the value is returned.

@since 0.1.0.0
-}
chainl :: ParserOps rep => Parser a -> Parser (a -> a -> a) -> rep a -> Parser a
chainl :: Parser a -> Parser (a -> a -> a) -> rep a -> Parser a
chainl Parser a
p Parser (a -> a -> a)
op rep a
x = rep a -> Parser a -> Parser a
forall (rep :: Type -> Type) a.
ParserOps rep =>
rep a -> Parser a -> Parser a
option rep a
x (Parser a -> Parser (a -> a -> a) -> Parser a
forall a. Parser a -> Parser (a -> a -> a) -> Parser a
chainl1 Parser a
p Parser (a -> a -> a)
op)

-- Derived Combinators
{-|
Attempts to parse the given parser __zero__ or more times, collecting all of the successful results
into a list. Same as @manyN 0@

@since 0.1.0.0
-}
many :: Parser a -> Parser [a]
many :: Parser a -> Parser [a]
many = Defunc (a -> [a] -> [a]) -> Defunc [a] -> Parser a -> Parser [a]
forall (repf :: Type -> Type) (repk :: Type -> Type) a b.
(ParserOps repf, ParserOps repk) =>
repf (a -> b -> b) -> repk b -> Parser a -> Parser b
pfoldr Defunc (a -> [a] -> [a])
forall a1. Defunc (a1 -> [a1] -> [a1])
CONS Defunc [a]
forall a1. Defunc [a1]
EMPTY

{-|
Attempts to parse the given parser __n__ or more times, collecting all of the successful results
into a list.

@since 0.1.0.0
-}
manyN :: Int -> Parser a -> Parser [a]
manyN :: Int -> Parser a -> Parser [a]
manyN Int
n Parser a
p = (Int -> Parser [a] -> Parser [a])
-> Parser [a] -> [Int] -> Parser [a]
forall (t :: Type -> Type) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr ((Parser [a] -> Parser [a]) -> Int -> Parser [a] -> Parser [a]
forall a b. a -> b -> a
const (Parser a
p Parser a -> Parser [a] -> Parser [a]
forall a. Parser a -> Parser [a] -> Parser [a]
<:>)) (Parser a -> Parser [a]
forall a. Parser a -> Parser [a]
many Parser a
p) [Int
1..Int
n]

{-|
Attempts to parse the given parser __one__ or more times, collecting all of the successful results
into a list. Same as @manyN 1@

@since 0.1.0.0
-}
some :: Parser a -> Parser [a]
some :: Parser a -> Parser [a]
some = Int -> Parser a -> Parser [a]
forall a. Int -> Parser a -> Parser [a]
manyN Int
1

{-|
Like `many`, excepts discards its results.

@since 0.1.0.0
-}
skipMany :: Parser a -> Parser ()
--skipMany p = let skipManyp = p *> skipManyp <|> unit in skipManyp
skipMany :: Parser a -> Parser ()
skipMany = Parser () -> Parser ()
forall a. Parser a -> Parser ()
void (Parser () -> Parser ())
-> (Parser a -> Parser ()) -> Parser a -> Parser ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Defunc (() -> a -> ()) -> Defunc () -> Parser a -> Parser ()
forall (repf :: Type -> Type) (repk :: Type -> Type) b a.
(ParserOps repf, ParserOps repk) =>
repf (b -> a -> b) -> repk b -> Parser a -> Parser b
pfoldl Defunc (() -> a -> ())
forall a1 b. Defunc (a1 -> b -> a1)
CONST Defunc ()
UNIT -- the void here will encourage the optimiser to recognise that the register is unused
--skipMany = flip loop (pure UNIT) . void -- This should be the optimal one, with register removed, but apparently not?! something is amiss, perhaps space leak?

{-|
Like `manyN`, excepts discards its results.

@since 0.1.0.0
-}
skipManyN :: Int -> Parser a -> Parser ()
skipManyN :: Int -> Parser a -> Parser ()
skipManyN Int
n Parser a
p = (Int -> Parser () -> Parser ()) -> Parser () -> [Int] -> Parser ()
forall (t :: Type -> Type) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr ((Parser () -> Parser ()) -> Int -> Parser () -> Parser ()
forall a b. a -> b -> a
const (Parser a
p Parser a -> Parser () -> Parser ()
forall a b. Parser a -> Parser b -> Parser b
*>)) (Parser a -> Parser ()
forall a. Parser a -> Parser ()
skipMany Parser a
p) [Int
1..Int
n]

{-|
Like `some`, excepts discards its results.

@since 0.1.0.0
-}
skipSome :: Parser a -> Parser ()
skipSome :: Parser a -> Parser ()
skipSome = Int -> Parser a -> Parser ()
forall a. Int -> Parser a -> Parser ()
skipManyN Int
1

{-|
@sepBy p sep@ parses __zero__ or more occurrences of @p@, separated by @sep@.
Returns a list of values returned by @p@.

@since 0.1.0.0
-}
sepBy :: Parser a -> Parser b -> Parser [a]
sepBy :: Parser a -> Parser b -> Parser [a]
sepBy Parser a
p Parser b
sep = Defunc [a] -> Parser [a] -> Parser [a]
forall (rep :: Type -> Type) a.
ParserOps rep =>
rep a -> Parser a -> Parser a
option Defunc [a]
forall a1. Defunc [a1]
EMPTY (Parser a -> Parser b -> Parser [a]
forall a b. Parser a -> Parser b -> Parser [a]
sepBy1 Parser a
p Parser b
sep)

{-|
@sepBy1 p sep@ parses __one__ or more occurrences of @p@, separated by @sep@.
Returns a list of values returned by @p@.

@since 0.1.0.0
-}
sepBy1 :: Parser a -> Parser b -> Parser [a]
sepBy1 :: Parser a -> Parser b -> Parser [a]
sepBy1 Parser a
p Parser b
sep = Parser a
p Parser a -> Parser [a] -> Parser [a]
forall a. Parser a -> Parser [a] -> Parser [a]
<:> Parser a -> Parser [a]
forall a. Parser a -> Parser [a]
many (Parser b
sep Parser b -> Parser a -> Parser a
forall a b. Parser a -> Parser b -> Parser b
*> Parser a
p)

{-|
@endBy p sep@ parses __zero__ or more occurrences of @p@, separated and ended by @sep@.
Returns a list of values returned by @p@.

@since 0.1.0.0
-}
endBy :: Parser a -> Parser b -> Parser [a]
endBy :: Parser a -> Parser b -> Parser [a]
endBy Parser a
p Parser b
sep = Parser a -> Parser [a]
forall a. Parser a -> Parser [a]
many (Parser a
p Parser a -> Parser b -> Parser a
forall a b. Parser a -> Parser b -> Parser a
<* Parser b
sep)

{-|
@endBy1 p sep@ parses __one__ or more occurrences of @p@, separated and ended by @sep@.
Returns a list of values returned by @p@.

@since 0.1.0.0
-}
endBy1 :: Parser a -> Parser b -> Parser [a]
endBy1 :: Parser a -> Parser b -> Parser [a]
endBy1 Parser a
p Parser b
sep = Parser a -> Parser [a]
forall a. Parser a -> Parser [a]
some (Parser a
p Parser a -> Parser b -> Parser a
forall a b. Parser a -> Parser b -> Parser a
<* Parser b
sep)

{-|
@sepEndBy p sep@ parses __zero__ or more occurrences of @p@, separated and /optionally/ ended by @sep@.
Returns a list of values returned by @p@.

@since 0.1.0.0
-}
sepEndBy :: Parser a -> Parser b -> Parser [a]
sepEndBy :: Parser a -> Parser b -> Parser [a]
sepEndBy Parser a
p Parser b
sep = Defunc [a] -> Parser [a] -> Parser [a]
forall (rep :: Type -> Type) a.
ParserOps rep =>
rep a -> Parser a -> Parser a
option Defunc [a]
forall a1. Defunc [a1]
EMPTY (Parser a -> Parser b -> Parser [a]
forall a b. Parser a -> Parser b -> Parser [a]
sepEndBy1 Parser a
p Parser b
sep)

{-|
@sepEndBy1 p sep@ parses __one__ or more occurrences of @p@, separated and /optionally/ ended by @sep@.
Returns a list of values returned by @p@.

@since 0.1.0.0
-}
sepEndBy1 :: Parser a -> Parser b -> Parser [a]
sepEndBy1 :: Parser a -> Parser b -> Parser [a]
sepEndBy1 Parser a
p Parser b
sep = Defunc ([a] -> [a])
-> (forall r. Reg r ([a] -> [a]) -> Parser [a]) -> Parser [a]
forall (rep :: Type -> Type) a b.
ParserOps rep =>
rep a -> (forall r. Reg r a -> Parser b) -> Parser b
newRegister_ Defunc ([a] -> [a])
forall a1. Defunc (a1 -> a1)
ID ((forall r. Reg r ([a] -> [a]) -> Parser [a]) -> Parser [a])
-> (forall r. Reg r ([a] -> [a]) -> Parser [a]) -> Parser [a]
forall a b. (a -> b) -> a -> b
$ \Reg r ([a] -> [a])
acc ->
  let go :: Parser ([a] -> [a])
go = Reg r ([a] -> [a])
-> Parser (([a] -> [a]) -> [a] -> [a]) -> Parser ()
forall r a. Reg r a -> Parser (a -> a) -> Parser ()
modify Reg r ([a] -> [a])
acc (Defunc (([a] -> [a]) -> ([a] -> [a]) -> [a] -> [a])
-> Defunc (a -> [a] -> [a])
-> Defunc (a -> ([a] -> [a]) -> [a] -> [a])
forall z x y b c a.
((x -> y -> z) ~ ((b -> c) -> (a -> b) -> a -> c)) =>
Defunc x -> Defunc y -> Defunc z
COMPOSE_H (Defunc (([a] -> [a]) -> ([a] -> [a]) -> [a] -> [a])
-> Defunc (([a] -> [a]) -> ([a] -> [a]) -> [a] -> [a])
forall y x a b c.
((x -> y) ~ ((a -> b -> c) -> b -> a -> c)) =>
Defunc x -> Defunc y
FLIP_H Defunc (([a] -> [a]) -> ([a] -> [a]) -> [a] -> [a])
forall b c a1. Defunc ((b -> c) -> (a1 -> b) -> a1 -> c)
COMPOSE) Defunc (a -> [a] -> [a])
forall a1. Defunc (a1 -> [a1] -> [a1])
CONS Defunc (a -> ([a] -> [a]) -> [a] -> [a])
-> Parser a -> Parser (([a] -> [a]) -> [a] -> [a])
forall (rep :: Type -> Type) a b.
ParserOps rep =>
rep (a -> b) -> Parser a -> Parser b
<$> Parser a
p)
         Parser () -> Parser ([a] -> [a]) -> Parser ([a] -> [a])
forall a b. Parser a -> Parser b -> Parser b
*> (Parser b
sep Parser b -> Parser ([a] -> [a]) -> Parser ([a] -> [a])
forall a b. Parser a -> Parser b -> Parser b
*> (Parser ([a] -> [a])
go Parser ([a] -> [a]) -> Parser ([a] -> [a]) -> Parser ([a] -> [a])
forall a. Parser a -> Parser a -> Parser a
<|> Reg r ([a] -> [a]) -> Parser ([a] -> [a])
forall r a. Reg r a -> Parser a
get Reg r ([a] -> [a])
acc) Parser ([a] -> [a]) -> Parser ([a] -> [a]) -> Parser ([a] -> [a])
forall a. Parser a -> Parser a -> Parser a
<|> Reg r ([a] -> [a]) -> Parser ([a] -> [a])
forall r a. Reg r a -> Parser a
get Reg r ([a] -> [a])
acc)
  in Parser ([a] -> [a])
go Parser ([a] -> [a]) -> Parser [a] -> Parser [a]
forall a b. Parser (a -> b) -> Parser a -> Parser b
<*> Defunc [a] -> Parser [a]
forall (rep :: Type -> Type) a. ParserOps rep => rep a -> Parser a
pure Defunc [a]
forall a1. Defunc [a1]
EMPTY

{-sepEndBy1 :: Parser a -> Parser b -> Parser [a]
sepEndBy1 p sep =
  let seb1 = p <**> (sep *> (FLIP_H CONS <$> option EMPTY seb1)
                 <|> pure (APP_H (FLIP_H CONS) EMPTY))
  in seb1-}