inline-c 0.7.0.1 → 0.8
raw patch · 4 files changed
+64/−39 lines, 4 filesdep ~basePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base
API changes (from Hackage documentation)
+ Language.C.Inline.Internal: [codeLoc] :: Code -> Maybe Loc
- Language.C.Inline.Internal: Code :: Safety -> TypeQ -> String -> String -> Bool -> Code
+ Language.C.Inline.Internal: Code :: Safety -> Maybe Loc -> TypeQ -> String -> String -> Bool -> Code
- Language.C.Inline.Internal: genericQuote :: Purity -> (TypeQ -> Type CIdentifier -> [(CIdentifier, Type CIdentifier)] -> String -> ExpQ) -> QuasiQuoter
+ Language.C.Inline.Internal: genericQuote :: Purity -> (Loc -> TypeQ -> Type CIdentifier -> [(CIdentifier, Type CIdentifier)] -> String -> ExpQ) -> QuasiQuoter
- Language.C.Inline.Internal: inlineExp :: Safety -> TypeQ -> Type CIdentifier -> [(CIdentifier, Type CIdentifier)] -> String -> ExpQ
+ Language.C.Inline.Internal: inlineExp :: Safety -> Loc -> TypeQ -> Type CIdentifier -> [(CIdentifier, Type CIdentifier)] -> String -> ExpQ
- Language.C.Inline.Internal: inlineItems :: Safety -> Bool -> Maybe String -> TypeQ -> Type CIdentifier -> [(CIdentifier, Type CIdentifier)] -> String -> ExpQ
+ Language.C.Inline.Internal: inlineItems :: Safety -> Bool -> Maybe String -> Loc -> TypeQ -> Type CIdentifier -> [(CIdentifier, Type CIdentifier)] -> String -> ExpQ
Files
- README.md +1/−1
- inline-c.cabal +1/−1
- src/Language/C/Inline/Internal.hs +41/−23
- test/tests.hs +21/−14
README.md view
@@ -304,7 +304,7 @@ Currently `inline-c` does not work in interpreted mode. However, GHCi can still be used using the `-fobject-code` flag. For speed, we-reccomend passing `-fobject-code -O0`, for example+recommend passing `-fobject-code -O0`, for example ``` stack ghci --ghci-options='-fobject-code -O0'
inline-c.cabal view
@@ -1,5 +1,5 @@ name: inline-c-version: 0.7.0.1+version: 0.8 synopsis: Write Haskell source files including C code inline. No FFI required. description: See <https://github.com/fpco/inline-c/blob/master/README.md>. license: MIT
src/Language/C/Inline/Internal.hs view
@@ -239,6 +239,8 @@ data Code = Code { codeCallSafety :: TH.Safety -- ^ Safety of the foreign call.+ , codeLoc :: Maybe TH.Loc+ -- ^ The haskell source location used for the #line directive , codeType :: TH.TypeQ -- ^ Type of the foreign call. , codeFunName :: String@@ -266,19 +268,23 @@ -- -- @ -- c_add :: Int -> Int -> Int--- c_add = $(inlineCode $ Code--- TH.Unsafe -- Call safety--- [t| Int -> Int -> Int |] -- Call type--- "francescos_add" -- Call name--- -- C Code--- \"int francescos_add(int x, int y) { int z = x + y; return z; }\")+-- c_add = $(do+-- here <- TH.location+-- inlineCode $ Code+-- TH.Unsafe -- Call safety+-- (Just here)+-- [t| Int -> Int -> Int |] -- Call type+-- "francescos_add" -- Call name+-- -- C Code+-- \"int francescos_add(int x, int y) { int z = x + y; return z; }\") -- @ inlineCode :: Code -> TH.ExpQ inlineCode Code{..} = do -- Write out definitions ctx <- getContext let out = fromMaybe id $ ctxOutput ctx- void $ emitVerbatim $ out codeDefs+ let directive = maybe "" (\l -> "#line " ++ show (fst $ TH.loc_start l) ++ " " ++ show (TH.loc_filename l ) ++ "\n") codeLoc+ void $ emitVerbatim $ out $ directive ++ codeDefs -- Create and add the FFI declaration. ffiImportName <- uniqueFfiImportName dec <- if codeFunPtr@@ -316,16 +322,21 @@ -- -- @ -- c_cos :: Double -> Double--- c_cos = $(inlineExp--- TH.Unsafe--- [t| Double -> Double |]--- (quickCParser_ \"double\" parseType)--- [("x", quickCParser_ \"double\" parseType)]--- "cos(x)")+-- c_cos = $(do+-- here <- TH.location+-- inlineExp+-- TH.Unsafe+-- here+-- [t| Double -> Double |]+-- (quickCParser_ \"double\" parseType)+-- [("x", quickCParser_ \"double\" parseType)]+-- "cos(x)") -- @ inlineExp :: TH.Safety -- ^ Safety of the foreign call+ -> TH.Loc+ -- ^ The location to report -> TH.TypeQ -- ^ Type of the foreign call -> C.Type C.CIdentifier@@ -335,8 +346,8 @@ -> String -- ^ The C expression -> TH.ExpQ-inlineExp callSafety type_ cRetType cParams cExp =- inlineItems callSafety False Nothing type_ cRetType cParams cItems+inlineExp callSafety loc type_ cRetType cParams cExp =+ inlineItems callSafety False Nothing loc type_ cRetType cParams cItems where cItems = case cRetType of C.TypeSpecifier _quals C.Void -> cExp ++ ";"@@ -348,9 +359,13 @@ -- -- @ -- c_cos :: Double -> Double--- c_cos = $(inlineItems+-- c_cos = $(do+-- here <- TH.location+-- inlineItems -- TH.Unsafe -- False+-- Nothing+-- here -- [t| Double -> Double |] -- (quickCParser_ \"double\" parseType) -- [("x", quickCParser_ \"double\" parseType)]@@ -363,6 +378,8 @@ -- ^ Whether to return as a FunPtr or not -> Maybe String -- ^ Optional postfix for the generated name+ -> TH.Loc+ -- ^ The location to report -> TH.TypeQ -- ^ Type of the foreign call -> C.Type C.CIdentifier@@ -372,7 +389,7 @@ -> String -- ^ The C items -> TH.ExpQ-inlineItems callSafety funPtr mbPostfix type_ cRetType cParams cItems = do+inlineItems callSafety funPtr mbPostfix loc type_ cRetType cParams cItems = do let mkParam (id', paramTy) = C.ParameterDeclaration (Just id') paramTy let proto = C.Proto cRetType (map mkParam cParams) funName <- uniqueCName mbPostfix@@ -381,11 +398,10 @@ "funName:\n" ++ err Right x -> return x let decl = C.ParameterDeclaration (Just cFunName) proto- let defs =- prettyOneLine decl ++ " {\n" ++- cItems ++ "\n}\n"+ let defs = prettyOneLine decl ++ " { " ++ cItems ++ " }\n" inlineCode $ Code { codeCallSafety = callSafety+ , codeLoc = Just loc , codeType = type_ , codeFunName = funName , codeDefs = defs@@ -546,12 +562,13 @@ genericQuote :: Purity- -> (TH.TypeQ -> C.Type C.CIdentifier -> [(C.CIdentifier, C.Type C.CIdentifier)] -> String -> TH.ExpQ)+ -> (TH.Loc -> TH.TypeQ -> C.Type C.CIdentifier -> [(C.CIdentifier, C.Type C.CIdentifier)] -> String -> TH.ExpQ) -- ^ Function building an Haskell expression, see 'inlineExp' for -- guidance on the other args. -> TH.QuasiQuoter genericQuote purity build = quoteCode $ \s -> do ctx <- getContext+ here <- TH.location ParseTypedC cType cParams cExp <- runParserInQ s (haskellCParserContext (typeNamesFromTypesTable (ctxTypesTable ctx)))@@ -577,7 +594,7 @@ aqMarshaller antiQ purity (ctxTypesTable ctx) cTy x let hsFunType = convertCFunSig hsType $ map fst hsParams let cParams' = [(cId, cTy) | (cId, cTy, _) <- cParams]- ioCall <- buildFunCall ctx (build hsFunType cType cParams' cExp) (map snd hsParams) []+ ioCall <- buildFunCall ctx (build here hsFunType cType cParams' cExp) (map snd hsParams) [] -- If the user requested a pure function, make it so. case purity of Pure -> [| unsafePerformIO $(return ioCall) |]@@ -625,12 +642,13 @@ funPtrQuote :: TH.Safety -> TH.QuasiQuoter funPtrQuote callSafety = quoteCode $ \code -> do+ loc <- TH.location ctx <- getContext FunPtrDecl{..} <- runParserInQ code (C.cCParserContext (typeNamesFromTypesTable (ctxTypesTable ctx))) parse hsRetType <- cToHs ctx funPtrReturnType hsParams <- forM funPtrParameters (\(_ident, typ_) -> cToHs ctx typ_) let hsFunType = convertCFunSig hsRetType hsParams- inlineItems callSafety True funPtrName hsFunType funPtrReturnType funPtrParameters funPtrBody+ inlineItems callSafety True funPtrName loc hsFunType funPtrReturnType funPtrParameters funPtrBody where cToHs :: Context -> C.Type C.CIdentifier -> TH.TypeQ cToHs ctx cTy = do
test/tests.hs view
@@ -50,6 +50,7 @@ Hspec.it "inlineCode" $ do let c_add = $(C.inlineCode $ C.Code TH.Unsafe -- Call safety+ Nothing [t| Int -> Int -> Int |] -- Call type "francescos_add" -- Call name -- C Code@@ -57,22 +58,28 @@ False) -- not a function pointer c_add 3 4 `Hspec.shouldBe` 7 Hspec.it "inlineItems" $ do- let c_add3 = $(C.inlineItems- TH.Unsafe- False -- not a function pointer- Nothing -- no postfix- [t| CInt -> CInt |]- (C.quickCParser_ "int" C.parseType)- [("x", C.quickCParser_ "int" C.parseType)]- [r| return x + 3; |])+ let c_add3 = $(do+ here <- TH.location+ C.inlineItems+ TH.Unsafe+ False -- not a function pointer+ Nothing -- no postfix+ here+ [t| CInt -> CInt |]+ (C.quickCParser_ "int" C.parseType)+ [("x", C.quickCParser_ "int" C.parseType)]+ [r| return x + 3; |]) c_add3 1 `Hspec.shouldBe` 1 + 3 Hspec.it "inlineExp" $ do- let x = $(C.inlineExp- TH.Safe- [t| CInt |]- (C.quickCParser_ "int" C.parseType)- []- [r| 1 + 4 |])+ let x = $(do+ here <- TH.location+ C.inlineExp+ TH.Safe+ here+ [t| CInt |]+ (C.quickCParser_ "int" C.parseType)+ []+ [r| 1 + 4 |]) x `Hspec.shouldBe` 1 + 4 Hspec.it "inlineCode" $ do francescos_mul 3 4 `Hspec.shouldBe` 12