module Parsers.Haskell.Pattern where

import Parsers.Haskell.Common      (literal, qCtor, qCtorOp, token, var)
import SyntaxTrees.Haskell.Pattern (Pattern (..))

import Bookhound.Parser              (Parser)
import Bookhound.ParserCombinators   (IsMatch (is), anySepBy, sepByOp, (<|>),
                                      (|+), (|?))
import Bookhound.Parsers.Char        (comma, underscore)
import Bookhound.Parsers.Collections (listOf, tupleOf)
import Bookhound.Parsers.String      (maybeWithinParens, withinCurlyBrackets,
                                      withinParens)



pattern' :: Parser Pattern
pattern' :: Parser Pattern
pattern' =  Parser Pattern
pattern'' forall a. Parser a -> Parser a -> Parser a
<|> forall b. Parser b -> Parser b
maybeWithinParens Parser Pattern
pattern''
  where
    ctor' :: Parser Pattern
ctor'       = QCtor -> [Pattern] -> Pattern
CtorPattern forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser QCtor
qCtor forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Parser Pattern
ctorElem' |+)
    nullaryCtor :: Parser Pattern
nullaryCtor = QCtor -> [Pattern] -> Pattern
CtorPattern forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser QCtor
qCtor forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (f :: * -> *) a. Applicative f => a -> f a
pure []
    infixCtor :: Parser Pattern
infixCtor   = forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry QCtorOp -> [Pattern] -> Pattern
InfixCtorPattern forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a b. Parser a -> Parser b -> Parser (a, [b])
sepByOp Parser QCtorOp
qCtorOp (Parser Pattern
ctor' forall a. Parser a -> Parser a -> Parser a
<|> Parser Pattern
ctorElem')

    record :: Parser Pattern
record = QCtor -> [(Var, Maybe Pattern)] -> Pattern
RecordPattern forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser QCtor
qCtor forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser [(Var, Maybe Pattern)]
recordShape
    recordWildcard :: Parser Pattern
recordWildcard = QCtor -> [(Var, Maybe Pattern)] -> Pattern
WildcardRecordPattern forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser QCtor
qCtor
                                           forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser [(Var, Maybe Pattern)]
wildcardRecordShape

    alias :: Parser Pattern
alias    = Var -> Pattern -> Pattern
AliasedPattern forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser Var
var forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall a. IsMatch a => a -> Parser a
is String
"@") forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Pattern
aliasElem'
    var' :: Parser Pattern
var'     = Var -> Pattern
VarPattern forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Var
var
    literal' :: Parser Pattern
literal' = Literal -> Pattern
LitPattern forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Literal
literal
    wildcard :: Parser Pattern
wildcard = Pattern
Wildcard forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall b. Parser b -> Parser b
token Parser Char
underscore

    list :: Parser Pattern
list          = [Pattern] -> Pattern
ListPattern forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Parser a -> Parser [a]
listOf Parser Pattern
pattern'
    tuple :: Parser Pattern
tuple         = [Pattern] -> Pattern
TuplePattern forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall a. Parser a -> Parser [a]
tupleOf Parser Pattern
pattern')
    recordField :: Parser (Var, Maybe Pattern)
recordField   = (,) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Var
var forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ((forall a. IsMatch a => a -> Parser a
is String
"=" forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser Pattern
pattern'') |?)
    recordShape :: Parser [(Var, Maybe Pattern)]
recordShape = forall b. Parser b -> Parser b
withinCurlyBrackets (forall a b. Parser a -> Parser b -> Parser [b]
anySepBy Parser Char
comma Parser (Var, Maybe Pattern)
recordField)
    wildcardRecordShape :: Parser [(Var, Maybe Pattern)]
wildcardRecordShape =
      forall b. Parser b -> Parser b
withinCurlyBrackets (forall a b. Parser a -> Parser b -> Parser [b]
anySepBy Parser Char
comma Parser (Var, Maybe Pattern)
recordField forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall b. Parser b -> Parser b
token Parser Char
comma forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall a. IsMatch a => a -> Parser a
is String
"..")

    elem' :: Parser Pattern
elem' =  Parser Pattern
literal' forall a. Parser a -> Parser a -> Parser a
<|> Parser Pattern
var' forall a. Parser a -> Parser a -> Parser a
<|> Parser Pattern
alias forall a. Parser a -> Parser a -> Parser a
<|> Parser Pattern
wildcard forall a. Parser a -> Parser a -> Parser a
<|> Parser Pattern
nullaryCtor forall a. Parser a -> Parser a -> Parser a
<|>
            forall b. Parser b -> Parser b
withinParens Parser Pattern
nullaryCtor forall a. Parser a -> Parser a -> Parser a
<|>
            Parser Pattern
tuple forall a. Parser a -> Parser a -> Parser a
<|> Parser Pattern
list

    ctorElem' :: Parser Pattern
ctorElem' = Parser Pattern
record forall a. Parser a -> Parser a -> Parser a
<|> Parser Pattern
recordWildcard forall a. Parser a -> Parser a -> Parser a
<|> Parser Pattern
alias forall a. Parser a -> Parser a -> Parser a
<|> Parser Pattern
elem' forall a. Parser a -> Parser a -> Parser a
<|>
                forall b. Parser b -> Parser b
withinParens (Parser Pattern
ctor' forall a. Parser a -> Parser a -> Parser a
<|> Parser Pattern
infixCtor)

    aliasElem' :: Parser Pattern
aliasElem' = Parser Pattern
elem' forall a. Parser a -> Parser a -> Parser a
<|> Parser Pattern
record forall a. Parser a -> Parser a -> Parser a
<|> Parser Pattern
recordWildcard forall a. Parser a -> Parser a -> Parser a
<|>
                 forall b. Parser b -> Parser b
withinParens (Parser Pattern
ctor' forall a. Parser a -> Parser a -> Parser a
<|> Parser Pattern
infixCtor)

    pattern'' :: Parser Pattern
pattern'' = Parser Pattern
alias forall a. Parser a -> Parser a -> Parser a
<|> Parser Pattern
infixCtor forall a. Parser a -> Parser a -> Parser a
<|> Parser Pattern
ctor' forall a. Parser a -> Parser a -> Parser a
<|> Parser Pattern
ctorElem'