{-# LANGUAGE
    DeriveDataTypeable
  , DeriveFoldable
  , DeriveGeneric
  , DeriveFunctor
  , DeriveTraversable
  , OverloadedStrings
  #-}
-- | Bash conditional commands.
module Language.Bash.Cond
    ( CondExpr(..)
    , UnaryOp(..)
    , BinaryOp(..)
    , parseTestExpr
    ) where

import Prelude                hiding (negate)

import Control.Applicative
import Data.Data              (Data)
import Data.Typeable          (Typeable)
import GHC.Generics           (Generic)
import Text.Parsec            hiding ((<|>), token)
import Text.Parsec.Expr       hiding (Operator)
import Prettyprinter          (Pretty(..), (<+>))

import Language.Bash.Operator

-- | Bash conditional expressions.
data CondExpr a
    = Unary UnaryOp a
    | Binary a BinaryOp a
    | Not (CondExpr a)
    | And (CondExpr a) (CondExpr a)
    | Or (CondExpr a) (CondExpr a)
    deriving (Typeable (CondExpr a)
Typeable (CondExpr a)
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> CondExpr a -> c (CondExpr a))
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (CondExpr a))
-> (CondExpr a -> Constr)
-> (CondExpr a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (CondExpr a)))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (CondExpr a)))
-> ((forall b. Data b => b -> b) -> CondExpr a -> CondExpr a)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> CondExpr a -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> CondExpr a -> r)
-> (forall u. (forall d. Data d => d -> u) -> CondExpr a -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> CondExpr a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> CondExpr a -> m (CondExpr a))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> CondExpr a -> m (CondExpr a))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> CondExpr a -> m (CondExpr a))
-> Data (CondExpr a)
CondExpr a -> Constr
CondExpr a -> DataType
(forall b. Data b => b -> b) -> CondExpr a -> CondExpr a
forall {a}. Data a => Typeable (CondExpr a)
forall a. Data a => CondExpr a -> Constr
forall a. Data a => CondExpr a -> DataType
forall a.
Data a =>
(forall b. Data b => b -> b) -> CondExpr a -> CondExpr a
forall a u.
Data a =>
Int -> (forall d. Data d => d -> u) -> CondExpr a -> u
forall a u.
Data a =>
(forall d. Data d => d -> u) -> CondExpr a -> [u]
forall a r r'.
Data a =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> CondExpr a -> r
forall a r r'.
Data a =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> CondExpr a -> r
forall a (m :: * -> *).
(Data a, Monad m) =>
(forall d. Data d => d -> m d) -> CondExpr a -> m (CondExpr a)
forall a (m :: * -> *).
(Data a, MonadPlus m) =>
(forall d. Data d => d -> m d) -> CondExpr a -> m (CondExpr a)
forall a (c :: * -> *).
Data a =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (CondExpr a)
forall a (c :: * -> *).
Data a =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> CondExpr a -> c (CondExpr a)
forall a (t :: * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (CondExpr a))
forall a (t :: * -> * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (CondExpr a))
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> CondExpr a -> u
forall u. (forall d. Data d => d -> u) -> CondExpr a -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> CondExpr a -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> CondExpr a -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> CondExpr a -> m (CondExpr a)
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> CondExpr a -> m (CondExpr a)
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (CondExpr a)
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> CondExpr a -> c (CondExpr a)
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (CondExpr a))
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (CondExpr a))
$cgfoldl :: forall a (c :: * -> *).
Data a =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> CondExpr a -> c (CondExpr a)
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> CondExpr a -> c (CondExpr a)
$cgunfold :: forall a (c :: * -> *).
Data a =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (CondExpr a)
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (CondExpr a)
$ctoConstr :: forall a. Data a => CondExpr a -> Constr
toConstr :: CondExpr a -> Constr
$cdataTypeOf :: forall a. Data a => CondExpr a -> DataType
dataTypeOf :: CondExpr a -> DataType
$cdataCast1 :: forall a (t :: * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (CondExpr a))
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (CondExpr a))
$cdataCast2 :: forall a (t :: * -> * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (CondExpr a))
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (CondExpr a))
$cgmapT :: forall a.
Data a =>
(forall b. Data b => b -> b) -> CondExpr a -> CondExpr a
gmapT :: (forall b. Data b => b -> b) -> CondExpr a -> CondExpr a
$cgmapQl :: forall a r r'.
Data a =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> CondExpr a -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> CondExpr a -> r
$cgmapQr :: forall a r r'.
Data a =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> CondExpr a -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> CondExpr a -> r
$cgmapQ :: forall a u.
Data a =>
(forall d. Data d => d -> u) -> CondExpr a -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> CondExpr a -> [u]
$cgmapQi :: forall a u.
Data a =>
Int -> (forall d. Data d => d -> u) -> CondExpr a -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> CondExpr a -> u
$cgmapM :: forall a (m :: * -> *).
(Data a, Monad m) =>
(forall d. Data d => d -> m d) -> CondExpr a -> m (CondExpr a)
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> CondExpr a -> m (CondExpr a)
$cgmapMp :: forall a (m :: * -> *).
(Data a, MonadPlus m) =>
(forall d. Data d => d -> m d) -> CondExpr a -> m (CondExpr a)
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> CondExpr a -> m (CondExpr a)
$cgmapMo :: forall a (m :: * -> *).
(Data a, MonadPlus m) =>
(forall d. Data d => d -> m d) -> CondExpr a -> m (CondExpr a)
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> CondExpr a -> m (CondExpr a)
Data, CondExpr a -> CondExpr a -> Bool
(CondExpr a -> CondExpr a -> Bool)
-> (CondExpr a -> CondExpr a -> Bool) -> Eq (CondExpr a)
forall a. Eq a => CondExpr a -> CondExpr a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => CondExpr a -> CondExpr a -> Bool
== :: CondExpr a -> CondExpr a -> Bool
$c/= :: forall a. Eq a => CondExpr a -> CondExpr a -> Bool
/= :: CondExpr a -> CondExpr a -> Bool
Eq, ReadPrec [CondExpr a]
ReadPrec (CondExpr a)
Int -> ReadS (CondExpr a)
ReadS [CondExpr a]
(Int -> ReadS (CondExpr a))
-> ReadS [CondExpr a]
-> ReadPrec (CondExpr a)
-> ReadPrec [CondExpr a]
-> Read (CondExpr a)
forall a. Read a => ReadPrec [CondExpr a]
forall a. Read a => ReadPrec (CondExpr a)
forall a. Read a => Int -> ReadS (CondExpr a)
forall a. Read a => ReadS [CondExpr a]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: forall a. Read a => Int -> ReadS (CondExpr a)
readsPrec :: Int -> ReadS (CondExpr a)
$creadList :: forall a. Read a => ReadS [CondExpr a]
readList :: ReadS [CondExpr a]
$creadPrec :: forall a. Read a => ReadPrec (CondExpr a)
readPrec :: ReadPrec (CondExpr a)
$creadListPrec :: forall a. Read a => ReadPrec [CondExpr a]
readListPrec :: ReadPrec [CondExpr a]
Read, Int -> CondExpr a -> ShowS
[CondExpr a] -> ShowS
CondExpr a -> String
(Int -> CondExpr a -> ShowS)
-> (CondExpr a -> String)
-> ([CondExpr a] -> ShowS)
-> Show (CondExpr a)
forall a. Show a => Int -> CondExpr a -> ShowS
forall a. Show a => [CondExpr a] -> ShowS
forall a. Show a => CondExpr a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> CondExpr a -> ShowS
showsPrec :: Int -> CondExpr a -> ShowS
$cshow :: forall a. Show a => CondExpr a -> String
show :: CondExpr a -> String
$cshowList :: forall a. Show a => [CondExpr a] -> ShowS
showList :: [CondExpr a] -> ShowS
Show, Typeable, (forall a b. (a -> b) -> CondExpr a -> CondExpr b)
-> (forall a b. a -> CondExpr b -> CondExpr a) -> Functor CondExpr
forall a b. a -> CondExpr b -> CondExpr a
forall a b. (a -> b) -> CondExpr a -> CondExpr b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> CondExpr a -> CondExpr b
fmap :: forall a b. (a -> b) -> CondExpr a -> CondExpr b
$c<$ :: forall a b. a -> CondExpr b -> CondExpr a
<$ :: forall a b. a -> CondExpr b -> CondExpr a
Functor, (forall m. Monoid m => CondExpr m -> m)
-> (forall m a. Monoid m => (a -> m) -> CondExpr a -> m)
-> (forall m a. Monoid m => (a -> m) -> CondExpr a -> m)
-> (forall a b. (a -> b -> b) -> b -> CondExpr a -> b)
-> (forall a b. (a -> b -> b) -> b -> CondExpr a -> b)
-> (forall b a. (b -> a -> b) -> b -> CondExpr a -> b)
-> (forall b a. (b -> a -> b) -> b -> CondExpr a -> b)
-> (forall a. (a -> a -> a) -> CondExpr a -> a)
-> (forall a. (a -> a -> a) -> CondExpr a -> a)
-> (forall a. CondExpr a -> [a])
-> (forall a. CondExpr a -> Bool)
-> (forall a. CondExpr a -> Int)
-> (forall a. Eq a => a -> CondExpr a -> Bool)
-> (forall a. Ord a => CondExpr a -> a)
-> (forall a. Ord a => CondExpr a -> a)
-> (forall a. Num a => CondExpr a -> a)
-> (forall a. Num a => CondExpr a -> a)
-> Foldable CondExpr
forall a. Eq a => a -> CondExpr a -> Bool
forall a. Num a => CondExpr a -> a
forall a. Ord a => CondExpr a -> a
forall m. Monoid m => CondExpr m -> m
forall a. CondExpr a -> Bool
forall a. CondExpr a -> Int
forall a. CondExpr a -> [a]
forall a. (a -> a -> a) -> CondExpr a -> a
forall m a. Monoid m => (a -> m) -> CondExpr a -> m
forall b a. (b -> a -> b) -> b -> CondExpr a -> b
forall a b. (a -> b -> b) -> b -> CondExpr a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
$cfold :: forall m. Monoid m => CondExpr m -> m
fold :: forall m. Monoid m => CondExpr m -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> CondExpr a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> CondExpr a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> CondExpr a -> m
foldMap' :: forall m a. Monoid m => (a -> m) -> CondExpr a -> m
$cfoldr :: forall a b. (a -> b -> b) -> b -> CondExpr a -> b
foldr :: forall a b. (a -> b -> b) -> b -> CondExpr a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> CondExpr a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> CondExpr a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> CondExpr a -> b
foldl :: forall b a. (b -> a -> b) -> b -> CondExpr a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> CondExpr a -> b
foldl' :: forall b a. (b -> a -> b) -> b -> CondExpr a -> b
$cfoldr1 :: forall a. (a -> a -> a) -> CondExpr a -> a
foldr1 :: forall a. (a -> a -> a) -> CondExpr a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> CondExpr a -> a
foldl1 :: forall a. (a -> a -> a) -> CondExpr a -> a
$ctoList :: forall a. CondExpr a -> [a]
toList :: forall a. CondExpr a -> [a]
$cnull :: forall a. CondExpr a -> Bool
null :: forall a. CondExpr a -> Bool
$clength :: forall a. CondExpr a -> Int
length :: forall a. CondExpr a -> Int
$celem :: forall a. Eq a => a -> CondExpr a -> Bool
elem :: forall a. Eq a => a -> CondExpr a -> Bool
$cmaximum :: forall a. Ord a => CondExpr a -> a
maximum :: forall a. Ord a => CondExpr a -> a
$cminimum :: forall a. Ord a => CondExpr a -> a
minimum :: forall a. Ord a => CondExpr a -> a
$csum :: forall a. Num a => CondExpr a -> a
sum :: forall a. Num a => CondExpr a -> a
$cproduct :: forall a. Num a => CondExpr a -> a
product :: forall a. Num a => CondExpr a -> a
Foldable, Functor CondExpr
Foldable CondExpr
Functor CondExpr
-> Foldable CondExpr
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> CondExpr a -> f (CondExpr b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    CondExpr (f a) -> f (CondExpr a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> CondExpr a -> m (CondExpr b))
-> (forall (m :: * -> *) a.
    Monad m =>
    CondExpr (m a) -> m (CondExpr a))
-> Traversable CondExpr
forall (t :: * -> *).
Functor t
-> Foldable t
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a. Monad m => CondExpr (m a) -> m (CondExpr a)
forall (f :: * -> *) a.
Applicative f =>
CondExpr (f a) -> f (CondExpr a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> CondExpr a -> m (CondExpr b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> CondExpr a -> f (CondExpr b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> CondExpr a -> f (CondExpr b)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> CondExpr a -> f (CondExpr b)
$csequenceA :: forall (f :: * -> *) a.
Applicative f =>
CondExpr (f a) -> f (CondExpr a)
sequenceA :: forall (f :: * -> *) a.
Applicative f =>
CondExpr (f a) -> f (CondExpr a)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> CondExpr a -> m (CondExpr b)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> CondExpr a -> m (CondExpr b)
$csequence :: forall (m :: * -> *) a. Monad m => CondExpr (m a) -> m (CondExpr a)
sequence :: forall (m :: * -> *) a. Monad m => CondExpr (m a) -> m (CondExpr a)
Traversable, (forall x. CondExpr a -> Rep (CondExpr a) x)
-> (forall x. Rep (CondExpr a) x -> CondExpr a)
-> Generic (CondExpr a)
forall x. Rep (CondExpr a) x -> CondExpr a
forall x. CondExpr a -> Rep (CondExpr a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (CondExpr a) x -> CondExpr a
forall a x. CondExpr a -> Rep (CondExpr a) x
$cfrom :: forall a x. CondExpr a -> Rep (CondExpr a) x
from :: forall x. CondExpr a -> Rep (CondExpr a) x
$cto :: forall a x. Rep (CondExpr a) x -> CondExpr a
to :: forall x. Rep (CondExpr a) x -> CondExpr a
Generic)

instance Pretty a => Pretty (CondExpr a) where
    pretty :: forall ann. CondExpr a -> Doc ann
pretty = Int -> CondExpr a -> Doc ann
forall {a} {t} {ann}.
(Pretty a, Num t, Ord t) =>
t -> CondExpr a -> Doc ann
go (Int
0 :: Int)
      where
        go :: t -> CondExpr a -> Doc ann
go t
_ (Unary UnaryOp
op a
a)    = UnaryOp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. UnaryOp -> Doc ann
pretty UnaryOp
op Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> a -> Doc ann
forall ann. a -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty a
a
        go t
_ (Binary a
a BinaryOp
op a
b) = a -> Doc ann
forall ann. a -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty a
a Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> BinaryOp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. BinaryOp -> Doc ann
pretty BinaryOp
op Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> a -> Doc ann
forall ann. a -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty a
b
        go t
_ (Not CondExpr a
e)         = Doc ann
"!" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> t -> CondExpr a -> Doc ann
go t
2 CondExpr a
e
        go t
p (And CondExpr a
e1 CondExpr a
e2)     = Bool -> Doc ann -> Doc ann
forall {ann}. Bool -> Doc ann -> Doc ann
paren (t
p t -> t -> Bool
forall a. Ord a => a -> a -> Bool
> t
1) (Doc ann -> Doc ann) -> Doc ann -> Doc ann
forall a b. (a -> b) -> a -> b
$ t -> CondExpr a -> Doc ann
go t
1 CondExpr a
e1 Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc ann
"&&" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> t -> CondExpr a -> Doc ann
go t
1 CondExpr a
e2
        go t
p (Or CondExpr a
e1 CondExpr a
e2)      = Bool -> Doc ann -> Doc ann
forall {ann}. Bool -> Doc ann -> Doc ann
paren (t
p t -> t -> Bool
forall a. Ord a => a -> a -> Bool
> t
0) (Doc ann -> Doc ann) -> Doc ann -> Doc ann
forall a b. (a -> b) -> a -> b
$ t -> CondExpr a -> Doc ann
go t
0 CondExpr a
e1 Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc ann
"||" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> t -> CondExpr a -> Doc ann
go t
0 CondExpr a
e2

        paren :: Bool -> Doc ann -> Doc ann
paren Bool
False Doc ann
d = Doc ann
d
        paren Bool
True Doc ann
d  = Doc ann
"(" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc ann
d Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc ann
")"

-- | Unary conditional operators.
data UnaryOp
    = BlockFile      -- ^ @-b@
    | CharacterFile  -- ^ @-c@
    | Directory      -- ^ @-d@
    | FileExists     -- ^ @-e@, @-a@
    | RegularFile    -- ^ @-f@
    | SetGID         -- ^ @-g@
    | Sticky         -- ^ @-k@
    | NamedPipe      -- ^ @-p@
    | Readable       -- ^ @-r@
    | FileSize       -- ^ @-s@
    | Terminal       -- ^ @-t@
    | SetUID         -- ^ @-u@
    | Writable       -- ^ @-w@
    | Executable     -- ^ @-x@
    | GroupOwned     -- ^ @-G@
    | SymbolicLink   -- ^ @-L@, @-h@
    | Modified       -- ^ @-N@
    | UserOwned      -- ^ @-O@
    | Socket         -- ^ @-S@
    | Optname        -- ^ @-o@
    | Varname        -- ^ @-v@
    | ZeroString     -- ^ @-z@
    | NonzeroString  -- ^ @-n /string/@ or @/string/@
    deriving (Typeable UnaryOp
Typeable UnaryOp
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> UnaryOp -> c UnaryOp)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c UnaryOp)
-> (UnaryOp -> Constr)
-> (UnaryOp -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c UnaryOp))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c UnaryOp))
-> ((forall b. Data b => b -> b) -> UnaryOp -> UnaryOp)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> UnaryOp -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> UnaryOp -> r)
-> (forall u. (forall d. Data d => d -> u) -> UnaryOp -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> UnaryOp -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> UnaryOp -> m UnaryOp)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> UnaryOp -> m UnaryOp)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> UnaryOp -> m UnaryOp)
-> Data UnaryOp
UnaryOp -> Constr
UnaryOp -> DataType
(forall b. Data b => b -> b) -> UnaryOp -> UnaryOp
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> UnaryOp -> u
forall u. (forall d. Data d => d -> u) -> UnaryOp -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> UnaryOp -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> UnaryOp -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> UnaryOp -> m UnaryOp
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> UnaryOp -> m UnaryOp
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c UnaryOp
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> UnaryOp -> c UnaryOp
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c UnaryOp)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c UnaryOp)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> UnaryOp -> c UnaryOp
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> UnaryOp -> c UnaryOp
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c UnaryOp
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c UnaryOp
$ctoConstr :: UnaryOp -> Constr
toConstr :: UnaryOp -> Constr
$cdataTypeOf :: UnaryOp -> DataType
dataTypeOf :: UnaryOp -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c UnaryOp)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c UnaryOp)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c UnaryOp)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c UnaryOp)
$cgmapT :: (forall b. Data b => b -> b) -> UnaryOp -> UnaryOp
gmapT :: (forall b. Data b => b -> b) -> UnaryOp -> UnaryOp
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> UnaryOp -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> UnaryOp -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> UnaryOp -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> UnaryOp -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> UnaryOp -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> UnaryOp -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> UnaryOp -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> UnaryOp -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> UnaryOp -> m UnaryOp
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> UnaryOp -> m UnaryOp
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> UnaryOp -> m UnaryOp
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> UnaryOp -> m UnaryOp
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> UnaryOp -> m UnaryOp
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> UnaryOp -> m UnaryOp
Data, UnaryOp -> UnaryOp -> Bool
(UnaryOp -> UnaryOp -> Bool)
-> (UnaryOp -> UnaryOp -> Bool) -> Eq UnaryOp
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: UnaryOp -> UnaryOp -> Bool
== :: UnaryOp -> UnaryOp -> Bool
$c/= :: UnaryOp -> UnaryOp -> Bool
/= :: UnaryOp -> UnaryOp -> Bool
Eq, Eq UnaryOp
Eq UnaryOp
-> (UnaryOp -> UnaryOp -> Ordering)
-> (UnaryOp -> UnaryOp -> Bool)
-> (UnaryOp -> UnaryOp -> Bool)
-> (UnaryOp -> UnaryOp -> Bool)
-> (UnaryOp -> UnaryOp -> Bool)
-> (UnaryOp -> UnaryOp -> UnaryOp)
-> (UnaryOp -> UnaryOp -> UnaryOp)
-> Ord UnaryOp
UnaryOp -> UnaryOp -> Bool
UnaryOp -> UnaryOp -> Ordering
UnaryOp -> UnaryOp -> UnaryOp
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: UnaryOp -> UnaryOp -> Ordering
compare :: UnaryOp -> UnaryOp -> Ordering
$c< :: UnaryOp -> UnaryOp -> Bool
< :: UnaryOp -> UnaryOp -> Bool
$c<= :: UnaryOp -> UnaryOp -> Bool
<= :: UnaryOp -> UnaryOp -> Bool
$c> :: UnaryOp -> UnaryOp -> Bool
> :: UnaryOp -> UnaryOp -> Bool
$c>= :: UnaryOp -> UnaryOp -> Bool
>= :: UnaryOp -> UnaryOp -> Bool
$cmax :: UnaryOp -> UnaryOp -> UnaryOp
max :: UnaryOp -> UnaryOp -> UnaryOp
$cmin :: UnaryOp -> UnaryOp -> UnaryOp
min :: UnaryOp -> UnaryOp -> UnaryOp
Ord, ReadPrec [UnaryOp]
ReadPrec UnaryOp
Int -> ReadS UnaryOp
ReadS [UnaryOp]
(Int -> ReadS UnaryOp)
-> ReadS [UnaryOp]
-> ReadPrec UnaryOp
-> ReadPrec [UnaryOp]
-> Read UnaryOp
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS UnaryOp
readsPrec :: Int -> ReadS UnaryOp
$creadList :: ReadS [UnaryOp]
readList :: ReadS [UnaryOp]
$creadPrec :: ReadPrec UnaryOp
readPrec :: ReadPrec UnaryOp
$creadListPrec :: ReadPrec [UnaryOp]
readListPrec :: ReadPrec [UnaryOp]
Read, Int -> UnaryOp -> ShowS
[UnaryOp] -> ShowS
UnaryOp -> String
(Int -> UnaryOp -> ShowS)
-> (UnaryOp -> String) -> ([UnaryOp] -> ShowS) -> Show UnaryOp
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> UnaryOp -> ShowS
showsPrec :: Int -> UnaryOp -> ShowS
$cshow :: UnaryOp -> String
show :: UnaryOp -> String
$cshowList :: [UnaryOp] -> ShowS
showList :: [UnaryOp] -> ShowS
Show, Typeable, Int -> UnaryOp
UnaryOp -> Int
UnaryOp -> [UnaryOp]
UnaryOp -> UnaryOp
UnaryOp -> UnaryOp -> [UnaryOp]
UnaryOp -> UnaryOp -> UnaryOp -> [UnaryOp]
(UnaryOp -> UnaryOp)
-> (UnaryOp -> UnaryOp)
-> (Int -> UnaryOp)
-> (UnaryOp -> Int)
-> (UnaryOp -> [UnaryOp])
-> (UnaryOp -> UnaryOp -> [UnaryOp])
-> (UnaryOp -> UnaryOp -> [UnaryOp])
-> (UnaryOp -> UnaryOp -> UnaryOp -> [UnaryOp])
-> Enum UnaryOp
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: UnaryOp -> UnaryOp
succ :: UnaryOp -> UnaryOp
$cpred :: UnaryOp -> UnaryOp
pred :: UnaryOp -> UnaryOp
$ctoEnum :: Int -> UnaryOp
toEnum :: Int -> UnaryOp
$cfromEnum :: UnaryOp -> Int
fromEnum :: UnaryOp -> Int
$cenumFrom :: UnaryOp -> [UnaryOp]
enumFrom :: UnaryOp -> [UnaryOp]
$cenumFromThen :: UnaryOp -> UnaryOp -> [UnaryOp]
enumFromThen :: UnaryOp -> UnaryOp -> [UnaryOp]
$cenumFromTo :: UnaryOp -> UnaryOp -> [UnaryOp]
enumFromTo :: UnaryOp -> UnaryOp -> [UnaryOp]
$cenumFromThenTo :: UnaryOp -> UnaryOp -> UnaryOp -> [UnaryOp]
enumFromThenTo :: UnaryOp -> UnaryOp -> UnaryOp -> [UnaryOp]
Enum, UnaryOp
UnaryOp -> UnaryOp -> Bounded UnaryOp
forall a. a -> a -> Bounded a
$cminBound :: UnaryOp
minBound :: UnaryOp
$cmaxBound :: UnaryOp
maxBound :: UnaryOp
Bounded, (forall x. UnaryOp -> Rep UnaryOp x)
-> (forall x. Rep UnaryOp x -> UnaryOp) -> Generic UnaryOp
forall x. Rep UnaryOp x -> UnaryOp
forall x. UnaryOp -> Rep UnaryOp x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. UnaryOp -> Rep UnaryOp x
from :: forall x. UnaryOp -> Rep UnaryOp x
$cto :: forall x. Rep UnaryOp x -> UnaryOp
to :: forall x. Rep UnaryOp x -> UnaryOp
Generic)

instance Operator UnaryOp where
    operatorTable :: [(UnaryOp, String)]
operatorTable =
        [UnaryOp] -> [String] -> [(UnaryOp, String)]
forall a b. [a] -> [b] -> [(a, b)]
zip [UnaryOp
forall a. Bounded a => a
minBound .. UnaryOp
forall a. Bounded a => a
maxBound]
            ((Char -> String) -> String -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (\Char
c -> [Char
'-', Char
c]) String
"bcdefgkprstuwxGLNOSovzn") [(UnaryOp, String)] -> [(UnaryOp, String)] -> [(UnaryOp, String)]
forall a. [a] -> [a] -> [a]
++
        [ (UnaryOp
FileExists  , String
"-a")
        , (UnaryOp
SymbolicLink, String
"-h")
        ]

instance Pretty UnaryOp where
    pretty :: forall ann. UnaryOp -> Doc ann
pretty = UnaryOp -> Doc ann
forall a ann. Operator a => a -> Doc ann
prettyOperator

-- | Binary conditional operators.
data BinaryOp
    = SameFile   -- ^ @-ef@
    | NewerThan  -- ^ @-nt@
    | OlderThan  -- ^ @-ot@
    | StrMatch   -- ^ @=~@
    | StrEQ      -- ^ @==@, @=@
    | StrNE      -- ^ @!=@
    | StrLT      -- ^ @<@
    | StrGT      -- ^ @>@
    | ArithEQ    -- ^ @-eq@
    | ArithNE    -- ^ @-ne@
    | ArithLT    -- ^ @-lt@
    | ArithLE    -- ^ @-le@
    | ArithGT    -- ^ @-gt@
    | ArithGE    -- ^ @-ge@
    deriving (Typeable BinaryOp
Typeable BinaryOp
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> BinaryOp -> c BinaryOp)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c BinaryOp)
-> (BinaryOp -> Constr)
-> (BinaryOp -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c BinaryOp))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c BinaryOp))
-> ((forall b. Data b => b -> b) -> BinaryOp -> BinaryOp)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> BinaryOp -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> BinaryOp -> r)
-> (forall u. (forall d. Data d => d -> u) -> BinaryOp -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> BinaryOp -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> BinaryOp -> m BinaryOp)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> BinaryOp -> m BinaryOp)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> BinaryOp -> m BinaryOp)
-> Data BinaryOp
BinaryOp -> Constr
BinaryOp -> DataType
(forall b. Data b => b -> b) -> BinaryOp -> BinaryOp
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> BinaryOp -> u
forall u. (forall d. Data d => d -> u) -> BinaryOp -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> BinaryOp -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> BinaryOp -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> BinaryOp -> m BinaryOp
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> BinaryOp -> m BinaryOp
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c BinaryOp
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> BinaryOp -> c BinaryOp
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c BinaryOp)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c BinaryOp)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> BinaryOp -> c BinaryOp
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> BinaryOp -> c BinaryOp
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c BinaryOp
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c BinaryOp
$ctoConstr :: BinaryOp -> Constr
toConstr :: BinaryOp -> Constr
$cdataTypeOf :: BinaryOp -> DataType
dataTypeOf :: BinaryOp -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c BinaryOp)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c BinaryOp)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c BinaryOp)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c BinaryOp)
$cgmapT :: (forall b. Data b => b -> b) -> BinaryOp -> BinaryOp
gmapT :: (forall b. Data b => b -> b) -> BinaryOp -> BinaryOp
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> BinaryOp -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> BinaryOp -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> BinaryOp -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> BinaryOp -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> BinaryOp -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> BinaryOp -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> BinaryOp -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> BinaryOp -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> BinaryOp -> m BinaryOp
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> BinaryOp -> m BinaryOp
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> BinaryOp -> m BinaryOp
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> BinaryOp -> m BinaryOp
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> BinaryOp -> m BinaryOp
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> BinaryOp -> m BinaryOp
Data, BinaryOp -> BinaryOp -> Bool
(BinaryOp -> BinaryOp -> Bool)
-> (BinaryOp -> BinaryOp -> Bool) -> Eq BinaryOp
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: BinaryOp -> BinaryOp -> Bool
== :: BinaryOp -> BinaryOp -> Bool
$c/= :: BinaryOp -> BinaryOp -> Bool
/= :: BinaryOp -> BinaryOp -> Bool
Eq, Eq BinaryOp
Eq BinaryOp
-> (BinaryOp -> BinaryOp -> Ordering)
-> (BinaryOp -> BinaryOp -> Bool)
-> (BinaryOp -> BinaryOp -> Bool)
-> (BinaryOp -> BinaryOp -> Bool)
-> (BinaryOp -> BinaryOp -> Bool)
-> (BinaryOp -> BinaryOp -> BinaryOp)
-> (BinaryOp -> BinaryOp -> BinaryOp)
-> Ord BinaryOp
BinaryOp -> BinaryOp -> Bool
BinaryOp -> BinaryOp -> Ordering
BinaryOp -> BinaryOp -> BinaryOp
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: BinaryOp -> BinaryOp -> Ordering
compare :: BinaryOp -> BinaryOp -> Ordering
$c< :: BinaryOp -> BinaryOp -> Bool
< :: BinaryOp -> BinaryOp -> Bool
$c<= :: BinaryOp -> BinaryOp -> Bool
<= :: BinaryOp -> BinaryOp -> Bool
$c> :: BinaryOp -> BinaryOp -> Bool
> :: BinaryOp -> BinaryOp -> Bool
$c>= :: BinaryOp -> BinaryOp -> Bool
>= :: BinaryOp -> BinaryOp -> Bool
$cmax :: BinaryOp -> BinaryOp -> BinaryOp
max :: BinaryOp -> BinaryOp -> BinaryOp
$cmin :: BinaryOp -> BinaryOp -> BinaryOp
min :: BinaryOp -> BinaryOp -> BinaryOp
Ord, ReadPrec [BinaryOp]
ReadPrec BinaryOp
Int -> ReadS BinaryOp
ReadS [BinaryOp]
(Int -> ReadS BinaryOp)
-> ReadS [BinaryOp]
-> ReadPrec BinaryOp
-> ReadPrec [BinaryOp]
-> Read BinaryOp
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS BinaryOp
readsPrec :: Int -> ReadS BinaryOp
$creadList :: ReadS [BinaryOp]
readList :: ReadS [BinaryOp]
$creadPrec :: ReadPrec BinaryOp
readPrec :: ReadPrec BinaryOp
$creadListPrec :: ReadPrec [BinaryOp]
readListPrec :: ReadPrec [BinaryOp]
Read, Int -> BinaryOp -> ShowS
[BinaryOp] -> ShowS
BinaryOp -> String
(Int -> BinaryOp -> ShowS)
-> (BinaryOp -> String) -> ([BinaryOp] -> ShowS) -> Show BinaryOp
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> BinaryOp -> ShowS
showsPrec :: Int -> BinaryOp -> ShowS
$cshow :: BinaryOp -> String
show :: BinaryOp -> String
$cshowList :: [BinaryOp] -> ShowS
showList :: [BinaryOp] -> ShowS
Show, Typeable, Int -> BinaryOp
BinaryOp -> Int
BinaryOp -> [BinaryOp]
BinaryOp -> BinaryOp
BinaryOp -> BinaryOp -> [BinaryOp]
BinaryOp -> BinaryOp -> BinaryOp -> [BinaryOp]
(BinaryOp -> BinaryOp)
-> (BinaryOp -> BinaryOp)
-> (Int -> BinaryOp)
-> (BinaryOp -> Int)
-> (BinaryOp -> [BinaryOp])
-> (BinaryOp -> BinaryOp -> [BinaryOp])
-> (BinaryOp -> BinaryOp -> [BinaryOp])
-> (BinaryOp -> BinaryOp -> BinaryOp -> [BinaryOp])
-> Enum BinaryOp
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: BinaryOp -> BinaryOp
succ :: BinaryOp -> BinaryOp
$cpred :: BinaryOp -> BinaryOp
pred :: BinaryOp -> BinaryOp
$ctoEnum :: Int -> BinaryOp
toEnum :: Int -> BinaryOp
$cfromEnum :: BinaryOp -> Int
fromEnum :: BinaryOp -> Int
$cenumFrom :: BinaryOp -> [BinaryOp]
enumFrom :: BinaryOp -> [BinaryOp]
$cenumFromThen :: BinaryOp -> BinaryOp -> [BinaryOp]
enumFromThen :: BinaryOp -> BinaryOp -> [BinaryOp]
$cenumFromTo :: BinaryOp -> BinaryOp -> [BinaryOp]
enumFromTo :: BinaryOp -> BinaryOp -> [BinaryOp]
$cenumFromThenTo :: BinaryOp -> BinaryOp -> BinaryOp -> [BinaryOp]
enumFromThenTo :: BinaryOp -> BinaryOp -> BinaryOp -> [BinaryOp]
Enum, BinaryOp
BinaryOp -> BinaryOp -> Bounded BinaryOp
forall a. a -> a -> Bounded a
$cminBound :: BinaryOp
minBound :: BinaryOp
$cmaxBound :: BinaryOp
maxBound :: BinaryOp
Bounded, (forall x. BinaryOp -> Rep BinaryOp x)
-> (forall x. Rep BinaryOp x -> BinaryOp) -> Generic BinaryOp
forall x. Rep BinaryOp x -> BinaryOp
forall x. BinaryOp -> Rep BinaryOp x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. BinaryOp -> Rep BinaryOp x
from :: forall x. BinaryOp -> Rep BinaryOp x
$cto :: forall x. Rep BinaryOp x -> BinaryOp
to :: forall x. Rep BinaryOp x -> BinaryOp
Generic)

instance Operator BinaryOp where
    operatorTable :: [(BinaryOp, String)]
operatorTable =
        [BinaryOp] -> [String] -> [(BinaryOp, String)]
forall a b. [a] -> [b] -> [(a, b)]
zip [BinaryOp
forall a. Bounded a => a
minBound .. BinaryOp
forall a. Bounded a => a
maxBound]
            [ String
"-ef", String
"-nt", String
"-ot"
            , String
"=~", String
"==", String
"!=", String
"<", String
">"
            , String
"-eq", String
"-ne", String
"-lt", String
"-le", String
"-gt", String
"-ge"
            ] [(BinaryOp, String)]
-> [(BinaryOp, String)] -> [(BinaryOp, String)]
forall a. [a] -> [a] -> [a]
++
        [ (BinaryOp
StrEQ, String
"=") ]

instance Pretty BinaryOp where
    pretty :: forall ann. BinaryOp -> Doc ann
pretty = BinaryOp -> Doc ann
forall a ann. Operator a => a -> Doc ann
prettyOperator

-- | A parser over lists of strings.
type Parser = Parsec [String] ()

-- | Parse a token.
token :: (String -> Maybe a) -> Parser a
token :: forall a. (String -> Maybe a) -> Parser a
token = ShowS
-> (SourcePos -> String -> [String] -> SourcePos)
-> (String -> Maybe a)
-> ParsecT [String] () Identity a
forall s (m :: * -> *) t a u.
Stream s m t =>
(t -> String)
-> (SourcePos -> t -> s -> SourcePos)
-> (t -> Maybe a)
-> ParsecT s u m a
tokenPrim ShowS
forall a. Show a => a -> String
show (\SourcePos
pos String
_ [String]
_ -> SourcePos
pos)

-- | Parse a specific word.
word :: String -> Parser String
word :: String -> Parser String
word String
s = (String -> Maybe String) -> Parser String
forall a. (String -> Maybe a) -> Parser a
token (\String
t -> if String
t String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
s then String -> Maybe String
forall a. a -> Maybe a
Just String
s else Maybe String
forall a. Maybe a
Nothing) Parser String -> String -> Parser String
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
s

-- | Parse any word.
anyWord :: Parser String
anyWord :: Parser String
anyWord = (String -> Maybe String) -> Parser String
forall a. (String -> Maybe a) -> Parser a
token String -> Maybe String
forall a. a -> Maybe a
Just

-- | Parse in parentheses.
parens :: Parser a -> Parser a
parens :: forall a. Parser a -> Parser a
parens Parser a
p = String -> Parser String
word String
"(" Parser String -> Parser a -> Parser a
forall a b.
ParsecT [String] () Identity a
-> ParsecT [String] () Identity b -> ParsecT [String] () Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser a
p Parser a -> Parser String -> Parser a
forall a b.
ParsecT [String] () Identity a
-> ParsecT [String] () Identity b -> ParsecT [String] () Identity a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* String -> Parser String
word String
")"

-- | Parse a nullary expression
nullaryExpr :: Parser (CondExpr String)
nullaryExpr :: Parser (CondExpr String)
nullaryExpr = UnaryOp -> String -> CondExpr String
forall a. UnaryOp -> a -> CondExpr a
Unary UnaryOp
NonzeroString (String -> CondExpr String)
-> Parser String -> Parser (CondExpr String)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser String
anyWord

-- | Parse a unary expression.
unaryExpr :: Parser (CondExpr String)
unaryExpr :: Parser (CondExpr String)
unaryExpr = UnaryOp -> String -> CondExpr String
forall a. UnaryOp -> a -> CondExpr a
Unary (UnaryOp -> String -> CondExpr String)
-> ParsecT [String] () Identity UnaryOp
-> ParsecT [String] () Identity (String -> CondExpr String)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (String -> Parser String)
-> [(UnaryOp, String)] -> ParsecT [String] () Identity UnaryOp
forall (f :: * -> *) b c a.
Alternative f =>
(b -> f c) -> [(a, b)] -> f a
select String -> Parser String
word [(UnaryOp, String)]
unaryOps ParsecT [String] () Identity (String -> CondExpr String)
-> Parser String -> Parser (CondExpr String)
forall a b.
ParsecT [String] () Identity (a -> b)
-> ParsecT [String] () Identity a -> ParsecT [String] () Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser String
anyWord
        Parser (CondExpr String) -> String -> Parser (CondExpr String)
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"unary expression"
  where
    unaryOps :: [(UnaryOp, String)]
unaryOps = ((UnaryOp, String) -> Bool)
-> [(UnaryOp, String)] -> [(UnaryOp, String)]
forall a. (a -> Bool) -> [a] -> [a]
filter ((String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [String
"-a", String
"-o"]) (String -> Bool)
-> ((UnaryOp, String) -> String) -> (UnaryOp, String) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (UnaryOp, String) -> String
forall a b. (a, b) -> b
snd) [(UnaryOp, String)]
forall a. Operator a => [(a, String)]
operatorTable

-- | Parse a standalone unary expression.
standaloneUnaryExpr :: Parser (CondExpr String)
standaloneUnaryExpr :: Parser (CondExpr String)
standaloneUnaryExpr = UnaryOp -> String -> CondExpr String
forall a. UnaryOp -> a -> CondExpr a
Unary (UnaryOp -> String -> CondExpr String)
-> ParsecT [String] () Identity UnaryOp
-> ParsecT [String] () Identity (String -> CondExpr String)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (String -> Parser String) -> ParsecT [String] () Identity UnaryOp
forall (f :: * -> *) a c.
(Alternative f, Operator a) =>
(String -> f c) -> f a
selectOperator String -> Parser String
word ParsecT [String] () Identity (String -> CondExpr String)
-> Parser String -> Parser (CondExpr String)
forall a b.
ParsecT [String] () Identity (a -> b)
-> ParsecT [String] () Identity a -> ParsecT [String] () Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser String
anyWord
                  Parser (CondExpr String) -> String -> Parser (CondExpr String)
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"unary expression"

-- | Parse a binary expression.
binaryExpr :: Parser (CondExpr String)
binaryExpr :: Parser (CondExpr String)
binaryExpr = String -> BinaryOp -> String -> CondExpr String
forall a. a -> BinaryOp -> a -> CondExpr a
Binary (String -> BinaryOp -> String -> CondExpr String)
-> Parser String
-> ParsecT
     [String] () Identity (BinaryOp -> String -> CondExpr String)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser String
anyWord ParsecT
  [String] () Identity (BinaryOp -> String -> CondExpr String)
-> ParsecT [String] () Identity BinaryOp
-> ParsecT [String] () Identity (String -> CondExpr String)
forall a b.
ParsecT [String] () Identity (a -> b)
-> ParsecT [String] () Identity a -> ParsecT [String] () Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (String -> Parser String)
-> [(BinaryOp, String)] -> ParsecT [String] () Identity BinaryOp
forall (f :: * -> *) b c a.
Alternative f =>
(b -> f c) -> [(a, b)] -> f a
select String -> Parser String
word [(BinaryOp, String)]
binaryOps ParsecT [String] () Identity (String -> CondExpr String)
-> Parser String -> Parser (CondExpr String)
forall a b.
ParsecT [String] () Identity (a -> b)
-> ParsecT [String] () Identity a -> ParsecT [String] () Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser String
anyWord
         Parser (CondExpr String) -> String -> Parser (CondExpr String)
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"binary expression"
  where
    binaryOps :: [(BinaryOp, String)]
binaryOps = ((BinaryOp, String) -> Bool)
-> [(BinaryOp, String)] -> [(BinaryOp, String)]
forall a. (a -> Bool) -> [a] -> [a]
filter ((String -> String -> Bool
forall a. Eq a => a -> a -> Bool
/= String
"=~") (String -> Bool)
-> ((BinaryOp, String) -> String) -> (BinaryOp, String) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (BinaryOp, String) -> String
forall a b. (a, b) -> b
snd) [(BinaryOp, String)]
forall a. Operator a => [(a, String)]
operatorTable

-- | Parse a binary @-a@ or @-o@ expression.
binaryAndOrExpr :: Parser (CondExpr String)
binaryAndOrExpr :: Parser (CondExpr String)
binaryAndOrExpr = Parser (CondExpr String)
nullaryExpr Parser (CondExpr String)
-> ParsecT
     [String]
     ()
     Identity
     (CondExpr String -> CondExpr String -> CondExpr String)
-> ParsecT
     [String] () Identity (CondExpr String -> CondExpr String)
forall (f :: * -> *) a b. Applicative f => f a -> f (a -> b) -> f b
<**> ParsecT
  [String]
  ()
  Identity
  (CondExpr String -> CondExpr String -> CondExpr String)
forall {a}.
ParsecT
  [String] () Identity (CondExpr a -> CondExpr a -> CondExpr a)
andOrOp ParsecT [String] () Identity (CondExpr String -> CondExpr String)
-> Parser (CondExpr String) -> Parser (CondExpr String)
forall a b.
ParsecT [String] () Identity (a -> b)
-> ParsecT [String] () Identity a -> ParsecT [String] () Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (CondExpr String)
nullaryExpr
  where
    andOrOp :: ParsecT
  [String] () Identity (CondExpr a -> CondExpr a -> CondExpr a)
andOrOp = CondExpr a -> CondExpr a -> CondExpr a
forall a. CondExpr a -> CondExpr a -> CondExpr a
And (CondExpr a -> CondExpr a -> CondExpr a)
-> Parser String
-> ParsecT
     [String] () Identity (CondExpr a -> CondExpr a -> CondExpr a)
forall a b.
a
-> ParsecT [String] () Identity b -> ParsecT [String] () Identity a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> Parser String
word String
"-a"
          ParsecT
  [String] () Identity (CondExpr a -> CondExpr a -> CondExpr a)
-> ParsecT
     [String] () Identity (CondExpr a -> CondExpr a -> CondExpr a)
-> ParsecT
     [String] () Identity (CondExpr a -> CondExpr a -> CondExpr a)
forall a.
ParsecT [String] () Identity a
-> ParsecT [String] () Identity a -> ParsecT [String] () Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> CondExpr a -> CondExpr a -> CondExpr a
forall a. CondExpr a -> CondExpr a -> CondExpr a
Or  (CondExpr a -> CondExpr a -> CondExpr a)
-> Parser String
-> ParsecT
     [String] () Identity (CondExpr a -> CondExpr a -> CondExpr a)
forall a b.
a
-> ParsecT [String] () Identity b -> ParsecT [String] () Identity a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> Parser String
word String
"-o"

-- | Parse a conditional expression.
condExpr :: Parser (CondExpr String)
condExpr :: Parser (CondExpr String)
condExpr = Parser (CondExpr String)
expr
  where
    expr :: Parser (CondExpr String)
expr = OperatorTable [String] () Identity (CondExpr String)
-> Parser (CondExpr String) -> Parser (CondExpr String)
forall s (m :: * -> *) t u a.
Stream s m t =>
OperatorTable s u m a -> ParsecT s u m a -> ParsecT s u m a
buildExpressionParser OperatorTable [String] () Identity (CondExpr String)
forall {a}. [[Operator [String] () Identity (CondExpr a)]]
opTable Parser (CondExpr String)
term

    term :: Parser (CondExpr String)
term = Parser (CondExpr String) -> Parser (CondExpr String)
forall a. Parser a -> Parser a
parens Parser (CondExpr String)
expr
       Parser (CondExpr String)
-> Parser (CondExpr String) -> Parser (CondExpr String)
forall a.
ParsecT [String] () Identity a
-> ParsecT [String] () Identity a -> ParsecT [String] () Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser (CondExpr String)
unaryExpr
       Parser (CondExpr String)
-> Parser (CondExpr String) -> Parser (CondExpr String)
forall a.
ParsecT [String] () Identity a
-> ParsecT [String] () Identity a -> ParsecT [String] () Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser (CondExpr String) -> Parser (CondExpr String)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try Parser (CondExpr String)
binaryExpr
       Parser (CondExpr String)
-> Parser (CondExpr String) -> Parser (CondExpr String)
forall a.
ParsecT [String] () Identity a
-> ParsecT [String] () Identity a -> ParsecT [String] () Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser (CondExpr String)
nullaryExpr

    opTable :: [[Operator [String] () Identity (CondExpr a)]]
opTable =
        [ [ParsecT [String] () Identity (CondExpr a -> CondExpr a)
-> Operator [String] () Identity (CondExpr a)
forall s u (m :: * -> *) a.
ParsecT s u m (a -> a) -> Operator s u m a
Prefix (CondExpr a -> CondExpr a
forall a. CondExpr a -> CondExpr a
Not (CondExpr a -> CondExpr a)
-> Parser String
-> ParsecT [String] () Identity (CondExpr a -> CondExpr a)
forall a b.
a
-> ParsecT [String] () Identity b -> ParsecT [String] () Identity a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> Parser String
word String
"!")]
        , [ParsecT
  [String] () Identity (CondExpr a -> CondExpr a -> CondExpr a)
-> Assoc -> Operator [String] () Identity (CondExpr a)
forall s u (m :: * -> *) a.
ParsecT s u m (a -> a -> a) -> Assoc -> Operator s u m a
Infix  (CondExpr a -> CondExpr a -> CondExpr a
forall a. CondExpr a -> CondExpr a -> CondExpr a
And (CondExpr a -> CondExpr a -> CondExpr a)
-> Parser String
-> ParsecT
     [String] () Identity (CondExpr a -> CondExpr a -> CondExpr a)
forall a b.
a
-> ParsecT [String] () Identity b -> ParsecT [String] () Identity a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> Parser String
word String
"-a") Assoc
AssocLeft]
        , [ParsecT
  [String] () Identity (CondExpr a -> CondExpr a -> CondExpr a)
-> Assoc -> Operator [String] () Identity (CondExpr a)
forall s u (m :: * -> *) a.
ParsecT s u m (a -> a -> a) -> Assoc -> Operator s u m a
Infix  (CondExpr a -> CondExpr a -> CondExpr a
forall a. CondExpr a -> CondExpr a -> CondExpr a
Or  (CondExpr a -> CondExpr a -> CondExpr a)
-> Parser String
-> ParsecT
     [String] () Identity (CondExpr a -> CondExpr a -> CondExpr a)
forall a b.
a
-> ParsecT [String] () Identity b -> ParsecT [String] () Identity a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> Parser String
word String
"-o") Assoc
AssocLeft]
        ]

-- | Parse a conditional expression for the Bash @test@ builtin.
parseTestExpr :: [String] -> Either ParseError (CondExpr String)
parseTestExpr :: [String] -> Either ParseError (CondExpr String)
parseTestExpr [String]
args = Parser (CondExpr String)
-> String -> [String] -> Either ParseError (CondExpr String)
forall s t a.
Stream s Identity t =>
Parsec s () a -> String -> s -> Either ParseError a
parse (Parser (CondExpr String)
testExpr Parser (CondExpr String)
-> ParsecT [String] () Identity () -> Parser (CondExpr String)
forall a b.
ParsecT [String] () Identity a
-> ParsecT [String] () Identity b -> ParsecT [String] () Identity a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT [String] () Identity ()
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof) String
"" [String]
args
  where
    testExpr :: Parser (CondExpr String)
testExpr = case [String] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [String]
args of
        Int
0 -> String -> Parser (CondExpr String)
forall a. String -> ParsecT [String] () Identity a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"no arguments"
        Int
1 -> Parser (CondExpr String)
oneArg
        Int
2 -> Parser (CondExpr String)
twoArg
        Int
3 -> Parser (CondExpr String)
threeArg
        Int
4 -> Parser (CondExpr String)
fourArg
        Int
_ -> Parser (CondExpr String)
condExpr

    oneArg :: Parser (CondExpr String)
oneArg = Parser (CondExpr String)
nullaryExpr

    twoArg :: Parser (CondExpr String)
twoArg = Parser (CondExpr String) -> Parser (CondExpr String)
forall {a}.
ParsecT [String] () Identity (CondExpr a)
-> ParsecT [String] () Identity (CondExpr a)
negate Parser (CondExpr String)
nullaryExpr
         Parser (CondExpr String)
-> Parser (CondExpr String) -> Parser (CondExpr String)
forall a.
ParsecT [String] () Identity a
-> ParsecT [String] () Identity a -> ParsecT [String] () Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser (CondExpr String)
standaloneUnaryExpr

    threeArg :: Parser (CondExpr String)
threeArg = Parser (CondExpr String) -> Parser (CondExpr String)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try Parser (CondExpr String)
binaryExpr
           Parser (CondExpr String)
-> Parser (CondExpr String) -> Parser (CondExpr String)
forall a.
ParsecT [String] () Identity a
-> ParsecT [String] () Identity a -> ParsecT [String] () Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser (CondExpr String) -> Parser (CondExpr String)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try Parser (CondExpr String)
binaryAndOrExpr
           Parser (CondExpr String)
-> Parser (CondExpr String) -> Parser (CondExpr String)
forall a.
ParsecT [String] () Identity a
-> ParsecT [String] () Identity a -> ParsecT [String] () Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser (CondExpr String) -> Parser (CondExpr String)
forall {a}.
ParsecT [String] () Identity (CondExpr a)
-> ParsecT [String] () Identity (CondExpr a)
negate Parser (CondExpr String)
twoArg
           Parser (CondExpr String)
-> Parser (CondExpr String) -> Parser (CondExpr String)
forall a.
ParsecT [String] () Identity a
-> ParsecT [String] () Identity a -> ParsecT [String] () Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser (CondExpr String) -> Parser (CondExpr String)
forall a. Parser a -> Parser a
parens Parser (CondExpr String)
nullaryExpr

    fourArg :: Parser (CondExpr String)
fourArg = Parser (CondExpr String) -> Parser (CondExpr String)
forall {a}.
ParsecT [String] () Identity (CondExpr a)
-> ParsecT [String] () Identity (CondExpr a)
negate Parser (CondExpr String)
threeArg
          Parser (CondExpr String)
-> Parser (CondExpr String) -> Parser (CondExpr String)
forall a.
ParsecT [String] () Identity a
-> ParsecT [String] () Identity a -> ParsecT [String] () Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser (CondExpr String)
condExpr

    negate :: ParsecT [String] () Identity (CondExpr a)
-> ParsecT [String] () Identity (CondExpr a)
negate ParsecT [String] () Identity (CondExpr a)
p = CondExpr a -> CondExpr a
forall a. CondExpr a -> CondExpr a
Not (CondExpr a -> CondExpr a)
-> Parser String
-> ParsecT [String] () Identity (CondExpr a -> CondExpr a)
forall a b.
a
-> ParsecT [String] () Identity b -> ParsecT [String] () Identity a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> Parser String
word String
"!" ParsecT [String] () Identity (CondExpr a -> CondExpr a)
-> ParsecT [String] () Identity (CondExpr a)
-> ParsecT [String] () Identity (CondExpr a)
forall a b.
ParsecT [String] () Identity (a -> b)
-> ParsecT [String] () Identity a -> ParsecT [String] () Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT [String] () Identity (CondExpr a)
p