Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
Synopsis
- setContext :: Context -> Q ()
- getContext :: Q Context
- newtype Substitutions = Substitutions {
- unSubstitutions :: Map String (String -> String)
- substitute :: [(String, String -> String)] -> Q a -> Q a
- getHaskellType :: Bool -> String -> TypeQ
- emitVerbatim :: String -> DecsQ
- emitBlock :: QuasiQuoter
- data Code = Code {
- codeCallSafety :: Safety
- codeLoc :: Maybe Loc
- codeType :: TypeQ
- codeFunName :: String
- codeDefs :: String
- codeFunPtr :: Bool
- inlineCode :: Code -> ExpQ
- inlineExp :: Safety -> Loc -> TypeQ -> Type CIdentifier -> [(CIdentifier, Type CIdentifier)] -> String -> ExpQ
- inlineItems :: Safety -> Bool -> Maybe String -> Loc -> TypeQ -> Type CIdentifier -> [(CIdentifier, Type CIdentifier)] -> String -> ExpQ
- data SomeEq
- toSomeEq :: (Eq a, Typeable a) => a -> SomeEq
- fromSomeEq :: (Eq a, Typeable a) => SomeEq -> Maybe a
- data ParameterType
- data ParseTypedC = ParseTypedC {}
- parseTypedC :: forall m. CParser HaskellIdentifier m => Bool -> AntiQuoters -> m ParseTypedC
- runParserInQ :: Hashable ident => String -> CParserContext ident -> (forall m. CParser ident m => m a) -> Q a
- splitTypedC :: String -> (String, String, Int)
- lineDirective :: Loc -> String
- here :: ExpQ
- shiftLines :: Int -> Loc -> Loc
- genericQuote :: Purity -> (Loc -> TypeQ -> Type CIdentifier -> [(CIdentifier, Type CIdentifier)] -> String -> ExpQ) -> QuasiQuoter
- funPtrQuote :: Safety -> QuasiQuoter
Context handling
setContext :: Context -> Q () Source #
Sets the Context
for the current module. This function, if
called, must be called before any of the other TH functions in this
module. Fails if that's not the case.
getContext :: Q Context Source #
Gets the current Context
. Also makes sure that the current
module is initialised.
Substitution
newtype Substitutions Source #
Substitutions | |
|
substitute :: [(String, String -> String)] -> Q a -> Q a Source #
Define macros that can be used in the nested Template Haskell expression.
Macros can be used as @MACRO_NAME(input)
in inline-c quotes, and will transform their input with the given function.
They can be useful for passing in types when defining Haskell instances for C++ template types.
getHaskellType :: Bool -> String -> TypeQ Source #
Given a C type name, return the Haskell type in Template Haskell. The first parameter controls whether function pointers should be mapped as pure or IO functions.
Emitting and invoking C code
The functions in this section let us access more the C file
associated with the current module. They can be used to build
additional features on top of the basic machinery. All of
inline-c
is based upon the functions defined here.
Emitting C code
emitVerbatim :: String -> DecsQ Source #
Simply appends some string to the module's C file. Use with care.
emitBlock :: QuasiQuoter Source #
Simply appends some string of block to the module's C file. Use with care.
Inlining C code
We use the Code
data structure to represent some C code that we
want to emit to the module's C file and immediately generate a
foreign call to. For this reason, Code
includes both some C
definition, and enough information to be able to generate a foreign
call -- specifically the name of the function to call and the Haskell
type.
All the quasi-quoters work by constructing a Code
and calling
inlineCode
.
Data type representing a list of C definitions with a typed and named entry function.
We use it as a basis to inline and call C code.
Code | |
|
inlineCode :: Code -> ExpQ Source #
Inlines a piece of code inline. The resulting Exp
will have
the type specified in the codeType
.
In practice, this function outputs the C code to the module's C file,
and then inserts a foreign call of type codeType
calling the
provided codeFunName
.
Example:
c_add :: Int -> Int -> Int 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; }")
:: Safety | Safety of the foreign call |
-> Loc | The location to report |
-> TypeQ | Type of the foreign call |
-> Type CIdentifier | Return type of the C expr |
-> [(CIdentifier, Type CIdentifier)] | Parameters of the C expr |
-> String | The C expression |
-> ExpQ |
Same as inlineCItems
, but with a single expression.
c_cos :: Double -> Double c_cos = $(do here <- TH.location inlineExp TH.Unsafe here [t| Double -> Double |] (quickCParser_ "double" parseType) [("x", quickCParser_ "double" parseType)] "cos(x)")
:: Safety | Safety of the foreign call |
-> Bool | Whether to return as a FunPtr or not |
-> Maybe String | Optional postfix for the generated name |
-> Loc | The location to report |
-> TypeQ | Type of the foreign call |
-> Type CIdentifier | Return type of the C expr |
-> [(CIdentifier, Type CIdentifier)] | Parameters of the C expr |
-> String | The C items |
-> ExpQ |
Same as inlineCode
, but accepts a string containing a list of C
statements instead instead than a full-blown Code
. A function
containing the provided statement will be automatically generated.
c_cos :: Double -> Double c_cos = $(do here <- TH.location inlineItems TH.Unsafe False Nothing here [t| Double -> Double |] (quickCParser_ "double" parseType) [("x", quickCParser_ "double" parseType)] "return cos(x);")
Parsing
These functions are used to parse the anti-quotations. They're exposed for testing purposes, you really should not use them.
data ParameterType Source #
Instances
Show ParameterType Source # | |
Defined in Language.C.Inline.Internal showsPrec :: Int -> ParameterType -> ShowS # show :: ParameterType -> String # showList :: [ParameterType] -> ShowS # | |
Eq ParameterType Source # | |
Defined in Language.C.Inline.Internal (==) :: ParameterType -> ParameterType -> Bool # (/=) :: ParameterType -> ParameterType -> Bool # |
data ParseTypedC Source #
:: forall m. CParser HaskellIdentifier m | |
=> Bool | |
-> AntiQuoters | |
-> m ParseTypedC | Returns the return type, the captured variables, and the body. |
runParserInQ :: Hashable ident => String -> CParserContext ident -> (forall m. CParser ident m => m a) -> Q a Source #
Line directives
lineDirective :: Loc -> String Source #
Tell the C compiler where the next line came from.
Example:
@@
there <- location
f (unlines
[ lineDirective $(here)
, "generated_code_user_did_not_write()"
, lineDirective there
] ++ userCode
])
@@
Use lineDirective $(C.here)
when generating code, so that any errors or
warnings report the location of the generating haskell module, rather than
tangentially related user code that doesn't contain the actual problem.
Get the location of the code you're looking at, for use with
lineDirective
; place before generated code that user did not write.
Utility functions for writing quasiquoters
:: Purity | |
-> (Loc -> TypeQ -> Type CIdentifier -> [(CIdentifier, Type CIdentifier)] -> String -> ExpQ) | Function building an Haskell expression, see |
-> QuasiQuoter |
funPtrQuote :: Safety -> QuasiQuoter Source #