Skip to content

Commit

Permalink
RawType code generation via ghc-exactprint (#215)
Browse files Browse the repository at this point in the history
Separated out HsRawType out of HsFrontend.
implemented mkData, mkNewtype, mkDeriving etc. so that RawType can be generated and tested.

* separate out HsRawType
* mkData, mkNewtype. HsRawType is almost converted.
* now no missing part in HsRawType
* mkDeriving
* mkTypeFamInst
* generated code formatting correctly. now it works!
* ormolu
  • Loading branch information
wavewave authored Aug 10, 2023
1 parent 83f70dc commit 086e022
Show file tree
Hide file tree
Showing 8 changed files with 288 additions and 102 deletions.
3 changes: 3 additions & 0 deletions experiments/sample.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,7 @@ test = do
addModFinalizer (addForeignSource LangCxx "\n#include \"test\"")

instance (C a) => D (P a) (Q a) where
type F (P a) = Double
dinst x = x * x

newtype Loader = Loader (Ptr RawLoader) deriving (Eq, Ord, Show)
1 change: 1 addition & 0 deletions fficxx/fficxx.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ Library
FFICXX.Generate.Code.HsFFI
FFICXX.Generate.Code.HsFrontEnd
FFICXX.Generate.Code.HsProxy
FFICXX.Generate.Code.HsRawType
FFICXX.Generate.Code.HsTemplate
FFICXX.Generate.Code.Cabal
FFICXX.Generate.Code.Primitive
Expand Down
5 changes: 3 additions & 2 deletions fficxx/src/FFICXX/Generate/Builder.hs
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,11 @@ simpleBuilder cfg sbc = do
for_ (cabal_additional_c_srcs cabal) (\(AddCSrc hdr txt) -> gen hdr txt)
--
putStrLn "Generating RawType.hs"
for_ mods $ \m ->
for_ mods $ \m -> do
debugExactPrint (C.buildRawTypeHs m)
gen
(cmModule m <.> "RawType" <.> "hs")
(prettyPrint (C.buildRawTypeHs m))
(exactPrint (C.buildRawTypeHs m))
--
putStrLn "Generating FFI.hsc"
for_ mods $ \m ->
Expand Down
14 changes: 10 additions & 4 deletions fficxx/src/FFICXX/Generate/Code/HsCast.hs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ import FFICXX.Generate.Util.GHCExactPrint
tyapp,
tycon,
)
--

import qualified FFICXX.Generate.Util.HaskellSrcExts as O
( app,
classA,
Expand Down Expand Up @@ -96,12 +94,20 @@ genHsFrontInstCastable c
(_, rname) = hsClassName c
a = mkTVar "a"
ctxt = cxTuple [classA iname [a], classA "FPtr" [a]]
in Just (instD (mkInstance ctxt "Castable" [a, tyapp tyPtr (tycon rname)] castBody))
in Just (instD (mkInstance ctxt "Castable" [a, tyapp tyPtr (tycon rname)] [] castBody))
| otherwise = Nothing

genHsFrontInstCastableSelf :: Class -> Maybe (HsDecl GhcPs)
genHsFrontInstCastableSelf c
| (not . isAbstractClass) c =
let (cname, rname) = hsClassName c
in Just (instD (mkInstance cxEmpty "Castable" [tycon cname, tyapp tyPtr (tycon rname)] castBody))
in Just $
instD
( mkInstance
cxEmpty
"Castable"
[tycon cname, tyapp tyPtr (tycon rname)]
[]
castBody
)
| otherwise = Nothing
23 changes: 0 additions & 23 deletions fficxx/src/FFICXX/Generate/Code/HsFrontEnd.hs
Original file line number Diff line number Diff line change
Expand Up @@ -189,29 +189,6 @@ genHsFrontInstVariables c =

--------------------------

hsClassRawType :: Class -> [Decl ()]
hsClassRawType c =
[ mkData rawname [] [] Nothing,
mkNewtype highname [] [qualConDecl Nothing Nothing (conDecl highname [tyapp tyPtr rawtype])] mderiv,
mkInstance
cxEmpty
"FPtr"
[hightype]
[ insType (tyapp (tycon "Raw") hightype) rawtype,
insDecl (mkBind1 "get_fptr" [pApp (name highname) [mkPVar "ptr"]] (mkVar "ptr") Nothing),
insDecl (mkBind1 "cast_fptr_to_obj" [] (con highname) Nothing)
]
]
where
(highname, rawname) = hsClassName c
hightype = tycon highname
rawtype = tycon rawname
mderiv = Just (mkDeriving [i_eq, i_ord, i_show])
where
i_eq = irule Nothing Nothing (ihcon (unqual "Eq"))
i_ord = irule Nothing Nothing (ihcon (unqual "Ord"))
i_show = irule Nothing Nothing (ihcon (unqual "Show"))

------------
-- upcast --
------------
Expand Down
62 changes: 62 additions & 0 deletions fficxx/src/FFICXX/Generate/Code/HsRawType.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
module FFICXX.Generate.Code.HsRawType
( hsClassRawType,
)
where

import FFICXX.Generate.Name (hsClassName)
import FFICXX.Generate.Type.Class (Class (..))
import FFICXX.Generate.Util.GHCExactPrint
( con,
conDecl,
cxEmpty,
instD,
mkBind1,
mkData,
mkDeriving,
mkInstance,
mkNewtype,
mkPVar,
mkTypeFamInst,
mkVar,
pApp,
parP,
tyPtr,
tyapp,
tycon,
)
import GHC.Hs (GhcPs)
import Language.Haskell.Syntax
( HsDecl (TyClD),
noExtField,
)

hsClassRawType :: Class -> [HsDecl GhcPs]
hsClassRawType c =
[ TyClD noExtField (mkData rawname [] []),
TyClD
noExtField
( mkNewtype
highname
(conDecl highname [tyapp tyPtr rawtype])
deriv
),
instD $
mkInstance
cxEmpty
"FPtr"
[hightype]
[ mkTypeFamInst "Raw" [hightype] rawtype
]
[ mkBind1
"get_fptr"
[parP (pApp highname [mkPVar "ptr"])]
(mkVar "ptr")
Nothing,
mkBind1 "cast_fptr_to_obj" [] (con highname) Nothing
]
]
where
(highname, rawname) = hsClassName c
hightype = tycon highname
rawtype = tycon rawname
deriv = mkDeriving [tycon "Eq", tycon "Ord", tycon "Show"]
29 changes: 13 additions & 16 deletions fficxx/src/FFICXX/Generate/ContentMaker.hs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ import FFICXX.Generate.Code.HsCast
import FFICXX.Generate.Code.HsFFI
( genHsFFI,
genImportInFFI,
genTopLevelFFI,
genTopLevelFFI_,
)
import FFICXX.Generate.Code.HsFrontEnd
Expand All @@ -59,9 +58,9 @@ import FFICXX.Generate.Code.HsFrontEnd
genImportInModule,
genImportInTopLevel,
genTopLevelDef,
hsClassRawType,
)
import FFICXX.Generate.Code.HsProxy (genProxyInstance)
import FFICXX.Generate.Code.HsRawType (hsClassRawType)
import FFICXX.Generate.Code.HsTemplate
( genImportInTH,
genImportInTemplate,
Expand Down Expand Up @@ -355,27 +354,25 @@ buildFFIHsc m =
<> genExtraImport m
hscBody = fmap (ForD noExtField) (genHsFFI (cmCIH m))

buildRawTypeHs :: ClassModule -> Module ()
buildRawTypeHs :: ClassModule -> HsModule GhcPs
buildRawTypeHs m =
mkModule
Ex.mkModule
(cmModule m <.> "RawType")
[ lang
[ "ForeignFunctionInterface",
"TypeFamilies",
"MultiParamTypeClasses",
"FlexibleInstances",
"TypeSynonymInstances",
"EmptyDataDecls",
"ExistentialQuantification",
"ScopedTypeVariables"
]
[ "ForeignFunctionInterface",
"TypeFamilies",
"MultiParamTypeClasses",
"FlexibleInstances",
"TypeSynonymInstances",
"EmptyDataDecls",
"ExistentialQuantification",
"ScopedTypeVariables"
]
rawtypeImports
rawtypeBody
where
rawtypeImports =
[ mkImport "Foreign.Ptr",
mkImport "FFICXX.Runtime.Cast"
[ Ex.mkImport "Foreign.Ptr",
Ex.mkImport "FFICXX.Runtime.Cast"
]
rawtypeBody =
let c = cihClass (cmCIH m)
Expand Down
Loading

0 comments on commit 086e022

Please sign in to comment.