Skip to content

Commit

Permalink
Start migrating to direct GHC API use and ghc-exactprint (#212)
Browse files Browse the repository at this point in the history
The simplest HsProxy is migrated.
For the time being, haskell-src-exts and ghc+ghc-exactprint will coexist and haskell-src-exts will be faded away. 

* prepare for ghc-exactprint migration. use only Util.HaskellSrcExts functions except types.
* explicit export
* make proxy-test generatable (for temporary tests for ghc-exactprint codegen)
* first try to generate code using ghc-exactprint
* finally print as desired.
* success in LANGUAGE pragma printing
* mkImport implementation
* mkFun, mkFunSig
* further mkBind1
* correct indentation doE and handling empty list
* remove all s1
* con, inapp, op, par, strE
* ormolu format fix
* ghc945 -> ghc962 in CI
  • Loading branch information
wavewave committed Aug 8, 2023
1 parent 52f371d commit cce2332
Show file tree
Hide file tree
Showing 18 changed files with 1,127 additions and 126 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
nix build --print-build-logs .#ghc962.fficxx-runtime
- name: build fficxx (GHC 9.6.2)
run: |
nix build --print-build-logs .#ghc945.fficxx
nix build --print-build-logs .#ghc962.fficxx
- name: build stdcxx (GHC 9.6.2)
run: |
nix build --print-build-logs .#ghc962.stdcxx
Expand Down
55 changes: 4 additions & 51 deletions examples/proxy/Gen.hs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ import FFICXX.Generate.Type.Class
Class (..),
Function (..),
ProtectedMethod (..),
TopLevelFunction (..),
TLOrdinary (..),
TopLevel (..),
Variable (..),
)
import FFICXX.Generate.Type.Config
Expand All @@ -69,7 +70,7 @@ stdcxx_cabal :: Cabal
stdcxx_cabal =
Cabal
{ cabal_pkgname = CabalName "stdcxx",
cabal_version = "0.7.0.1",
cabal_version = "0.8",
cabal_cheaderprefix = "STD",
cabal_moduleprefix = "STD",
cabal_additional_c_incs = [],
Expand Down Expand Up @@ -98,54 +99,6 @@ deletable =
class_tmpl_funcs = []
}

-- import from stdcxx
string :: Class
string =
Class
stdcxx_cabal
"string"
[deletable]
mempty
(Just (ClassAlias {caHaskellName = "CppString", caFFIName = "string"}))
[ Constructor [cstring "p"] Nothing,
NonVirtual cstring_ "c_str" [] Nothing,
NonVirtual (cppclassref_ string) "append" [cppclassref string "str"] Nothing,
NonVirtual (cppclassref_ string) "erase" [] Nothing
]
[]
[]
False

t_vector :: TemplateClass
t_vector =
TmplCls
stdcxx_cabal
"Vector"
"std::vector"
["tp1"]
[ TFunNew [] Nothing,
TFun void_ "push_back" "push_back" [Arg (TemplateParam "tp1") "x"] Nothing,
TFun void_ "pop_back" "pop_back" [] Nothing,
TFun (TemplateParam "tp1") "at" "at" [int "n"] Nothing,
TFun int_ "size" "size" [] Nothing,
TFunDelete
]

t_unique_ptr :: TemplateClass
t_unique_ptr =
TmplCls
stdcxx_cabal
"UniquePtr"
"std::unique_ptr"
["tp1"]
[ TFunNew [] (Just "newUniquePtr0"),
TFunNew [Arg (TemplateParamPointer "tp1") "p"] Nothing,
TFun (TemplateParamPointer "tp1") "get" "get" [] Nothing,
TFun (TemplateParamPointer "tp1") "release" "release" [] Nothing,
TFun void_ "reset" "reset" [] Nothing,
TFunDelete
]

-- -------------------------------------------------------------------
-- proxy-test
-- -------------------------------------------------------------------
Expand Down Expand Up @@ -218,7 +171,7 @@ main = do
let tmpldir =
if length args == 1
then args !! 0
else "../template"
else "./template"

cwd <- getCurrentDirectory

Expand Down
6 changes: 6 additions & 0 deletions examples/proxy/cabal.project
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
packages:
../../fficxx/
../../fficxx-runtime/
optional-packages:
./stdcxx/
./proxy-test/
14 changes: 14 additions & 0 deletions experiments/ghc-exactprint.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module Main where

import Language.Haskell.GHC.ExactPrint
( makeDeltaAst,
parseModule,
showAst,
)

main :: IO ()
main = do
e <- parseModule "/nix/store/1dccaqdx3v2acc4zk5cnln14jf5q7h04-ghc-9.6.2-with-packages/lib/ghc-9.6.2/lib" "./sample.hs"
case e of
Left msg -> print "error" -- print msg
Right parsed -> putStrLn (showAst (makeDeltaAst parsed))
10 changes: 10 additions & 0 deletions experiments/sample.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{-# LANGUAGE ForeignFunctionInterface #-}
{-# OPTIONS_GHC -w #-}

module MyModule where

data K = K Int

test :: IO ()
test = do
addModFinalizer (addForeignSource LangCxx "\n#include \"test\"")
2 changes: 1 addition & 1 deletion fficxx/LICENSE
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
The following license covers this documentation, and the source code, except
where otherwise indicated.

Copyright 2011-2022, Ian-Woo Kim. All rights reserved.
Copyright 2011-2023, Ian-Woo Kim. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
Expand Down
14 changes: 12 additions & 2 deletions fficxx/fficxx.cabal
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Cabal-Version: 3.0
Cabal-Version: 3.6
Name: fficxx
Version: 0.8.0.0
Synopsis: Automatic C++ binding generation
Expand Down Expand Up @@ -31,7 +31,6 @@ Library
, fficxx-runtime
, filepath>1
, hashable
, haskell-src-exts >= 1.22
, lens > 3
, mtl>2
, process
Expand All @@ -42,6 +41,16 @@ Library
, template-haskell
, text
, unordered-containers
, haskell-src-exts
if impl (ghc >= 9.6)
Build-Depends:
ghc >= 9.6,
ghc-exactprint >= 1.7.0.0
else
Build-Depends:
ghc,
ghc-exactprint

Exposed-Modules:
FFICXX.Generate.Builder
FFICXX.Generate.Config
Expand All @@ -60,6 +69,7 @@ Library
FFICXX.Generate.QQ.Verbatim
FFICXX.Generate.Util
FFICXX.Generate.Util.DepGraph
FFICXX.Generate.Util.GHCExactPrint
FFICXX.Generate.Util.HaskellSrcExts
FFICXX.Generate.Type.Annotate
FFICXX.Generate.Type.Cabal
Expand Down
13 changes: 10 additions & 3 deletions fficxx/src/FFICXX/Generate/Builder.hs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,10 @@ import FFICXX.Generate.Type.Module
TopLevelImportHeader (..),
)
import FFICXX.Generate.Util (moduleDirFile)
import FFICXX.Generate.Util.GHCExactPrint (exactPrint)
import FFICXX.Generate.Util.HaskellSrcExts (prettyPrint)
import FFICXX.Runtime.CodeGen.Cxx (HeaderName (..))
import Language.Haskell.Exts.Pretty (prettyPrint)
import qualified Language.Haskell.GHC.ExactPrint as Exact
import System.Directory
( copyFile,
createDirectoryIfMissing,
Expand Down Expand Up @@ -163,8 +165,13 @@ simpleBuilder cfg sbc = do
--
putStrLn "Generating Proxy.hs"
for_ mods $ \m ->
when (hasProxy . cihClass . cmCIH $ m) $
gen (cmModule m <.> "Proxy" <.> "hs") (prettyPrint (C.buildProxyHs m))
when (hasProxy . cihClass . cmCIH $ m) $ do
let x = C.buildProxyHs m
putStrLn (Exact.showAst x)
putStrLn "-------"
putStrLn (exactPrint (C.buildProxyHs m))
putStrLn "-------"
gen (cmModule m <.> "Proxy" <.> "hs") (exactPrint (C.buildProxyHs m))
--
putStrLn "Generating Template.hs"
for_ tcms $ \m ->
Expand Down
6 changes: 3 additions & 3 deletions fficxx/src/FFICXX/Generate/Code/HsCast.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ module FFICXX.Generate.Code.HsCast where
import FFICXX.Generate.Name (hsClassName, typeclassName)
import FFICXX.Generate.Type.Class (Class (..), isAbstractClass)
import FFICXX.Generate.Util.HaskellSrcExts
( classA,
( app,
classA,
cxEmpty,
cxTuple,
insDecl,
Expand All @@ -18,8 +19,7 @@ import FFICXX.Generate.Util.HaskellSrcExts
tycon,
unqual,
)
import Language.Haskell.Exts.Build (app)
import Language.Haskell.Exts.Syntax (Decl (..), InstDecl (..))
import Language.Haskell.Exts.Syntax (Decl, InstDecl)

-----

Expand Down
2 changes: 1 addition & 1 deletion fficxx/src/FFICXX/Generate/Code/HsFFI.hs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import FFICXX.Generate.Type.Module
import FFICXX.Generate.Util (toLowers)
import FFICXX.Generate.Util.HaskellSrcExts (mkForImpCcall, mkImport)
import FFICXX.Runtime.CodeGen.Cxx (HeaderName (..))
import Language.Haskell.Exts.Syntax (Decl (..), ImportDecl (..))
import Language.Haskell.Exts.Syntax (Decl, ImportDecl)
import System.FilePath ((<.>))

genHsFFI :: ClassImportHeader -> [Decl ()]
Expand Down
9 changes: 4 additions & 5 deletions fficxx/src/FFICXX/Generate/Code/HsFrontEnd.hs
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,9 @@ import FFICXX.Generate.Util.HaskellSrcExts
)
import Language.Haskell.Exts.Build (app, letE, name, pApp)
import Language.Haskell.Exts.Syntax
( Context (CxTuple),
Decl (..),
ExportSpec (..),
ImportDecl (..),
( Decl,
ExportSpec,
ImportDecl,
)
import System.FilePath ((<.>))

Expand All @@ -120,7 +119,7 @@ genHsFrontDecl isHsBoot c = do
-- let cann = maybe "" id $ M.lookup (PkgClass,class_name c) amap
let cdecl = mkClass (classConstraints c) (typeclassName c) [mkTBind "a"] body
-- for hs-boot, we only have instance head.
cdecl' = mkClass (CxTuple () []) (typeclassName c) [mkTBind "a"] []
cdecl' = mkClass (cxTuple []) (typeclassName c) [mkTBind "a"] []
sigdecl f = mkFunSig (hsFuncName c f) (functionSignature c f)
body = map (clsDecl . sigdecl) . virtualFuncs . class_funcs $ c
if isHsBoot
Expand Down
50 changes: 29 additions & 21 deletions fficxx/src/FFICXX/Generate/Code/HsProxy.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3,45 +3,53 @@
module FFICXX.Generate.Code.HsProxy where

import qualified Data.List as L (foldr1)
--

import FFICXX.Generate.Util.HaskellSrcExts
( con,
import FFICXX.Generate.Util.GHCExactPrint
( app,
con,
doE,
inapp,
listE,
mkBodyStmt,
mkFun,
mkVar,
op,
qualifier,
par,
strE,
tyapp,
tycon,
tylist,
)
import qualified FFICXX.Runtime.CodeGen.Cxx as R
import Language.Haskell.Exts.Build (app, doE, listE, qualStmt, strE)
import Language.Haskell.Exts.Syntax (Decl (..))
import GHC.Hs.Extension
( GhcPs,
)
import Language.Haskell.Syntax.Decls (HsDecl)

genProxyInstance :: [Decl ()]
genProxyInstance =
mkFun fname sig [] rhs Nothing
genProxyInstance :: [HsDecl GhcPs]
genProxyInstance = mkFun fname sig [] rhs Nothing
where
fname = "genImplProxy"
v = mkVar
sig = tycon "Q" `tyapp` tylist (tycon "Dec")
rhs = doE [foreignSrcStmt, qualStmt retstmt]
rhs = doE [foreignSrcStmt, retstmt]

v = mkVar
retstmt = mkBodyStmt (v "pure" `app` listE [])

foreignSrcStmt =
qualifier $
mkBodyStmt $
(v "addModFinalizer")
`app` ( v "addForeignSource"
`app` con "LangCxx"
`app` ( L.foldr1
(\x y -> inapp x (op "++") y)
[includeStatic]
)
)
`app` par
( v "addForeignSource"
`app` con "LangCxx"
`app` par
( L.foldr1
(\x y -> inapp x (op "++") y)
[includeStatic]
)
)
where
includeStatic =
strE $
concatMap
(<> "\n")
[R.renderCMacro (R.Include "MacroPatternMatch.h")]
retstmt = v "pure" `app` listE []

0 comments on commit cce2332

Please sign in to comment.