module Conversions.ToPurescript.ModuleDef where

import qualified SyntaxTrees.Haskell.ModuleDef    as H
import qualified SyntaxTrees.Haskell.Type         as H
import qualified SyntaxTrees.Purescript.Common    as P
import qualified SyntaxTrees.Purescript.ModuleDef as P

import Conversions.ToPurescript.ClassDef (classDef, derivingDef, instanceDef)
import Conversions.ToPurescript.Common   (module', var, varOp)
import Conversions.ToPurescript.DataDef  (dataDef, newtypeDef, typeDef)
import Conversions.ToPurescript.FnDef    (fnDefOrSig, infixFnAnnotation)
import Conversions.ToPurescript.Type     (typeVar)



moduleDef :: H.ModuleDef -> P.ModuleDef
moduleDef :: ModuleDef -> ModuleDef
moduleDef (H.ModuleDef Module
x Maybe ModuleExport
y [ModuleImport]
z [InternalDef]
t) =
  Module
-> Maybe ModuleExport
-> [ModuleImport]
-> [InternalDef]
-> ModuleDef
P.ModuleDef (Module -> Module
module' Module
x) (ModuleExport -> ModuleExport
moduleExport forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe ModuleExport
y)
              (ModuleImport -> ModuleImport
moduleImport forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [ModuleImport]
z) (forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap InternalDef -> [InternalDef]
internalDef [InternalDef]
t)

moduleExport :: H.ModuleExport -> P.ModuleExport
moduleExport :: ModuleExport -> ModuleExport
moduleExport (H.ModuleExport [ModuleExportDef]
x) =
  [ModuleExportDef] -> ModuleExport
P.ModuleExport forall a b. (a -> b) -> a -> b
$ ModuleExportDef -> ModuleExportDef
moduleExportDef forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [ModuleExportDef]
x

moduleExportDef :: H.ModuleExportDef -> P.ModuleExportDef
moduleExportDef :: ModuleExportDef -> ModuleExportDef
moduleExportDef (H.ModuleExportDef ImportExportDef
x)  = ImportExportDef -> ModuleExportDef
P.ModuleExportDef forall a b. (a -> b) -> a -> b
$ ImportExportDef -> ImportExportDef
importExportDef ImportExportDef
x
moduleExportDef (H.FullModuleExport Module
x) = Module -> ModuleExportDef
P.FullModuleExport forall a b. (a -> b) -> a -> b
$ Module -> Module
module' Module
x

moduleImport :: H.ModuleImport -> P.ModuleImport
moduleImport :: ModuleImport -> ModuleImport
moduleImport (H.ModuleImport Bool
_ Module
x Maybe Module
y Bool
z [ModuleImportDef]
t) =
  Module -> Bool -> [ModuleImportDef] -> Maybe Module -> ModuleImport
P.ModuleImport (Module -> Module
module' Module
x) Bool
z (ModuleImportDef -> ModuleImportDef
moduleImportDef forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [ModuleImportDef]
t) (Module -> Module
module' forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Module
y)


moduleImportDef :: H.ModuleImportDef -> P.ModuleImportDef
moduleImportDef :: ModuleImportDef -> ModuleImportDef
moduleImportDef (H.ModuleImportDef ImportExportDef
x)  = ImportExportDef -> ModuleImportDef
P.ModuleImportDef forall a b. (a -> b) -> a -> b
$ ImportExportDef -> ImportExportDef
importExportDef ImportExportDef
x


importExportDef :: H.ImportExportDef -> P.ImportExportDef
importExportDef :: ImportExportDef -> ImportExportDef
importExportDef (H.Member ModuleMember
x)       = ModuleMember -> ImportExportDef
P.Member forall a b. (a -> b) -> a -> b
$ ModuleMember -> ModuleMember
moduleMember ModuleMember
x
importExportDef (H.FullData TypeVar
x)     = TypeVar -> ImportExportDef
P.FullData forall a b. (a -> b) -> a -> b
$ TypeVar -> TypeVar
typeVar TypeVar
x
importExportDef (H.FilteredData (H.TypeVar String
name) [ModuleMember]
y)
  | forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all ModuleMember -> Bool
isVarMember [ModuleMember]
y = Class -> ImportExportDef
P.FullClass (String -> Class
P.Class String
name)
importExportDef (H.FilteredData TypeVar
x [ModuleMember]
y) =
  TypeVar -> [ModuleMember] -> ImportExportDef
P.FilteredData (TypeVar -> TypeVar
typeVar TypeVar
x) (ModuleMember -> ModuleMember
moduleMember forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [ModuleMember]
y)


isVarMember :: H.ModuleMember -> Bool
isVarMember :: ModuleMember -> Bool
isVarMember (H.VarMember Var
_)   = Bool
True
isVarMember (H.VarOpMember VarOp
_) = Bool
True
isVarMember (H.DataMember TypeVar
_)  = Bool
False

moduleMember :: H.ModuleMember -> P.ModuleMember
moduleMember :: ModuleMember -> ModuleMember
moduleMember (H.VarMember Var
x)   = Var -> ModuleMember
P.VarMember forall a b. (a -> b) -> a -> b
$ Var -> Var
var Var
x
moduleMember (H.VarOpMember VarOp
x) = VarOp -> ModuleMember
P.VarOpMember forall a b. (a -> b) -> a -> b
$ VarOp -> VarOp
varOp VarOp
x
moduleMember (H.DataMember TypeVar
x)  = TypeVar -> ModuleMember
P.DataMember forall a b. (a -> b) -> a -> b
$ TypeVar -> TypeVar
typeVar TypeVar
x

internalDef :: H.InternalDef -> [P.InternalDef]
internalDef :: InternalDef -> [InternalDef]
internalDef (H.TypeDef' TypeDef
x)           = [TypeDef -> InternalDef
P.TypeDef' forall a b. (a -> b) -> a -> b
$ TypeDef -> TypeDef
typeDef TypeDef
x]
internalDef (H.NewTypeDef' NewTypeDef
x)        =
  (\(NewTypeDef
y, [DerivingDef]
z) -> NewTypeDef -> InternalDef
P.NewTypeDef' NewTypeDef
y forall a. a -> [a] -> [a]
: (DerivingDef -> InternalDef
P.DerivingDef' forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [DerivingDef]
z)) forall a b. (a -> b) -> a -> b
$ NewTypeDef -> (NewTypeDef, [DerivingDef])
newtypeDef NewTypeDef
x
internalDef (H.DataDef' DataDef
x)           =
  (\(DataDef
y, [DerivingDef]
z) -> DataDef -> InternalDef
P.DataDef' DataDef
y forall a. a -> [a] -> [a]
: (DerivingDef -> InternalDef
P.DerivingDef' forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [DerivingDef]
z)) forall a b. (a -> b) -> a -> b
$ DataDef -> (DataDef, [DerivingDef])
dataDef DataDef
x
internalDef (H.FnDefOrSig' FnDefOrSig
x)        = [FnDefOrSig -> InternalDef
P.FnDefOrSig' forall a b. (a -> b) -> a -> b
$ FnDefOrSig -> FnDefOrSig
fnDefOrSig FnDefOrSig
x]
internalDef (H.ClassDef' ClassDef
x)          = [ClassDef -> InternalDef
P.ClassDef' forall a b. (a -> b) -> a -> b
$ ClassDef -> ClassDef
classDef ClassDef
x]
internalDef (H.InstanceDef' InstanceDef
x)       = [InstanceDef -> InternalDef
P.InstanceDef' forall a b. (a -> b) -> a -> b
$ InstanceDef -> InstanceDef
instanceDef InstanceDef
x]
internalDef (H.DerivingDef' DerivingDef
x)       = [DerivingDef -> InternalDef
P.DerivingDef' forall a b. (a -> b) -> a -> b
$ DerivingDef -> DerivingDef
derivingDef DerivingDef
x]
internalDef (H.InfixFnAnnotation' InfixFnAnnotation
x) = [InfixFnDef -> InternalDef
P.InfixFnDef' forall a b. (a -> b) -> a -> b
$ InfixFnAnnotation -> InfixFnDef
infixFnAnnotation InfixFnAnnotation
x]