module Test.Tasty.Patterns.Expr
( Operator (..)
, makeExprParser )
where
import Control.Monad
choice :: MonadPlus m => [m a] -> m a
choice :: forall (m :: * -> *) a. MonadPlus m => [m a] -> m a
choice = forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, MonadPlus m) =>
t (m a) -> m a
msum
option :: MonadPlus m => a -> m a -> m a
option :: forall (m :: * -> *) a. MonadPlus m => a -> m a -> m a
option a
x m a
p = m a
p forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` forall (m :: * -> *) a. Monad m => a -> m a
return a
x
data Operator m a
= InfixN (m (a -> a -> a))
| InfixL (m (a -> a -> a))
| InfixR (m (a -> a -> a))
| Prefix (m (a -> a))
| Postfix (m (a -> a))
| TernR (m (m (a -> a -> a -> a)))
makeExprParser :: MonadPlus m
=> m a
-> [[Operator m a]]
-> m a
makeExprParser :: forall (m :: * -> *) a.
MonadPlus m =>
m a -> [[Operator m a]] -> m a
makeExprParser = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl forall (m :: * -> *) a. MonadPlus m => m a -> [Operator m a] -> m a
addPrecLevel
{-# INLINEABLE makeExprParser #-}
addPrecLevel :: MonadPlus m => m a -> [Operator m a] -> m a
addPrecLevel :: forall (m :: * -> *) a. MonadPlus m => m a -> [Operator m a] -> m a
addPrecLevel m a
term [Operator m a]
ops =
m a
term' forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \a
x -> forall (m :: * -> *) a. MonadPlus m => [m a] -> m a
choice [a -> m a
ras' a
x, a -> m a
las' a
x, a -> m a
nas' a
x, a -> m a
tern' a
x, forall (m :: * -> *) a. Monad m => a -> m a
return a
x]
where ([m (a -> a -> a)]
ras, [m (a -> a -> a)]
las, [m (a -> a -> a)]
nas, [m (a -> a)]
prefix, [m (a -> a)]
postfix, [m (m (a -> a -> a -> a))]
tern) = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr forall (m :: * -> *) a. Operator m a -> Batch m a -> Batch m a
splitOp ([],[],[],[],[],[]) [Operator m a]
ops
term' :: m a
term' = forall (m :: * -> *) a.
MonadPlus m =>
m (a -> a) -> m a -> m (a -> a) -> m a
pTerm (forall (m :: * -> *) a. MonadPlus m => [m a] -> m a
choice [m (a -> a)]
prefix) m a
term (forall (m :: * -> *) a. MonadPlus m => [m a] -> m a
choice [m (a -> a)]
postfix)
ras' :: a -> m a
ras' = forall (m :: * -> *) a.
MonadPlus m =>
m (a -> a -> a) -> m a -> a -> m a
pInfixR (forall (m :: * -> *) a. MonadPlus m => [m a] -> m a
choice [m (a -> a -> a)]
ras) m a
term'
las' :: a -> m a
las' = forall (m :: * -> *) a.
MonadPlus m =>
m (a -> a -> a) -> m a -> a -> m a
pInfixL (forall (m :: * -> *) a. MonadPlus m => [m a] -> m a
choice [m (a -> a -> a)]
las) m a
term'
nas' :: a -> m a
nas' = forall (m :: * -> *) a.
MonadPlus m =>
m (a -> a -> a) -> m a -> a -> m a
pInfixN (forall (m :: * -> *) a. MonadPlus m => [m a] -> m a
choice [m (a -> a -> a)]
nas) m a
term'
tern' :: a -> m a
tern' = forall (m :: * -> *) a.
MonadPlus m =>
m (m (a -> a -> a -> a)) -> m a -> a -> m a
pTernR (forall (m :: * -> *) a. MonadPlus m => [m a] -> m a
choice [m (m (a -> a -> a -> a))]
tern) m a
term'
pTerm :: MonadPlus m => m (a -> a) -> m a -> m (a -> a) -> m a
pTerm :: forall (m :: * -> *) a.
MonadPlus m =>
m (a -> a) -> m a -> m (a -> a) -> m a
pTerm m (a -> a)
prefix m a
term m (a -> a)
postfix = do
a -> a
pre <- forall (m :: * -> *) a. MonadPlus m => a -> m a -> m a
option forall a. a -> a
id m (a -> a)
prefix
a
x <- m a
term
a -> a
post <- forall (m :: * -> *) a. MonadPlus m => a -> m a -> m a
option forall a. a -> a
id m (a -> a)
postfix
forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
post forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
pre forall a b. (a -> b) -> a -> b
$ a
x
pInfixN :: MonadPlus m => m (a -> a -> a) -> m a -> a -> m a
pInfixN :: forall (m :: * -> *) a.
MonadPlus m =>
m (a -> a -> a) -> m a -> a -> m a
pInfixN m (a -> a -> a)
op m a
p a
x = do
a -> a -> a
f <- m (a -> a -> a)
op
a
y <- m a
p
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ a -> a -> a
f a
x a
y
pInfixL :: MonadPlus m => m (a -> a -> a) -> m a -> a -> m a
pInfixL :: forall (m :: * -> *) a.
MonadPlus m =>
m (a -> a -> a) -> m a -> a -> m a
pInfixL m (a -> a -> a)
op m a
p a
x = do
a -> a -> a
f <- m (a -> a -> a)
op
a
y <- m a
p
let r :: a
r = a -> a -> a
f a
x a
y
forall (m :: * -> *) a.
MonadPlus m =>
m (a -> a -> a) -> m a -> a -> m a
pInfixL m (a -> a -> a)
op m a
p a
r forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` forall (m :: * -> *) a. Monad m => a -> m a
return a
r
pInfixR :: MonadPlus m => m (a -> a -> a) -> m a -> a -> m a
pInfixR :: forall (m :: * -> *) a.
MonadPlus m =>
m (a -> a -> a) -> m a -> a -> m a
pInfixR m (a -> a -> a)
op m a
p a
x = do
a -> a -> a
f <- m (a -> a -> a)
op
a
y <- m a
p forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \a
r -> forall (m :: * -> *) a.
MonadPlus m =>
m (a -> a -> a) -> m a -> a -> m a
pInfixR m (a -> a -> a)
op m a
p a
r forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` forall (m :: * -> *) a. Monad m => a -> m a
return a
r
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ a -> a -> a
f a
x a
y
pTernR :: MonadPlus m => m (m (a -> a -> a -> a)) -> m a -> a -> m a
pTernR :: forall (m :: * -> *) a.
MonadPlus m =>
m (m (a -> a -> a -> a)) -> m a -> a -> m a
pTernR m (m (a -> a -> a -> a))
sep1 m a
p a
x = do
m (a -> a -> a -> a)
sep2 <- m (m (a -> a -> a -> a))
sep1
a
y <- m a
p forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \a
r -> forall (m :: * -> *) a.
MonadPlus m =>
m (m (a -> a -> a -> a)) -> m a -> a -> m a
pTernR m (m (a -> a -> a -> a))
sep1 m a
p a
r forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` forall (m :: * -> *) a. Monad m => a -> m a
return a
r
a -> a -> a -> a
f <- m (a -> a -> a -> a)
sep2
a
z <- m a
p forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \a
r -> forall (m :: * -> *) a.
MonadPlus m =>
m (m (a -> a -> a -> a)) -> m a -> a -> m a
pTernR m (m (a -> a -> a -> a))
sep1 m a
p a
r forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` forall (m :: * -> *) a. Monad m => a -> m a
return a
r
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ a -> a -> a -> a
f a
x a
y a
z
type Batch m a =
( [m (a -> a -> a)]
, [m (a -> a -> a)]
, [m (a -> a -> a)]
, [m (a -> a)]
, [m (a -> a)]
, [m (m (a -> a -> a -> a))]
)
splitOp :: Operator m a -> Batch m a -> Batch m a
splitOp :: forall (m :: * -> *) a. Operator m a -> Batch m a -> Batch m a
splitOp (InfixR m (a -> a -> a)
op) ([m (a -> a -> a)]
r, [m (a -> a -> a)]
l, [m (a -> a -> a)]
n, [m (a -> a)]
pre, [m (a -> a)]
post, [m (m (a -> a -> a -> a))]
tern) = (m (a -> a -> a)
opforall a. a -> [a] -> [a]
:[m (a -> a -> a)]
r, [m (a -> a -> a)]
l, [m (a -> a -> a)]
n, [m (a -> a)]
pre, [m (a -> a)]
post, [m (m (a -> a -> a -> a))]
tern)
splitOp (InfixL m (a -> a -> a)
op) ([m (a -> a -> a)]
r, [m (a -> a -> a)]
l, [m (a -> a -> a)]
n, [m (a -> a)]
pre, [m (a -> a)]
post, [m (m (a -> a -> a -> a))]
tern) = ([m (a -> a -> a)]
r, m (a -> a -> a)
opforall a. a -> [a] -> [a]
:[m (a -> a -> a)]
l, [m (a -> a -> a)]
n, [m (a -> a)]
pre, [m (a -> a)]
post, [m (m (a -> a -> a -> a))]
tern)
splitOp (InfixN m (a -> a -> a)
op) ([m (a -> a -> a)]
r, [m (a -> a -> a)]
l, [m (a -> a -> a)]
n, [m (a -> a)]
pre, [m (a -> a)]
post, [m (m (a -> a -> a -> a))]
tern) = ([m (a -> a -> a)]
r, [m (a -> a -> a)]
l, m (a -> a -> a)
opforall a. a -> [a] -> [a]
:[m (a -> a -> a)]
n, [m (a -> a)]
pre, [m (a -> a)]
post, [m (m (a -> a -> a -> a))]
tern)
splitOp (Prefix m (a -> a)
op) ([m (a -> a -> a)]
r, [m (a -> a -> a)]
l, [m (a -> a -> a)]
n, [m (a -> a)]
pre, [m (a -> a)]
post, [m (m (a -> a -> a -> a))]
tern) = ([m (a -> a -> a)]
r, [m (a -> a -> a)]
l, [m (a -> a -> a)]
n, m (a -> a)
opforall a. a -> [a] -> [a]
:[m (a -> a)]
pre, [m (a -> a)]
post, [m (m (a -> a -> a -> a))]
tern)
splitOp (Postfix m (a -> a)
op) ([m (a -> a -> a)]
r, [m (a -> a -> a)]
l, [m (a -> a -> a)]
n, [m (a -> a)]
pre, [m (a -> a)]
post, [m (m (a -> a -> a -> a))]
tern) = ([m (a -> a -> a)]
r, [m (a -> a -> a)]
l, [m (a -> a -> a)]
n, [m (a -> a)]
pre, m (a -> a)
opforall a. a -> [a] -> [a]
:[m (a -> a)]
post, [m (m (a -> a -> a -> a))]
tern)
splitOp (TernR m (m (a -> a -> a -> a))
op) ([m (a -> a -> a)]
r, [m (a -> a -> a)]
l, [m (a -> a -> a)]
n, [m (a -> a)]
pre, [m (a -> a)]
post, [m (m (a -> a -> a -> a))]
tern) = ([m (a -> a -> a)]
r, [m (a -> a -> a)]
l, [m (a -> a -> a)]
n, [m (a -> a)]
pre, [m (a -> a)]
post, m (m (a -> a -> a -> a))
opforall a. a -> [a] -> [a]
:[m (m (a -> a -> a -> a))]
tern)