module Parsers.Haskell.ModuleDef where


import Parsers.Haskell.ClassDef (classDef, derivingDef, instanceDef)
import Parsers.Haskell.Common   (module', token, var, varOp)
import Parsers.Haskell.DataDef  (dataDef, newtypeDef, typeDef)
import Parsers.Haskell.FnDef    (fnDef, fnSig, infixAnnotation,
                                 withinContextTupled)
import Parsers.Haskell.Type     (typeVar)

import SyntaxTrees.Haskell.FnDef     (FnDefOrSig (..))
import SyntaxTrees.Haskell.ModuleDef (ImportExportDef (..), InternalDef (..),
                                      ModuleDef (..), ModuleExport (..),
                                      ModuleExportDef (..), ModuleImport (..),
                                      ModuleImportDef (..), ModuleMember (..))

import Bookhound.Parser            (Parser)
import Bookhound.ParserCombinators (IsMatch (is), anySepBy, maybeWithin, (<|>),
                                    (|?))
import Bookhound.Parsers.Char      (comma)
import Bookhound.Parsers.String    (spacing, withinParens)


import Data.Foldable (Foldable (fold))
import Data.Maybe    (isJust)



moduleDef :: Parser ModuleDef
moduleDef :: Parser ModuleDef
moduleDef = forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
              (Module
-> Maybe ModuleExport
-> [ModuleImport]
-> [InternalDef]
-> ModuleDef
ModuleDef forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall a. IsMatch a => a -> Parser a
is String
"module" forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser Module
module')
                         forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Parser ModuleExport
moduleExport |?)
                         forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<*  forall a. IsMatch a => a -> Parser a
is String
"where")
                         forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a1 a2. Parser a1 -> Parser a2 -> Parser ([a1], [a2])
withinContextTupled Parser ModuleImport
moduleImport Parser InternalDef
internalDef



moduleExport :: Parser ModuleExport
moduleExport :: Parser ModuleExport
moduleExport = [ModuleExportDef] -> ModuleExport
ModuleExport forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall b. Parser b -> Parser b
withinParens (forall a b. Parser a -> Parser b -> Parser [b]
anySepBy Parser Char
comma Parser ModuleExportDef
moduleExportDef)


moduleExportDef :: Parser ModuleExportDef
moduleExportDef :: Parser ModuleExportDef
moduleExportDef = ImportExportDef -> ModuleExportDef
ModuleExportDef  forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ImportExportDef
importExportDef forall a. Parser a -> Parser a -> Parser a
<|>
                  Module -> ModuleExportDef
FullModuleExport forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall a. IsMatch a => a -> Parser a
is String
"module" forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser Module
module')

moduleImport :: Parser ModuleImport
moduleImport :: Parser ModuleImport
moduleImport = Bool
-> Module
-> Maybe Module
-> Bool
-> [ModuleImportDef]
-> ModuleImport
ModuleImport forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall b. Parser b -> Parser b
token (forall a. IsMatch a => a -> Parser a
is String
"import") forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*>
                                 (forall a. Maybe a -> Bool
isJust forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall a. IsMatch a => a -> Parser a
is String
"qualified" |?)))
                            forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Module
module'
                            forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ((forall a. IsMatch a => a -> Parser a
is String
"as" forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser Module
module') |?)
                            forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (forall a. Maybe a -> Bool
isJust forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall a. IsMatch a => a -> Parser a
is String
"hiding" |?))
                            forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser [ModuleImportDef]
defs |?))
  where
    defs :: Parser [ModuleImportDef]
defs = forall b. Parser b -> Parser b
withinParens forall a b. (a -> b) -> a -> b
$ forall a b. Parser a -> Parser b -> Parser [b]
anySepBy Parser Char
comma forall a b. (a -> b) -> a -> b
$ forall a b. Parser a -> Parser b -> Parser b
maybeWithin Parser String
spacing Parser ModuleImportDef
moduleImportDef


moduleImportDef :: Parser ModuleImportDef
moduleImportDef :: Parser ModuleImportDef
moduleImportDef = ImportExportDef -> ModuleImportDef
ModuleImportDef forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ImportExportDef
importExportDef


importExportDef :: Parser ImportExportDef
importExportDef :: Parser ImportExportDef
importExportDef = TypeVar -> ImportExportDef
FullData     forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser TypeVar
typeVar
                               forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<*  forall b. Parser b -> Parser b
withinParens (forall a. IsMatch a => a -> Parser a
is String
"..")      forall a. Parser a -> Parser a -> Parser a
<|>
                  TypeVar -> [ModuleMember] -> ImportExportDef
FilteredData forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser TypeVar
typeVar
                               forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall b. Parser b -> Parser b
withinParens
                                 (forall a b. Parser a -> Parser b -> Parser [b]
anySepBy Parser Char
comma Parser ModuleMember
moduleMember) forall a. Parser a -> Parser a -> Parser a
<|>
                  ModuleMember -> ImportExportDef
Member       forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ModuleMember
moduleMember


moduleMember :: Parser ModuleMember
moduleMember :: Parser ModuleMember
moduleMember = VarOp -> ModuleMember
VarOpMember forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall b. Parser b -> Parser b
withinParens Parser VarOp
varOp forall a. Parser a -> Parser a -> Parser a
<|>
               Var -> ModuleMember
VarMember   forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Var
var                forall a. Parser a -> Parser a -> Parser a
<|>
               TypeVar -> ModuleMember
DataMember  forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser TypeVar
typeVar

internalDef :: Parser InternalDef
internalDef :: Parser InternalDef
internalDef = FnDefOrSig -> InternalDef
FnDefOrSig' forall b c a. (b -> c) -> (a -> b) -> a -> c
. FnDef -> FnDefOrSig
Def  forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser FnDef
fnDef        forall a. Parser a -> Parser a -> Parser a
<|>
              FnDefOrSig -> InternalDef
FnDefOrSig' forall b c a. (b -> c) -> (a -> b) -> a -> c
. FnSig -> FnDefOrSig
Sig  forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser FnSig
fnSig        forall a. Parser a -> Parser a -> Parser a
<|>
              TypeDef -> InternalDef
TypeDef'           forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser TypeDef
typeDef      forall a. Parser a -> Parser a -> Parser a
<|>
              NewTypeDef -> InternalDef
NewTypeDef'        forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser NewTypeDef
newtypeDef   forall a. Parser a -> Parser a -> Parser a
<|>
              DataDef -> InternalDef
DataDef'           forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser DataDef
dataDef      forall a. Parser a -> Parser a -> Parser a
<|>
              ClassDef -> InternalDef
ClassDef'          forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ClassDef
classDef     forall a. Parser a -> Parser a -> Parser a
<|>
              InstanceDef -> InternalDef
InstanceDef'       forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser InstanceDef
instanceDef  forall a. Parser a -> Parser a -> Parser a
<|>
              DerivingDef -> InternalDef
DerivingDef'       forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser DerivingDef
derivingDef  forall a. Parser a -> Parser a -> Parser a
<|>
              InfixFnAnnotation -> InternalDef
InfixFnAnnotation' forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser InfixFnAnnotation
infixAnnotation