{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE RecordWildCards #-}
module FFICXX.Generate.Code.HsTemplate where
import qualified Data.List as L (foldr1)
import FFICXX.Generate.Code.Cpp
( genTLTmplFunCpp,
genTmplClassCpp,
genTmplFunCpp,
genTmplVarCpp,
)
import FFICXX.Generate.Code.HsCast (castBody)
import FFICXX.Generate.Code.Primitive
( convertCpp2HS,
convertCpp2HS4Tmpl,
functionSignatureT,
functionSignatureTMF,
functionSignatureTT,
tmplAccessorToTFun,
)
import FFICXX.Generate.Dependency (calculateDependency)
import FFICXX.Generate.Name
( ffiTmplFuncName,
hsTemplateClassName,
hsTemplateMemberFunctionName,
hsTemplateMemberFunctionNameTH,
hsTmplFuncName,
hsTmplFuncNameTH,
subModuleName,
tmplAccessorName,
typeclassNameT,
)
import FFICXX.Generate.Type.Class
( Accessor (Getter, Setter),
Arg (..),
Class (..),
TLTemplate (..),
TemplateClass (..),
TemplateFunction (..),
TemplateMemberFunction (..),
Types (Void),
Variable (..),
)
import FFICXX.Generate.Type.Module
( ClassImportHeader (..),
TemplateClassImportHeader (..),
TemplateClassSubmoduleType (..),
TopLevelImportHeader (..),
)
import FFICXX.Generate.Util (firstUpper)
import FFICXX.Generate.Util.HaskellSrcExts
( bracketExp,
clsDecl,
con,
conDecl,
cxEmpty,
generator,
inapp,
insDecl,
insType,
match,
mkBind1,
mkClass,
mkData,
mkFun,
mkFunSig,
mkImport,
mkInstance,
mkNewtype,
mkPVar,
mkTBind,
mkTVar,
mkVar,
op,
parenSplice,
pbind_,
qualConDecl,
qualifier,
tyPtr,
tySplice,
tyapp,
tycon,
tyfun,
tylist,
typeBracket,
)
import FFICXX.Runtime.CodeGen.Cxx (HeaderName (..))
import qualified FFICXX.Runtime.CodeGen.Cxx as R
import FFICXX.Runtime.TH (IsCPrimitive (CPrim, NonCPrim))
import Language.Haskell.Exts.Build
( app,
binds,
caseE,
doE,
lamE,
letE,
letStmt,
listE,
name,
pApp,
pTuple,
paren,
qualStmt,
strE,
tuple,
wildcard,
)
import Language.Haskell.Exts.Syntax (Boxed (Boxed), Decl (..), ImportDecl (..), Type (TyTuple))
genTemplateMemberFunctions :: ClassImportHeader -> [Decl ()]
genTemplateMemberFunctions :: ClassImportHeader -> [Decl ()]
genTemplateMemberFunctions ClassImportHeader
cih =
let c :: Class
c = ClassImportHeader -> Class
cihClass ClassImportHeader
cih
in forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\TemplateMemberFunction
f -> Class -> TemplateMemberFunction -> [Decl ()]
genTMFExp Class
c TemplateMemberFunction
f forall a. Semigroup a => a -> a -> a
<> ClassImportHeader -> TemplateMemberFunction -> [Decl ()]
genTMFInstance ClassImportHeader
cih TemplateMemberFunction
f) (Class -> [TemplateMemberFunction]
class_tmpl_funcs Class
c)
genTMFExp :: Class -> TemplateMemberFunction -> [Decl ()]
genTMFExp :: Class -> TemplateMemberFunction -> [Decl ()]
genTMFExp Class
c TemplateMemberFunction
f = String
-> Type () -> [Pat ()] -> Exp () -> Maybe (Binds ()) -> [Decl ()]
mkFun String
nh Type ()
sig ([Pat ()]
tvars_p forall a. [a] -> [a] -> [a]
++ [String -> Pat ()
p String
"suffix"]) Exp ()
rhs (forall a. a -> Maybe a
Just Binds ()
bstmts)
where
nh :: String
nh = Class -> TemplateMemberFunction -> String
hsTemplateMemberFunctionNameTH Class
c TemplateMemberFunction
f
v :: String -> Exp ()
v = String -> Exp ()
mkVar
p :: String -> Pat ()
p = String -> Pat ()
mkPVar
itps :: [(Int, String)]
itps = forall a b. [a] -> [b] -> [(a, b)]
zip ([Int
1 ..] :: [Int]) (TemplateMemberFunction -> [String]
tmf_params TemplateMemberFunction
f)
tvars :: [String]
tvars = forall a b. (a -> b) -> [a] -> [b]
map (\(Int
i, String
_) -> String
"typ" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
i) [(Int, String)]
itps
nparams :: Int
nparams = forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Int, String)]
itps
tparams :: Type ()
tparams = if Int
nparams forall a. Eq a => a -> a -> Bool
== Int
1 then String -> Type ()
tycon String
"Type" else forall l. l -> Boxed -> [Type l] -> Type l
TyTuple () Boxed
Boxed (forall a. Int -> a -> [a]
replicate Int
nparams (String -> Type ()
tycon String
"Type"))
sig :: Type ()
sig = forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 Type () -> Type () -> Type ()
tyfun [Type ()
tparams, String -> Type ()
tycon String
"String", Type () -> Type () -> Type ()
tyapp (String -> Type ()
tycon String
"Q") (String -> Type ()
tycon String
"Exp")]
tvars_p :: [Pat ()]
tvars_p = if Int
nparams forall a. Eq a => a -> a -> Bool
== Int
1 then forall a b. (a -> b) -> [a] -> [b]
map String -> Pat ()
p [String]
tvars else [[Pat ()] -> Pat ()
pTuple (forall a b. (a -> b) -> [a] -> [b]
map String -> Pat ()
p [String]
tvars)]
lit' :: Exp ()
lit' = String -> Exp ()
strE (Class -> TemplateMemberFunction -> String
hsTemplateMemberFunctionName Class
c TemplateMemberFunction
f forall a. Semigroup a => a -> a -> a
<> String
"_")
lam :: Exp ()
lam = [Pat ()] -> Exp () -> Exp ()
lamE [String -> Pat ()
p String
"n"] (Exp ()
lit' Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v String
"<>" Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v String
"n")
rhs :: Exp ()
rhs =
Exp () -> Exp () -> Exp ()
app (String -> Exp ()
v String
"mkTFunc") forall a b. (a -> b) -> a -> b
$
let typs :: [Exp ()]
typs = if Int
nparams forall a. Eq a => a -> a -> Bool
== Int
1 then forall a b. (a -> b) -> [a] -> [b]
map String -> Exp ()
v [String]
tvars else [[Exp ()] -> Exp ()
tuple (forall a b. (a -> b) -> [a] -> [b]
map String -> Exp ()
v [String]
tvars)]
in [Exp ()] -> Exp ()
tuple ([Exp ()]
typs forall a. [a] -> [a] -> [a]
++ [String -> Exp ()
v String
"suffix", Exp ()
lam, String -> Exp ()
v String
"tyf"])
sig' :: Type ()
sig' = Class -> TemplateMemberFunction -> Type ()
functionSignatureTMF Class
c TemplateMemberFunction
f
tassgns :: [Decl ()]
tassgns = forall a b. (a -> b) -> [a] -> [b]
map (\(Int
i, String
tp) -> Pat () -> Exp () -> Decl ()
pbind_ (String -> Pat ()
p String
tp) (String -> Exp ()
v String
"pure" Exp () -> Exp () -> Exp ()
`app` (String -> Exp ()
v (String
"typ" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
i)))) [(Int, String)]
itps
bstmts :: Binds ()
bstmts =
[Decl ()] -> Binds ()
binds
[ String -> [Pat ()] -> Exp () -> Maybe (Binds ()) -> Decl ()
mkBind1
String
"tyf"
[String -> Pat ()
mkPVar String
"n"]
( [Decl ()] -> Exp () -> Exp ()
letE
[Decl ()]
tassgns
(Bracket () -> Exp ()
bracketExp (Type () -> Bracket ()
typeBracket Type ()
sig'))
)
forall a. Maybe a
Nothing
]
genTMFInstance :: ClassImportHeader -> TemplateMemberFunction -> [Decl ()]
genTMFInstance :: ClassImportHeader -> TemplateMemberFunction -> [Decl ()]
genTMFInstance ClassImportHeader
cih TemplateMemberFunction
f =
String
-> Type () -> [Pat ()] -> Exp () -> Maybe (Binds ()) -> [Decl ()]
mkFun
String
fname
Type ()
sig
[String -> Pat ()
p String
"isCprim", [Pat ()] -> Pat ()
pTuple [String -> Pat ()
p String
"qtyp", String -> Pat ()
p String
"param"]]
Exp ()
rhs
forall a. Maybe a
Nothing
where
c :: Class
c = ClassImportHeader -> Class
cihClass ClassImportHeader
cih
fname :: String
fname = String
"genInstanceFor_" forall a. Semigroup a => a -> a -> a
<> Class -> TemplateMemberFunction -> String
hsTemplateMemberFunctionName Class
c TemplateMemberFunction
f
p :: String -> Pat ()
p = String -> Pat ()
mkPVar
v :: String -> Exp ()
v = String -> Exp ()
mkVar
sig :: Type ()
sig =
String -> Type ()
tycon String
"IsCPrimitive"
Type () -> Type () -> Type ()
`tyfun` forall l. l -> Boxed -> [Type l] -> Type l
TyTuple () Boxed
Boxed [String -> Type ()
tycon String
"Q" Type () -> Type () -> Type ()
`tyapp` String -> Type ()
tycon String
"Type", String -> Type ()
tycon String
"TemplateParamInfo"]
Type () -> Type () -> Type ()
`tyfun` (String -> Type ()
tycon String
"Q" Type () -> Type () -> Type ()
`tyapp` Type () -> Type ()
tylist (String -> Type ()
tycon String
"Dec"))
rhs :: Exp ()
rhs = [Stmt ()] -> Exp ()
doE [Stmt ()
suffixstmt, Stmt ()
qtypstmt, Stmt ()
genstmt, Stmt ()
foreignSrcStmt, [Decl ()] -> Stmt ()
letStmt [Decl ()]
lststmt, Exp () -> Stmt ()
qualStmt Exp ()
retstmt]
suffixstmt :: Stmt ()
suffixstmt = [Decl ()] -> Stmt ()
letStmt [Pat () -> Exp () -> Decl ()
pbind_ (String -> Pat ()
p String
"suffix") (String -> Exp ()
v String
"tpinfoSuffix" Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v String
"param")]
qtypstmt :: Stmt ()
qtypstmt = Pat () -> Exp () -> Stmt ()
generator (String -> Pat ()
p String
"typ") (String -> Exp ()
v String
"qtyp")
genstmt :: Stmt ()
genstmt =
Pat () -> Exp () -> Stmt ()
generator
(String -> Pat ()
p String
"f1")
( String -> Exp ()
v String
"mkMember"
Exp () -> Exp () -> Exp ()
`app` ( String -> Exp ()
strE (Class -> TemplateMemberFunction -> String
hsTemplateMemberFunctionName Class
c TemplateMemberFunction
f forall a. Semigroup a => a -> a -> a
<> String
"_")
Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v String
"<>"
Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v String
"suffix"
)
Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v (Class -> TemplateMemberFunction -> String
hsTemplateMemberFunctionNameTH Class
c TemplateMemberFunction
f)
Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v String
"typ"
Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v String
"suffix"
)
lststmt :: [Decl ()]
lststmt = [Pat () -> Exp () -> Decl ()
pbind_ (String -> Pat ()
p String
"lst") ([Exp ()] -> Exp ()
listE ([String -> Exp ()
v String
"f1"]))]
retstmt :: Exp ()
retstmt = String -> Exp ()
v String
"pure" Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v String
"lst"
foreignSrcStmt :: Stmt ()
foreignSrcStmt =
Exp () -> Stmt ()
qualifier forall a b. (a -> b) -> a -> b
$
(String -> Exp ()
v String
"addModFinalizer")
Exp () -> Exp () -> Exp ()
`app` ( String -> Exp ()
v String
"addForeignSource"
Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
con String
"LangCxx"
Exp () -> Exp () -> Exp ()
`app` ( forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
L.foldr1
(\Exp ()
x Exp ()
y -> Exp () -> QOp () -> Exp () -> Exp ()
inapp Exp ()
x (String -> QOp ()
op String
"++") Exp ()
y)
[ Exp ()
includeStatic,
Exp ()
includeDynamic,
Exp ()
namespaceStr,
String -> Exp ()
strE (Class -> TemplateMemberFunction -> String
hsTemplateMemberFunctionName Class
c TemplateMemberFunction
f),
String -> Exp ()
strE String
"(",
String -> Exp ()
v String
"suffix",
String -> Exp ()
strE String
")\n"
]
)
)
where
includeStatic :: Exp ()
includeStatic =
String -> Exp ()
strE forall a b. (a -> b) -> a -> b
$
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((forall a. Semigroup a => a -> a -> a
<> String
"\n") forall b c a. (b -> c) -> (a -> b) -> a -> c
. CMacro Identity -> String
R.renderCMacro forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *). HeaderName -> CMacro f
R.Include) forall a b. (a -> b) -> a -> b
$
[String -> HeaderName
HdrName String
"MacroPatternMatch.h", ClassImportHeader -> HeaderName
cihSelfHeader ClassImportHeader
cih]
forall a. Semigroup a => a -> a -> a
<> ClassImportHeader -> [HeaderName]
cihIncludedHPkgHeadersInCPP ClassImportHeader
cih
forall a. Semigroup a => a -> a -> a
<> ClassImportHeader -> [HeaderName]
cihIncludedCPkgHeaders ClassImportHeader
cih
includeDynamic :: Exp ()
includeDynamic =
[Decl ()] -> Exp () -> Exp ()
letE
[ Pat () -> Exp () -> Decl ()
pbind_ (String -> Pat ()
p String
"headers") (String -> Exp ()
v String
"tpinfoCxxHeaders" Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v String
"param"),
Pat () -> Exp () -> Decl ()
pbind_
(Name () -> [Pat ()] -> Pat ()
pApp (String -> Name ()
name String
"f") [String -> Pat ()
p String
"x"])
(String -> Exp ()
v String
"renderCMacro" Exp () -> Exp () -> Exp ()
`app` (String -> Exp ()
con String
"Include" Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v String
"x"))
]
(String -> Exp ()
v String
"concatMap" Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v String
"f" Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v String
"headers")
namespaceStr :: Exp ()
namespaceStr =
[Decl ()] -> Exp () -> Exp ()
letE
[ Pat () -> Exp () -> Decl ()
pbind_ (String -> Pat ()
p String
"nss") (String -> Exp ()
v String
"tpinfoCxxNamespaces" Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v String
"param"),
Pat () -> Exp () -> Decl ()
pbind_
(Name () -> [Pat ()] -> Pat ()
pApp (String -> Name ()
name String
"f") [String -> Pat ()
p String
"x"])
(String -> Exp ()
v String
"renderCStmt" Exp () -> Exp () -> Exp ()
`app` (String -> Exp ()
con String
"UsingNamespace" Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v String
"x"))
]
(String -> Exp ()
v String
"concatMap" Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v String
"f" Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v String
"nss")
genImportInTemplate :: TemplateClass -> [ImportDecl ()]
genImportInTemplate :: TemplateClass -> [ImportDecl ()]
genImportInTemplate TemplateClass
t0 =
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (String -> ImportDecl ()
mkImport forall b c a. (b -> c) -> (a -> b) -> a -> c
. Either
(TemplateClassSubmoduleType, TemplateClass)
(ClassSubmoduleType, Class)
-> String
subModuleName) forall a b. (a -> b) -> a -> b
$ Either
(TemplateClassSubmoduleType, TemplateClass)
(ClassSubmoduleType, Class)
-> [Either
(TemplateClassSubmoduleType, TemplateClass)
(ClassSubmoduleType, Class)]
calculateDependency forall a b. (a -> b) -> a -> b
$ forall a b. a -> Either a b
Left (TemplateClassSubmoduleType
TCSTTemplate, TemplateClass
t0)
genTmplInterface :: TemplateClass -> [Decl ()]
genTmplInterface :: TemplateClass -> [Decl ()]
genTmplInterface TemplateClass
t =
[ String
-> [TyVarBind ()]
-> [QualConDecl ()]
-> Maybe (Deriving ())
-> Decl ()
mkData String
rname (forall a b. (a -> b) -> [a] -> [b]
map String -> TyVarBind ()
mkTBind [String]
tps) [] forall a. Maybe a
Nothing,
String
-> [TyVarBind ()]
-> [QualConDecl ()]
-> Maybe (Deriving ())
-> Decl ()
mkNewtype
String
hname
(forall a b. (a -> b) -> [a] -> [b]
map String -> TyVarBind ()
mkTBind [String]
tps)
[Maybe [TyVarBind ()]
-> Maybe (Context ()) -> ConDecl () -> QualConDecl ()
qualConDecl forall a. Maybe a
Nothing forall a. Maybe a
Nothing (String -> [Type ()] -> ConDecl ()
conDecl String
hname [Type () -> Type () -> Type ()
tyapp Type ()
tyPtr Type ()
rawtype])]
forall a. Maybe a
Nothing,
Context () -> String -> [TyVarBind ()] -> [ClassDecl ()] -> Decl ()
mkClass Context ()
cxEmpty (TemplateClass -> String
typeclassNameT TemplateClass
t) (forall a b. (a -> b) -> [a] -> [b]
map String -> TyVarBind ()
mkTBind [String]
tps) [ClassDecl ()]
methods,
Context () -> String -> [Type ()] -> [InstDecl ()] -> Decl ()
mkInstance Context ()
cxEmpty String
"FPtr" [Type ()
hightype] [InstDecl ()]
fptrbody,
Context () -> String -> [Type ()] -> [InstDecl ()] -> Decl ()
mkInstance Context ()
cxEmpty String
"Castable" [Type ()
hightype, Type () -> Type () -> Type ()
tyapp Type ()
tyPtr Type ()
rawtype] [InstDecl ()]
castBody
]
where
(String
hname, String
rname) = TemplateClass -> (String, String)
hsTemplateClassName TemplateClass
t
tps :: [String]
tps = TemplateClass -> [String]
tclass_params TemplateClass
t
fs :: [TemplateFunction]
fs = TemplateClass -> [TemplateFunction]
tclass_funcs TemplateClass
t
vfs :: [Variable]
vfs = TemplateClass -> [Variable]
tclass_vars TemplateClass
t
rawtype :: Type ()
rawtype = forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldl1 Type () -> Type () -> Type ()
tyapp (String -> Type ()
tycon String
rname forall a. a -> [a] -> [a]
: forall a b. (a -> b) -> [a] -> [b]
map String -> Type ()
mkTVar [String]
tps)
hightype :: Type ()
hightype = forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldl1 Type () -> Type () -> Type ()
tyapp (String -> Type ()
tycon String
hname forall a. a -> [a] -> [a]
: forall a b. (a -> b) -> [a] -> [b]
map String -> Type ()
mkTVar [String]
tps)
sigdecl :: TemplateFunction -> Decl ()
sigdecl TemplateFunction
f = String -> Type () -> Decl ()
mkFunSig (TemplateClass -> TemplateFunction -> String
hsTmplFuncName TemplateClass
t TemplateFunction
f) (TemplateClass -> TemplateFunction -> Type ()
functionSignatureT TemplateClass
t TemplateFunction
f)
sigdeclV :: Variable -> [Decl ()]
sigdeclV Variable
vf =
let f_g :: TemplateFunction
f_g = Variable -> Accessor -> TemplateFunction
tmplAccessorToTFun Variable
vf Accessor
Getter
f_s :: TemplateFunction
f_s = Variable -> Accessor -> TemplateFunction
tmplAccessorToTFun Variable
vf Accessor
Setter
in [TemplateFunction -> Decl ()
sigdecl TemplateFunction
f_g, TemplateFunction -> Decl ()
sigdecl TemplateFunction
f_s]
methods :: [ClassDecl ()]
methods = forall a b. (a -> b) -> [a] -> [b]
map (Decl () -> ClassDecl ()
clsDecl forall b c a. (b -> c) -> (a -> b) -> a -> c
. TemplateFunction -> Decl ()
sigdecl) [TemplateFunction]
fs forall a. [a] -> [a] -> [a]
++ (forall a b. (a -> b) -> [a] -> [b]
map Decl () -> ClassDecl ()
clsDecl forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Variable -> [Decl ()]
sigdeclV) [Variable]
vfs
fptrbody :: [InstDecl ()]
fptrbody =
[ Type () -> Type () -> InstDecl ()
insType (Type () -> Type () -> Type ()
tyapp (String -> Type ()
tycon String
"Raw") Type ()
hightype) Type ()
rawtype,
Decl () -> InstDecl ()
insDecl (String -> [Pat ()] -> Exp () -> Maybe (Binds ()) -> Decl ()
mkBind1 String
"get_fptr" [Name () -> [Pat ()] -> Pat ()
pApp (String -> Name ()
name String
hname) [String -> Pat ()
mkPVar String
"ptr"]] (String -> Exp ()
mkVar String
"ptr") forall a. Maybe a
Nothing),
Decl () -> InstDecl ()
insDecl (String -> [Pat ()] -> Exp () -> Maybe (Binds ()) -> Decl ()
mkBind1 String
"cast_fptr_to_obj" [] (String -> Exp ()
con String
hname) forall a. Maybe a
Nothing)
]
genImportInTH :: TemplateClass -> [ImportDecl ()]
genImportInTH :: TemplateClass -> [ImportDecl ()]
genImportInTH TemplateClass
t0 =
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (String -> ImportDecl ()
mkImport forall b c a. (b -> c) -> (a -> b) -> a -> c
. Either
(TemplateClassSubmoduleType, TemplateClass)
(ClassSubmoduleType, Class)
-> String
subModuleName) forall a b. (a -> b) -> a -> b
$ Either
(TemplateClassSubmoduleType, TemplateClass)
(ClassSubmoduleType, Class)
-> [Either
(TemplateClassSubmoduleType, TemplateClass)
(ClassSubmoduleType, Class)]
calculateDependency forall a b. (a -> b) -> a -> b
$ forall a b. a -> Either a b
Left (TemplateClassSubmoduleType
TCSTTH, TemplateClass
t0)
genTmplImplementation :: TemplateClass -> [Decl ()]
genTmplImplementation :: TemplateClass -> [Decl ()]
genTmplImplementation TemplateClass
t =
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap TemplateFunction -> [Decl ()]
gen (TemplateClass -> [TemplateFunction]
tclass_funcs TemplateClass
t) forall a. [a] -> [a] -> [a]
++ forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Variable -> [Decl ()]
genV (TemplateClass -> [Variable]
tclass_vars TemplateClass
t)
where
v :: String -> Exp ()
v = String -> Exp ()
mkVar
p :: String -> Pat ()
p = String -> Pat ()
mkPVar
itps :: [(Int, String)]
itps = forall a b. [a] -> [b] -> [(a, b)]
zip ([Int
1 ..] :: [Int]) (TemplateClass -> [String]
tclass_params TemplateClass
t)
tvars :: [String]
tvars = forall a b. (a -> b) -> [a] -> [b]
map (\(Int
i, String
_) -> String
"typ" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
i) [(Int, String)]
itps
nparams :: Int
nparams = forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Int, String)]
itps
tparams :: Type ()
tparams = if Int
nparams forall a. Eq a => a -> a -> Bool
== Int
1 then String -> Type ()
tycon String
"Type" else forall l. l -> Boxed -> [Type l] -> Type l
TyTuple () Boxed
Boxed (forall a. Int -> a -> [a]
replicate Int
nparams (String -> Type ()
tycon String
"Type"))
sig :: Type ()
sig = forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 Type () -> Type () -> Type ()
tyfun [Type ()
tparams, String -> Type ()
tycon String
"String", Type () -> Type () -> Type ()
tyapp (String -> Type ()
tycon String
"Q") (String -> Type ()
tycon String
"Exp")]
tvars_p :: [Pat ()]
tvars_p = if Int
nparams forall a. Eq a => a -> a -> Bool
== Int
1 then forall a b. (a -> b) -> [a] -> [b]
map String -> Pat ()
p [String]
tvars else [[Pat ()] -> Pat ()
pTuple (forall a b. (a -> b) -> [a] -> [b]
map String -> Pat ()
p [String]
tvars)]
prefix :: String
prefix = TemplateClass -> String
tclass_name TemplateClass
t
gen :: TemplateFunction -> [Decl ()]
gen TemplateFunction
f = String
-> Type () -> [Pat ()] -> Exp () -> Maybe (Binds ()) -> [Decl ()]
mkFun String
nh Type ()
sig ([Pat ()]
tvars_p forall a. [a] -> [a] -> [a]
++ [String -> Pat ()
p String
"suffix"]) Exp ()
rhs (forall a. a -> Maybe a
Just Binds ()
bstmts)
where
nh :: String
nh = TemplateClass -> TemplateFunction -> String
hsTmplFuncNameTH TemplateClass
t TemplateFunction
f
nc :: String
nc = TemplateFunction -> String
ffiTmplFuncName TemplateFunction
f
lit' :: Exp ()
lit' = String -> Exp ()
strE (String
prefix forall a. Semigroup a => a -> a -> a
<> String
"_" forall a. Semigroup a => a -> a -> a
<> String
nc)
lam :: Exp ()
lam = [Pat ()] -> Exp () -> Exp ()
lamE [String -> Pat ()
p String
"n"] (Exp ()
lit' Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v String
"<>" Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v String
"n")
rhs :: Exp ()
rhs =
Exp () -> Exp () -> Exp ()
app (String -> Exp ()
v String
"mkTFunc") forall a b. (a -> b) -> a -> b
$
let typs :: [Exp ()]
typs = if Int
nparams forall a. Eq a => a -> a -> Bool
== Int
1 then forall a b. (a -> b) -> [a] -> [b]
map String -> Exp ()
v [String]
tvars else [[Exp ()] -> Exp ()
tuple (forall a b. (a -> b) -> [a] -> [b]
map String -> Exp ()
v [String]
tvars)]
in [Exp ()] -> Exp ()
tuple ([Exp ()]
typs forall a. [a] -> [a] -> [a]
++ [String -> Exp ()
v String
"suffix", Exp ()
lam, String -> Exp ()
v String
"tyf"])
sig' :: Type ()
sig' = TemplateClass -> TemplateFunction -> Type ()
functionSignatureTT TemplateClass
t TemplateFunction
f
tassgns :: [Decl ()]
tassgns = forall a b. (a -> b) -> [a] -> [b]
map (\(Int
i, String
tp) -> Pat () -> Exp () -> Decl ()
pbind_ (String -> Pat ()
p String
tp) (String -> Exp ()
v String
"pure" Exp () -> Exp () -> Exp ()
`app` (String -> Exp ()
v (String
"typ" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
i)))) [(Int, String)]
itps
bstmts :: Binds ()
bstmts =
[Decl ()] -> Binds ()
binds
[ String -> [Pat ()] -> Exp () -> Maybe (Binds ()) -> Decl ()
mkBind1
String
"tyf"
[Pat ()
wildcard]
( [Decl ()] -> Exp () -> Exp ()
letE
[Decl ()]
tassgns
(Bracket () -> Exp ()
bracketExp (Type () -> Bracket ()
typeBracket Type ()
sig'))
)
forall a. Maybe a
Nothing
]
genV :: Variable -> [Decl ()]
genV Variable
vf =
let f_g :: TemplateFunction
f_g = Variable -> Accessor -> TemplateFunction
tmplAccessorToTFun Variable
vf Accessor
Getter
f_s :: TemplateFunction
f_s = Variable -> Accessor -> TemplateFunction
tmplAccessorToTFun Variable
vf Accessor
Setter
in TemplateFunction -> [Decl ()]
gen TemplateFunction
f_g forall a. [a] -> [a] -> [a]
++ TemplateFunction -> [Decl ()]
gen TemplateFunction
f_s
genTmplInstance ::
TemplateClassImportHeader ->
[Decl ()]
genTmplInstance :: TemplateClassImportHeader -> [Decl ()]
genTmplInstance TemplateClassImportHeader
tcih =
String
-> Type () -> [Pat ()] -> Exp () -> Maybe (Binds ()) -> [Decl ()]
mkFun
String
fname
Type ()
sig
(String -> Pat ()
p String
"isCprim" forall a. a -> [a] -> [a]
: forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\String
x String
y -> [Pat ()] -> Pat ()
pTuple [String -> Pat ()
p String
x, String -> Pat ()
p String
y]) [String]
qtvars [String]
pvars)
Exp ()
rhs
forall a. Maybe a
Nothing
where
t :: TemplateClass
t = TemplateClassImportHeader -> TemplateClass
tcihTClass TemplateClassImportHeader
tcih
fs :: [TemplateFunction]
fs = TemplateClass -> [TemplateFunction]
tclass_funcs TemplateClass
t
vfs :: [Variable]
vfs = TemplateClass -> [Variable]
tclass_vars TemplateClass
t
tname :: String
tname = TemplateClass -> String
tclass_name TemplateClass
t
fname :: String
fname = String
"gen" forall a. Semigroup a => a -> a -> a
<> String
tname forall a. Semigroup a => a -> a -> a
<> String
"InstanceFor"
p :: String -> Pat ()
p = String -> Pat ()
mkPVar
v :: String -> Exp ()
v = String -> Exp ()
mkVar
itps :: [(Int, String)]
itps = forall a b. [a] -> [b] -> [(a, b)]
zip ([Int
1 ..] :: [Int]) (TemplateClass -> [String]
tclass_params TemplateClass
t)
tvars :: [String]
tvars = forall a b. (a -> b) -> [a] -> [b]
map (\(Int
i, String
_) -> String
"typ" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
i) [(Int, String)]
itps
qtvars :: [String]
qtvars = forall a b. (a -> b) -> [a] -> [b]
map (\(Int
i, String
_) -> String
"qtyp" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
i) [(Int, String)]
itps
pvars :: [String]
pvars = forall a b. (a -> b) -> [a] -> [b]
map (\(Int
i, String
_) -> String
"param" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
i) [(Int, String)]
itps
nparams :: Int
nparams = forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Int, String)]
itps
typs_v :: Exp ()
typs_v = if Int
nparams forall a. Eq a => a -> a -> Bool
== Int
1 then String -> Exp ()
v ([String]
tvars forall a. [a] -> Int -> a
!! Int
0) else [Exp ()] -> Exp ()
tuple (forall a b. (a -> b) -> [a] -> [b]
map String -> Exp ()
v [String]
tvars)
params_l :: Exp ()
params_l = [Exp ()] -> Exp ()
listE (forall a b. (a -> b) -> [a] -> [b]
map String -> Exp ()
v [String]
pvars)
sig :: Type ()
sig =
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 Type () -> Type () -> Type ()
tyfun forall a b. (a -> b) -> a -> b
$
[String -> Type ()
tycon String
"IsCPrimitive"]
forall a. [a] -> [a] -> [a]
++ forall a. Int -> a -> [a]
replicate
Int
nparams
(forall l. l -> Boxed -> [Type l] -> Type l
TyTuple () Boxed
Boxed [String -> Type ()
tycon String
"Q" Type () -> Type () -> Type ()
`tyapp` String -> Type ()
tycon String
"Type", String -> Type ()
tycon String
"TemplateParamInfo"])
forall a. [a] -> [a] -> [a]
++ [String -> Type ()
tycon String
"Q" Type () -> Type () -> Type ()
`tyapp` Type () -> Type ()
tylist (String -> Type ()
tycon String
"Dec")]
nfs :: [(Int, TemplateFunction)]
nfs = forall a b. [a] -> [b] -> [(a, b)]
zip ([Int
1 ..] :: [Int]) [TemplateFunction]
fs
nvfs :: [(Int, Variable)]
nvfs = forall a b. [a] -> [b] -> [(a, b)]
zip ([Int
1 ..] :: [Int]) [Variable]
vfs
rhs :: Exp ()
rhs =
[Stmt ()] -> Exp ()
doE
( [Stmt ()
paramsstmt, Stmt ()
suffixstmt]
forall a. Semigroup a => a -> a -> a
<> [ Pat () -> Exp () -> Stmt ()
generator (String -> Pat ()
p String
"callmod_") (String -> Exp ()
v String
"fmap" Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v String
"loc_module" Exp () -> Exp () -> Exp ()
`app` (String -> Exp ()
v String
"location")),
[Decl ()] -> Stmt ()
letStmt
[ Pat () -> Exp () -> Decl ()
pbind_
(String -> Pat ()
p String
"callmod")
(String -> Exp ()
v String
"dot2_" Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v String
"callmod_")
]
]
forall a. Semigroup a => a -> a -> a
<> forall a b. (a -> b) -> [a] -> [b]
map (String, String) -> Stmt ()
genqtypstmt (forall a b. [a] -> [b] -> [(a, b)]
zip [String]
tvars [String]
qtvars)
forall a. Semigroup a => a -> a -> a
<> forall a b. (a -> b) -> [a] -> [b]
map forall {a}. Show a => (a, TemplateFunction) -> Stmt ()
genstmt [(Int, TemplateFunction)]
nfs
forall a. Semigroup a => a -> a -> a
<> forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap forall {a}. (Show a, Num a) => (a, Variable) -> [Stmt ()]
genvarstmt [(Int, Variable)]
nvfs
forall a. Semigroup a => a -> a -> a
<> [Stmt ()
foreignSrcStmt, [Decl ()] -> Stmt ()
letStmt [Decl ()]
lststmt, Exp () -> Stmt ()
qualStmt Exp ()
retstmt]
)
paramsstmt :: Stmt ()
paramsstmt =
[Decl ()] -> Stmt ()
letStmt
[ Pat () -> Exp () -> Decl ()
pbind_
(String -> Pat ()
p String
"params")
(String -> Exp ()
v String
"map" Exp () -> Exp () -> Exp ()
`app` (String -> Exp ()
v String
"tpinfoSuffix") Exp () -> Exp () -> Exp ()
`app` Exp ()
params_l)
]
suffixstmt :: Stmt ()
suffixstmt =
[Decl ()] -> Stmt ()
letStmt
[ Pat () -> Exp () -> Decl ()
pbind_
(String -> Pat ()
p String
"suffix")
( String -> Exp ()
v String
"concatMap"
Exp () -> Exp () -> Exp ()
`app` ([Pat ()] -> Exp () -> Exp ()
lamE [String -> Pat ()
p String
"x"] (Exp () -> QOp () -> Exp () -> Exp ()
inapp (String -> Exp ()
strE String
"_") (String -> QOp ()
op String
"++") (String -> Exp ()
v String
"tpinfoSuffix" Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v String
"x")))
Exp () -> Exp () -> Exp ()
`app` Exp ()
params_l
)
]
genqtypstmt :: (String, String) -> Stmt ()
genqtypstmt (String
tvar, String
qtvar) = Pat () -> Exp () -> Stmt ()
generator (String -> Pat ()
p String
tvar) (String -> Exp ()
v String
qtvar)
gen :: String -> String -> TemplateFunction -> a -> Stmt ()
gen String
prefix String
nm TemplateFunction
f a
n =
Pat () -> Exp () -> Stmt ()
generator
(String -> Pat ()
p (String
prefix forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show a
n))
( String -> Exp ()
v String
nm Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
strE (TemplateClass -> TemplateFunction -> String
hsTmplFuncName TemplateClass
t TemplateFunction
f)
Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v (TemplateClass -> TemplateFunction -> String
hsTmplFuncNameTH TemplateClass
t TemplateFunction
f)
Exp () -> Exp () -> Exp ()
`app` Exp ()
typs_v
Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v String
"suffix"
)
genstmt :: (a, TemplateFunction) -> Stmt ()
genstmt (a
n, f :: TemplateFunction
f@TFun {}) = forall {a}.
Show a =>
String -> String -> TemplateFunction -> a -> Stmt ()
gen String
"f" String
"mkMember" TemplateFunction
f a
n
genstmt (a
n, f :: TemplateFunction
f@TFunNew {}) = forall {a}.
Show a =>
String -> String -> TemplateFunction -> a -> Stmt ()
gen String
"f" String
"mkNew" TemplateFunction
f a
n
genstmt (a
n, f :: TemplateFunction
f@TemplateFunction
TFunDelete) = forall {a}.
Show a =>
String -> String -> TemplateFunction -> a -> Stmt ()
gen String
"f" String
"mkDelete" TemplateFunction
f a
n
genstmt (a
n, f :: TemplateFunction
f@TFunOp {}) = forall {a}.
Show a =>
String -> String -> TemplateFunction -> a -> Stmt ()
gen String
"f" String
"mkMember" TemplateFunction
f a
n
genvarstmt :: (a, Variable) -> [Stmt ()]
genvarstmt (a
n, Variable
vf) =
let Variable (Arg {String
Types
arg_name :: Arg -> String
arg_type :: Arg -> Types
arg_name :: String
arg_type :: Types
..}) = Variable
vf
f_g :: TemplateFunction
f_g =
TFun
{ tfun_ret :: Types
tfun_ret = Types
arg_type,
tfun_name :: String
tfun_name = Variable -> Accessor -> String
tmplAccessorName Variable
vf Accessor
Getter,
tfun_oname :: String
tfun_oname = Variable -> Accessor -> String
tmplAccessorName Variable
vf Accessor
Getter,
tfun_args :: [Arg]
tfun_args = []
}
f_s :: TemplateFunction
f_s =
TFun
{ tfun_ret :: Types
tfun_ret = Types
Void,
tfun_name :: String
tfun_name = Variable -> Accessor -> String
tmplAccessorName Variable
vf Accessor
Setter,
tfun_oname :: String
tfun_oname = Variable -> Accessor -> String
tmplAccessorName Variable
vf Accessor
Setter,
tfun_args :: [Arg]
tfun_args = [Types -> String -> Arg
Arg Types
arg_type String
"value"]
}
in [ forall {a}.
Show a =>
String -> String -> TemplateFunction -> a -> Stmt ()
gen String
"vf" String
"mkMember" TemplateFunction
f_g (a
2 forall a. Num a => a -> a -> a
* a
n forall a. Num a => a -> a -> a
- a
1),
forall {a}.
Show a =>
String -> String -> TemplateFunction -> a -> Stmt ()
gen String
"vf" String
"mkMember" TemplateFunction
f_s (a
2 forall a. Num a => a -> a -> a
* a
n)
]
lststmt :: [Decl ()]
lststmt =
let mkElems :: String -> [(a, b)] -> [Exp ()]
mkElems String
prefix [(a, b)]
xs = forall a b. (a -> b) -> [a] -> [b]
map (String -> Exp ()
v forall b c a. (b -> c) -> (a -> b) -> a -> c
. (\a
n -> String
prefix forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show a
n) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst) [(a, b)]
xs
in [ Pat () -> Exp () -> Decl ()
pbind_
(String -> Pat ()
p String
"lst")
( [Exp ()] -> Exp ()
listE
( forall {a} {b}. Show a => String -> [(a, b)] -> [Exp ()]
mkElems String
"f" [(Int, TemplateFunction)]
nfs
forall a. Semigroup a => a -> a -> a
<> forall {a} {b}. Show a => String -> [(a, b)] -> [Exp ()]
mkElems String
"vf" (forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\(Int
n, Variable
vf) -> [(Int
2 forall a. Num a => a -> a -> a
* Int
n forall a. Num a => a -> a -> a
- Int
1, Variable
vf), (Int
2 forall a. Num a => a -> a -> a
* Int
n, Variable
vf)]) [(Int, Variable)]
nvfs)
)
)
]
foreignSrcStmt :: Stmt ()
foreignSrcStmt =
Exp () -> Stmt ()
qualifier forall a b. (a -> b) -> a -> b
$
(String -> Exp ()
v String
"addModFinalizer")
Exp () -> Exp () -> Exp ()
`app` ( String -> Exp ()
v String
"addForeignSource"
Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
con String
"LangCxx"
Exp () -> Exp () -> Exp ()
`app` ( forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
L.foldr1
(\Exp ()
x Exp ()
y -> Exp () -> QOp () -> Exp () -> Exp ()
inapp Exp ()
x (String -> QOp ()
op String
"++") Exp ()
y)
[ Exp ()
includeStatic,
Exp ()
includeDynamic,
Exp ()
namespaceStr,
String -> Exp ()
strE (String
tname forall a. Semigroup a => a -> a -> a
<> String
"_instance"),
Exp () -> Exp ()
paren forall a b. (a -> b) -> a -> b
$
Exp () -> [Alt ()] -> Exp ()
caseE
(String -> Exp ()
v String
"isCprim")
[ Pat () -> Exp () -> Alt ()
match (String -> Pat ()
p String
"CPrim") (String -> Exp ()
strE String
"_s"),
Pat () -> Exp () -> Alt ()
match (String -> Pat ()
p String
"NonCPrim") (String -> Exp ()
strE String
"")
],
String -> Exp ()
strE String
"(",
String -> Exp ()
v String
"intercalate"
Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
strE String
", "
Exp () -> Exp () -> Exp ()
`app` Exp () -> Exp ()
paren (Exp () -> QOp () -> Exp () -> Exp ()
inapp (String -> Exp ()
v String
"callmod") (String -> QOp ()
op String
":") (String -> Exp ()
v String
"params")),
String -> Exp ()
strE String
")\n"
]
)
)
where
body :: [String]
body =
forall a b. (a -> b) -> [a] -> [b]
map CMacro Identity -> String
R.renderCMacro forall a b. (a -> b) -> a -> b
$
forall a b. (a -> b) -> [a] -> [b]
map forall (f :: * -> *). HeaderName -> CMacro f
R.Include (TemplateClassImportHeader -> [HeaderName]
tcihCxxHeaders TemplateClassImportHeader
tcih)
forall a. [a] -> [a] -> [a]
++ forall a b. (a -> b) -> [a] -> [b]
map (IsCPrimitive
-> TemplateClass -> TemplateFunction -> CMacro Identity
genTmplFunCpp IsCPrimitive
NonCPrim TemplateClass
t) [TemplateFunction]
fs
forall a. [a] -> [a] -> [a]
++ forall a b. (a -> b) -> [a] -> [b]
map (IsCPrimitive
-> TemplateClass -> TemplateFunction -> CMacro Identity
genTmplFunCpp IsCPrimitive
CPrim TemplateClass
t) [TemplateFunction]
fs
forall a. [a] -> [a] -> [a]
++ forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (IsCPrimitive -> TemplateClass -> Variable -> [CMacro Identity]
genTmplVarCpp IsCPrimitive
NonCPrim TemplateClass
t) [Variable]
vfs
forall a. [a] -> [a] -> [a]
++ forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (IsCPrimitive -> TemplateClass -> Variable -> [CMacro Identity]
genTmplVarCpp IsCPrimitive
CPrim TemplateClass
t) [Variable]
vfs
forall a. [a] -> [a] -> [a]
++ [ IsCPrimitive
-> TemplateClass
-> ([TemplateFunction], [Variable])
-> CMacro Identity
genTmplClassCpp IsCPrimitive
NonCPrim TemplateClass
t ([TemplateFunction]
fs, [Variable]
vfs),
IsCPrimitive
-> TemplateClass
-> ([TemplateFunction], [Variable])
-> CMacro Identity
genTmplClassCpp IsCPrimitive
CPrim TemplateClass
t ([TemplateFunction]
fs, [Variable]
vfs)
]
includeStatic :: Exp ()
includeStatic =
String -> Exp ()
strE forall a b. (a -> b) -> a -> b
$
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap
(forall a. Semigroup a => a -> a -> a
<> String
"\n")
( [CMacro Identity -> String
R.renderCMacro (forall (f :: * -> *). HeaderName -> CMacro f
R.Include (String -> HeaderName
HdrName String
"MacroPatternMatch.h"))]
forall a. [a] -> [a] -> [a]
++ [String]
body
)
cxxHeaders :: Exp ()
cxxHeaders = String -> Exp ()
v String
"concatMap" Exp () -> Exp () -> Exp ()
`app` (String -> Exp ()
v String
"tpinfoCxxHeaders") Exp () -> Exp () -> Exp ()
`app` Exp ()
params_l
cxxNamespaces :: Exp ()
cxxNamespaces = String -> Exp ()
v String
"concatMap" Exp () -> Exp () -> Exp ()
`app` (String -> Exp ()
v String
"tpinfoCxxNamespaces") Exp () -> Exp () -> Exp ()
`app` Exp ()
params_l
includeDynamic :: Exp ()
includeDynamic =
[Decl ()] -> Exp () -> Exp ()
letE
[ Pat () -> Exp () -> Decl ()
pbind_ (String -> Pat ()
p String
"headers") Exp ()
cxxHeaders,
Pat () -> Exp () -> Decl ()
pbind_
(Name () -> [Pat ()] -> Pat ()
pApp (String -> Name ()
name String
"f") [String -> Pat ()
p String
"x"])
(String -> Exp ()
v String
"renderCMacro" Exp () -> Exp () -> Exp ()
`app` (String -> Exp ()
con String
"Include" Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v String
"x"))
]
(String -> Exp ()
v String
"concatMap" Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v String
"f" Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v String
"headers")
namespaceStr :: Exp ()
namespaceStr =
[Decl ()] -> Exp () -> Exp ()
letE
[ Pat () -> Exp () -> Decl ()
pbind_ (String -> Pat ()
p String
"nss") Exp ()
cxxNamespaces,
Pat () -> Exp () -> Decl ()
pbind_
(Name () -> [Pat ()] -> Pat ()
pApp (String -> Name ()
name String
"f") [String -> Pat ()
p String
"x"])
(String -> Exp ()
v String
"renderCStmt" Exp () -> Exp () -> Exp ()
`app` (String -> Exp ()
con String
"UsingNamespace" Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v String
"x"))
]
(String -> Exp ()
v String
"concatMap" Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v String
"f" Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v String
"nss")
retstmt :: Exp ()
retstmt =
String -> Exp ()
v String
"pure"
Exp () -> Exp () -> Exp ()
`app` [Exp ()] -> Exp ()
listE
[ String -> Exp ()
v String
"mkInstance"
Exp () -> Exp () -> Exp ()
`app` [Exp ()] -> Exp ()
listE []
Exp () -> Exp () -> Exp ()
`app` forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldl1
(\Exp ()
f Exp ()
x -> String -> Exp ()
con String
"AppT" Exp () -> Exp () -> Exp ()
`app` Exp ()
f Exp () -> Exp () -> Exp ()
`app` Exp ()
x)
(String -> Exp ()
v String
"con" Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
strE (TemplateClass -> String
typeclassNameT TemplateClass
t) forall a. a -> [a] -> [a]
: forall a b. (a -> b) -> [a] -> [b]
map String -> Exp ()
v [String]
tvars)
Exp () -> Exp () -> Exp ()
`app` (String -> Exp ()
v String
"lst")
]
genTLTemplateInterface :: TLTemplate -> [Decl ()]
genTLTemplateInterface :: TLTemplate -> [Decl ()]
genTLTemplateInterface TLTemplate
t =
[ Context () -> String -> [TyVarBind ()] -> [ClassDecl ()] -> Decl ()
mkClass Context ()
cxEmpty (String -> String
firstUpper (TLTemplate -> String
topleveltfunc_name TLTemplate
t)) (forall a b. (a -> b) -> [a] -> [b]
map String -> TyVarBind ()
mkTBind [String]
tps) [ClassDecl ()]
methods
]
where
tps :: [String]
tps = TLTemplate -> [String]
topleveltfunc_params TLTemplate
t
ctyp :: Type ()
ctyp = Maybe Class -> Types -> Type ()
convertCpp2HS forall a. Maybe a
Nothing (TLTemplate -> Types
topleveltfunc_ret TLTemplate
t)
lst :: [Type ()]
lst = forall a b. (a -> b) -> [a] -> [b]
map (Maybe Class -> Types -> Type ()
convertCpp2HS forall a. Maybe a
Nothing forall b c a. (b -> c) -> (a -> b) -> a -> c
. Arg -> Types
arg_type) (TLTemplate -> [Arg]
topleveltfunc_args TLTemplate
t)
sigdecl :: Decl ()
sigdecl = String -> Type () -> Decl ()
mkFunSig (TLTemplate -> String
topleveltfunc_name TLTemplate
t) forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 Type () -> Type () -> Type ()
tyfun ([Type ()]
lst forall a. Semigroup a => a -> a -> a
<> [Type () -> Type () -> Type ()
tyapp (String -> Type ()
tycon String
"IO") Type ()
ctyp])
methods :: [ClassDecl ()]
methods = [Decl () -> ClassDecl ()
clsDecl Decl ()
sigdecl]
genTLTemplateImplementation :: TLTemplate -> [Decl ()]
genTLTemplateImplementation :: TLTemplate -> [Decl ()]
genTLTemplateImplementation TLTemplate
t =
String
-> Type () -> [Pat ()] -> Exp () -> Maybe (Binds ()) -> [Decl ()]
mkFun String
nh Type ()
sig ([Pat ()]
tvars_p forall a. [a] -> [a] -> [a]
++ [String -> Pat ()
p String
"suffix"]) Exp ()
rhs (forall a. a -> Maybe a
Just Binds ()
bstmts)
where
v :: String -> Exp ()
v = String -> Exp ()
mkVar
p :: String -> Pat ()
p = String -> Pat ()
mkPVar
itps :: [(Int, String)]
itps = forall a b. [a] -> [b] -> [(a, b)]
zip ([Int
1 ..] :: [Int]) (TLTemplate -> [String]
topleveltfunc_params TLTemplate
t)
tvars :: [String]
tvars = forall a b. (a -> b) -> [a] -> [b]
map (\(Int
i, String
_) -> String
"typ" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
i) [(Int, String)]
itps
nparams :: Int
nparams = forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Int, String)]
itps
tparams :: Type ()
tparams = if Int
nparams forall a. Eq a => a -> a -> Bool
== Int
1 then String -> Type ()
tycon String
"Type" else forall l. l -> Boxed -> [Type l] -> Type l
TyTuple () Boxed
Boxed (forall a. Int -> a -> [a]
replicate Int
nparams (String -> Type ()
tycon String
"Type"))
sig :: Type ()
sig = forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 Type () -> Type () -> Type ()
tyfun [Type ()
tparams, String -> Type ()
tycon String
"String", Type () -> Type () -> Type ()
tyapp (String -> Type ()
tycon String
"Q") (String -> Type ()
tycon String
"Exp")]
tvars_p :: [Pat ()]
tvars_p = if Int
nparams forall a. Eq a => a -> a -> Bool
== Int
1 then forall a b. (a -> b) -> [a] -> [b]
map String -> Pat ()
p [String]
tvars else [[Pat ()] -> Pat ()
pTuple (forall a b. (a -> b) -> [a] -> [b]
map String -> Pat ()
p [String]
tvars)]
prefix :: String
prefix = String
"TL"
nh :: String
nh = String
"t_" forall a. Semigroup a => a -> a -> a
<> TLTemplate -> String
topleveltfunc_name TLTemplate
t
nc :: String
nc = TLTemplate -> String
topleveltfunc_name TLTemplate
t
lit' :: Exp ()
lit' = String -> Exp ()
strE (String
prefix forall a. Semigroup a => a -> a -> a
<> String
"_" forall a. Semigroup a => a -> a -> a
<> String
nc)
lam :: Exp ()
lam = [Pat ()] -> Exp () -> Exp ()
lamE [String -> Pat ()
p String
"n"] (Exp ()
lit' Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v String
"<>" Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v String
"n")
rhs :: Exp ()
rhs =
Exp () -> Exp () -> Exp ()
app (String -> Exp ()
v String
"mkTFunc") forall a b. (a -> b) -> a -> b
$
let typs :: [Exp ()]
typs = if Int
nparams forall a. Eq a => a -> a -> Bool
== Int
1 then forall a b. (a -> b) -> [a] -> [b]
map String -> Exp ()
v [String]
tvars else [[Exp ()] -> Exp ()
tuple (forall a b. (a -> b) -> [a] -> [b]
map String -> Exp ()
v [String]
tvars)]
in [Exp ()] -> Exp ()
tuple ([Exp ()]
typs forall a. [a] -> [a] -> [a]
++ [String -> Exp ()
v String
"suffix", Exp ()
lam, String -> Exp ()
v String
"tyf"])
sig' :: Type ()
sig' =
let e :: a
e = forall a. HasCallStack => String -> a
error String
"genTLTemplateImplementation"
spls :: [Type ()]
spls = forall a b. (a -> b) -> [a] -> [b]
map (Splice () -> Type ()
tySplice forall b c a. (b -> c) -> (a -> b) -> a -> c
. Exp () -> Splice ()
parenSplice forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Exp ()
mkVar) forall a b. (a -> b) -> a -> b
$ TLTemplate -> [String]
topleveltfunc_params TLTemplate
t
ctyp :: Type ()
ctyp = Type () -> Maybe Class -> [Type ()] -> Types -> Type ()
convertCpp2HS4Tmpl forall {a}. a
e forall a. Maybe a
Nothing [Type ()]
spls (TLTemplate -> Types
topleveltfunc_ret TLTemplate
t)
lst :: [Type ()]
lst = forall a b. (a -> b) -> [a] -> [b]
map (Type () -> Maybe Class -> [Type ()] -> Types -> Type ()
convertCpp2HS4Tmpl forall {a}. a
e forall a. Maybe a
Nothing [Type ()]
spls forall b c a. (b -> c) -> (a -> b) -> a -> c
. Arg -> Types
arg_type) (TLTemplate -> [Arg]
topleveltfunc_args TLTemplate
t)
in forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 Type () -> Type () -> Type ()
tyfun ([Type ()]
lst forall a. Semigroup a => a -> a -> a
<> [Type () -> Type () -> Type ()
tyapp (String -> Type ()
tycon String
"IO") Type ()
ctyp])
tassgns :: [Decl ()]
tassgns = forall a b. (a -> b) -> [a] -> [b]
map (\(Int
i, String
tp) -> Pat () -> Exp () -> Decl ()
pbind_ (String -> Pat ()
p String
tp) (String -> Exp ()
v String
"pure" Exp () -> Exp () -> Exp ()
`app` (String -> Exp ()
v (String
"typ" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
i)))) [(Int, String)]
itps
bstmts :: Binds ()
bstmts =
[Decl ()] -> Binds ()
binds
[ String -> [Pat ()] -> Exp () -> Maybe (Binds ()) -> Decl ()
mkBind1
String
"tyf"
[Pat ()
wildcard]
( [Decl ()] -> Exp () -> Exp ()
letE
[Decl ()]
tassgns
(Bracket () -> Exp ()
bracketExp (Type () -> Bracket ()
typeBracket Type ()
sig'))
)
forall a. Maybe a
Nothing
]
genTLTemplateInstance ::
TopLevelImportHeader ->
TLTemplate ->
[Decl ()]
genTLTemplateInstance :: TopLevelImportHeader -> TLTemplate -> [Decl ()]
genTLTemplateInstance TopLevelImportHeader
tih TLTemplate
t =
String
-> Type () -> [Pat ()] -> Exp () -> Maybe (Binds ()) -> [Decl ()]
mkFun
String
fname
Type ()
sig
(String -> Pat ()
p String
"isCprim" forall a. a -> [a] -> [a]
: forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\String
x String
y -> [Pat ()] -> Pat ()
pTuple [String -> Pat ()
p String
x, String -> Pat ()
p String
y]) [String]
qtvars [String]
pvars)
Exp ()
rhs
forall a. Maybe a
Nothing
where
p :: String -> Pat ()
p = String -> Pat ()
mkPVar
v :: String -> Exp ()
v = String -> Exp ()
mkVar
tcname :: String
tcname = String -> String
firstUpper (TLTemplate -> String
topleveltfunc_name TLTemplate
t)
fname :: String
fname = String
"gen" forall a. Semigroup a => a -> a -> a
<> String
tcname forall a. Semigroup a => a -> a -> a
<> String
"InstanceFor"
itps :: [(Int, String)]
itps = forall a b. [a] -> [b] -> [(a, b)]
zip ([Int
1 ..] :: [Int]) (TLTemplate -> [String]
topleveltfunc_params TLTemplate
t)
tvars :: [String]
tvars = forall a b. (a -> b) -> [a] -> [b]
map (\(Int
i, String
_) -> String
"typ" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
i) [(Int, String)]
itps
qtvars :: [String]
qtvars = forall a b. (a -> b) -> [a] -> [b]
map (\(Int
i, String
_) -> String
"qtyp" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
i) [(Int, String)]
itps
pvars :: [String]
pvars = forall a b. (a -> b) -> [a] -> [b]
map (\(Int
i, String
_) -> String
"param" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
i) [(Int, String)]
itps
nparams :: Int
nparams = forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Int, String)]
itps
typs_v :: Exp ()
typs_v = if Int
nparams forall a. Eq a => a -> a -> Bool
== Int
1 then String -> Exp ()
v ([String]
tvars forall a. [a] -> Int -> a
!! Int
0) else [Exp ()] -> Exp ()
tuple (forall a b. (a -> b) -> [a] -> [b]
map String -> Exp ()
v [String]
tvars)
params_l :: Exp ()
params_l = [Exp ()] -> Exp ()
listE (forall a b. (a -> b) -> [a] -> [b]
map String -> Exp ()
v [String]
pvars)
sig :: Type ()
sig =
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 Type () -> Type () -> Type ()
tyfun forall a b. (a -> b) -> a -> b
$
[String -> Type ()
tycon String
"IsCPrimitive"]
forall a. [a] -> [a] -> [a]
++ forall a. Int -> a -> [a]
replicate
Int
nparams
(forall l. l -> Boxed -> [Type l] -> Type l
TyTuple () Boxed
Boxed [String -> Type ()
tycon String
"Q" Type () -> Type () -> Type ()
`tyapp` String -> Type ()
tycon String
"Type", String -> Type ()
tycon String
"TemplateParamInfo"])
forall a. [a] -> [a] -> [a]
++ [String -> Type ()
tycon String
"Q" Type () -> Type () -> Type ()
`tyapp` Type () -> Type ()
tylist (String -> Type ()
tycon String
"Dec")]
rhs :: Exp ()
rhs =
[Stmt ()] -> Exp ()
doE
( [Stmt ()
paramsstmt, Stmt ()
suffixstmt]
forall a. Semigroup a => a -> a -> a
<> [ Pat () -> Exp () -> Stmt ()
generator (String -> Pat ()
p String
"callmod_") (String -> Exp ()
v String
"fmap" Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v String
"loc_module" Exp () -> Exp () -> Exp ()
`app` (String -> Exp ()
v String
"location")),
[Decl ()] -> Stmt ()
letStmt
[ Pat () -> Exp () -> Decl ()
pbind_
(String -> Pat ()
p String
"callmod")
(String -> Exp ()
v String
"dot2_" Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v String
"callmod_")
]
]
forall a. Semigroup a => a -> a -> a
<> forall a b. (a -> b) -> [a] -> [b]
map (String, String) -> Stmt ()
genqtypstmt (forall a b. [a] -> [b] -> [(a, b)]
zip [String]
tvars [String]
qtvars)
forall a. Semigroup a => a -> a -> a
<> [forall {a}. Show a => String -> a -> Stmt ()
genstmt String
"f" (Int
1 :: Int)]
forall a. Semigroup a => a -> a -> a
<> [ Stmt ()
foreignSrcStmt,
[Decl ()] -> Stmt ()
letStmt [Decl ()]
lststmt,
Exp () -> Stmt ()
qualStmt Exp ()
retstmt
]
)
paramsstmt :: Stmt ()
paramsstmt =
[Decl ()] -> Stmt ()
letStmt
[ Pat () -> Exp () -> Decl ()
pbind_
(String -> Pat ()
p String
"params")
(String -> Exp ()
v String
"map" Exp () -> Exp () -> Exp ()
`app` (String -> Exp ()
v String
"tpinfoSuffix") Exp () -> Exp () -> Exp ()
`app` Exp ()
params_l)
]
suffixstmt :: Stmt ()
suffixstmt =
[Decl ()] -> Stmt ()
letStmt
[ Pat () -> Exp () -> Decl ()
pbind_
(String -> Pat ()
p String
"suffix")
( String -> Exp ()
v String
"concatMap"
Exp () -> Exp () -> Exp ()
`app` ([Pat ()] -> Exp () -> Exp ()
lamE [String -> Pat ()
p String
"x"] (Exp () -> QOp () -> Exp () -> Exp ()
inapp (String -> Exp ()
strE String
"_") (String -> QOp ()
op String
"++") (String -> Exp ()
v String
"tpinfoSuffix" Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v String
"x")))
Exp () -> Exp () -> Exp ()
`app` Exp ()
params_l
)
]
genqtypstmt :: (String, String) -> Stmt ()
genqtypstmt (String
tvar, String
qtvar) = Pat () -> Exp () -> Stmt ()
generator (String -> Pat ()
p String
tvar) (String -> Exp ()
v String
qtvar)
genstmt :: String -> a -> Stmt ()
genstmt String
prefix a
n =
Pat () -> Exp () -> Stmt ()
generator
(String -> Pat ()
p (String
prefix forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show a
n))
( String -> Exp ()
v String
"mkFunc" Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
strE (TLTemplate -> String
topleveltfunc_name TLTemplate
t)
Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v (String
"t_" forall a. Semigroup a => a -> a -> a
<> TLTemplate -> String
topleveltfunc_name TLTemplate
t)
Exp () -> Exp () -> Exp ()
`app` Exp ()
typs_v
Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
v String
"suffix"
)
lststmt :: [Decl ()]
lststmt = [Pat () -> Exp () -> Decl ()
pbind_ (String -> Pat ()
p String
"lst") ([Exp ()] -> Exp ()
listE [String -> Exp ()
v String
"f1"])]
foreignSrcStmt :: Stmt ()
foreignSrcStmt =
Exp () -> Stmt ()
qualifier forall a b. (a -> b) -> a -> b
$
(String -> Exp ()
v String
"addModFinalizer")
Exp () -> Exp () -> Exp ()
`app` ( String -> Exp ()
v String
"addForeignSource"
Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
con String
"LangCxx"
Exp () -> Exp () -> Exp ()
`app` ( forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
L.foldr1
(\Exp ()
x Exp ()
y -> Exp () -> QOp () -> Exp () -> Exp ()
inapp Exp ()
x (String -> QOp ()
op String
"++") Exp ()
y)
[ Exp ()
includeStatic,
String -> Exp ()
strE (String
tcname forall a. Semigroup a => a -> a -> a
<> String
"_instance"),
Exp () -> Exp ()
paren forall a b. (a -> b) -> a -> b
$
Exp () -> [Alt ()] -> Exp ()
caseE
(String -> Exp ()
v String
"isCprim")
[ Pat () -> Exp () -> Alt ()
match (String -> Pat ()
p String
"CPrim") (String -> Exp ()
strE String
"_s"),
Pat () -> Exp () -> Alt ()
match (String -> Pat ()
p String
"NonCPrim") (String -> Exp ()
strE String
"")
],
String -> Exp ()
strE String
"(",
String -> Exp ()
v String
"intercalate"
Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
strE String
", "
Exp () -> Exp () -> Exp ()
`app` Exp () -> Exp ()
paren (Exp () -> QOp () -> Exp () -> Exp ()
inapp (String -> Exp ()
v String
"callmod") (String -> QOp ()
op String
":") (String -> Exp ()
v String
"params")),
String -> Exp ()
strE String
")\n"
]
)
)
where
includeStatic :: Exp ()
includeStatic =
String -> Exp ()
strE forall a b. (a -> b) -> a -> b
$
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap
(forall a. Semigroup a => a -> a -> a
<> String
"\n")
( [CMacro Identity -> String
R.renderCMacro (forall (f :: * -> *). HeaderName -> CMacro f
R.Include (String -> HeaderName
HdrName String
"MacroPatternMatch.h"))]
forall a. [a] -> [a] -> [a]
++ forall a b. (a -> b) -> [a] -> [b]
map
CMacro Identity -> String
R.renderCMacro
( forall a b. (a -> b) -> [a] -> [b]
map forall (f :: * -> *). HeaderName -> CMacro f
R.Include (TopLevelImportHeader -> [HeaderName]
tihExtraHeadersInCPP TopLevelImportHeader
tih)
forall a. [a] -> [a] -> [a]
++ [IsCPrimitive -> TLTemplate -> CMacro Identity
genTLTmplFunCpp IsCPrimitive
CPrim TLTemplate
t, IsCPrimitive -> TLTemplate -> CMacro Identity
genTLTmplFunCpp IsCPrimitive
NonCPrim TLTemplate
t]
)
)
retstmt :: Exp ()
retstmt =
String -> Exp ()
v String
"pure"
Exp () -> Exp () -> Exp ()
`app` [Exp ()] -> Exp ()
listE
[ String -> Exp ()
v String
"mkInstance"
Exp () -> Exp () -> Exp ()
`app` [Exp ()] -> Exp ()
listE []
Exp () -> Exp () -> Exp ()
`app` forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldl1
(\Exp ()
f Exp ()
x -> String -> Exp ()
con String
"AppT" Exp () -> Exp () -> Exp ()
`app` Exp ()
f Exp () -> Exp () -> Exp ()
`app` Exp ()
x)
(String -> Exp ()
v String
"con" Exp () -> Exp () -> Exp ()
`app` String -> Exp ()
strE String
tcname forall a. a -> [a] -> [a]
: forall a b. (a -> b) -> [a] -> [b]
map String -> Exp ()
v [String]
tvars)
Exp () -> Exp () -> Exp ()
`app` (String -> Exp ()
v String
"lst")
]