-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | Write Haskell source files including C code inline. No FFI required.
--
@package inline-c
@version 0.5.4.0
-- | A parser for C99 declarations. Currently, the parser has the following
-- limitations:
--
--
-- - Array sizes can only be *, n (where n is a
-- positive integer), x (where x is a C identifier). In
-- C99 they can be arbitrary expressions. See the
-- ArrayType data type.
-- - _Bool, _Complex, and _Imaginary are not
-- present.
-- - Untyped parameter lists (pre-K&R C) are not allowed.
--
--
-- The parser is incremental and generic (see CParser).
-- Pretty and Arbitrary instances are provided for all the
-- data types.
--
-- The entry point if you want to parse C declarations is
-- parameter_declaration.
module Language.C.Types.Parse
-- | A collection of named types (typedefs)
type TypeNames = HashSet CIdentifier
data CParserContext i
CParserContext :: String -> TypeNames -> (forall m. CParser i m => m i) -> (i -> String) -> CParserContext i
cpcIdentName :: CParserContext i -> String
-- | Function used to determine whether an identifier is a type name.
cpcTypeNames :: CParserContext i -> TypeNames
-- | Parses an identifier, *without consuming whitespace afterwards*.
cpcParseIdent :: CParserContext i -> forall m. CParser i m => m i
cpcIdentToString :: CParserContext i -> i -> String
-- | A type for C identifiers.
data CIdentifier
unCIdentifier :: CIdentifier -> String
cIdentifierFromString :: String -> Either String CIdentifier
cCParserContext :: TypeNames -> CParserContext CIdentifier
-- | All the parsing is done using the type classes provided by the
-- parsers package. You can use the parsing routines with any of
-- the parsers that implement the classes, such as parsec or
-- trifecta.
--
-- We parametrize the parsing by the type of the variable identifiers,
-- i. We do so because we use this parser to implement
-- anti-quoters referring to Haskell variables, and thus we need to parse
-- Haskell identifiers in certain positions.
type CParser i m = (Monad m, Functor m, Applicative m, MonadPlus m, Parsing m, CharParsing m, TokenParsing m, LookAheadParsing m, MonadReader (CParserContext i) m, Hashable i)
-- | Runs a CParser using parsec.
runCParser :: Stream s Identity Char => CParserContext i -> String -> s -> (ReaderT (CParserContext i) (Parsec s ()) a) -> Either ParseError a
-- | Useful for quick testing. Uses "quickCParser" as source name,
-- and throws an error if parsing fails.
quickCParser :: CParserContext i -> String -> (ReaderT (CParserContext i) (Parsec String ()) a) -> a
-- | Like quickCParser, but uses cCParserContext
-- (const False) as CParserContext.
quickCParser_ :: String -> (ReaderT (CParserContext CIdentifier) (Parsec String ()) a) -> a
identifier_no_lex :: CParser i m => m i
data DeclarationSpecifier
StorageClassSpecifier :: StorageClassSpecifier -> DeclarationSpecifier
TypeSpecifier :: TypeSpecifier -> DeclarationSpecifier
TypeQualifier :: TypeQualifier -> DeclarationSpecifier
FunctionSpecifier :: FunctionSpecifier -> DeclarationSpecifier
declaration_specifiers :: CParser i m => m [DeclarationSpecifier]
data StorageClassSpecifier
TYPEDEF :: StorageClassSpecifier
EXTERN :: StorageClassSpecifier
STATIC :: StorageClassSpecifier
AUTO :: StorageClassSpecifier
REGISTER :: StorageClassSpecifier
storage_class_specifier :: CParser i m => m StorageClassSpecifier
data TypeSpecifier
VOID :: TypeSpecifier
CHAR :: TypeSpecifier
SHORT :: TypeSpecifier
INT :: TypeSpecifier
LONG :: TypeSpecifier
FLOAT :: TypeSpecifier
DOUBLE :: TypeSpecifier
SIGNED :: TypeSpecifier
UNSIGNED :: TypeSpecifier
Struct :: CIdentifier -> TypeSpecifier
Enum :: CIdentifier -> TypeSpecifier
TypeName :: CIdentifier -> TypeSpecifier
type_specifier :: CParser i m => m TypeSpecifier
data TypeQualifier
CONST :: TypeQualifier
RESTRICT :: TypeQualifier
VOLATILE :: TypeQualifier
type_qualifier :: CParser i m => m TypeQualifier
data FunctionSpecifier
INLINE :: FunctionSpecifier
function_specifier :: CParser i m => m FunctionSpecifier
data Declarator i
Declarator :: [Pointer] -> (DirectDeclarator i) -> Declarator i
declaratorPointers :: Declarator i -> [Pointer]
declaratorDirect :: Declarator i -> (DirectDeclarator i)
declarator :: CParser i m => m (Declarator i)
data DirectDeclarator i
DeclaratorRoot :: i -> DirectDeclarator i
ArrayOrProto :: (DirectDeclarator i) -> (ArrayOrProto i) -> DirectDeclarator i
DeclaratorParens :: (Declarator i) -> DirectDeclarator i
direct_declarator :: CParser i m => m (DirectDeclarator i)
data ArrayOrProto i
Array :: (ArrayType i) -> ArrayOrProto i
Proto :: [ParameterDeclaration i] -> ArrayOrProto i
array_or_proto :: CParser i m => m (ArrayOrProto i)
data ArrayType i
VariablySized :: ArrayType i
Unsized :: ArrayType i
SizedByInteger :: Integer -> ArrayType i
SizedByIdentifier :: i -> ArrayType i
array_type :: CParser i m => m (ArrayType i)
data Pointer
Pointer :: [TypeQualifier] -> Pointer
pointer :: CParser i m => m Pointer
data ParameterDeclaration i
ParameterDeclaration :: [DeclarationSpecifier] -> DeclaratorOrAbstractDeclarator i -> ParameterDeclaration i
parameterDeclarationSpecifiers :: ParameterDeclaration i -> [DeclarationSpecifier]
parameterDeclarationDeclarator :: ParameterDeclaration i -> DeclaratorOrAbstractDeclarator i
data DeclaratorOrAbstractDeclarator i
IsDeclarator :: (Declarator i) -> DeclaratorOrAbstractDeclarator i
IsAbstractDeclarator :: (AbstractDeclarator i) -> DeclaratorOrAbstractDeclarator i
parameter_declaration :: CParser i m => m (ParameterDeclaration i)
parameter_list :: CParser i m => m [ParameterDeclaration i]
data AbstractDeclarator i
AbstractDeclarator :: [Pointer] -> Maybe (DirectAbstractDeclarator i) -> AbstractDeclarator i
abstractDeclaratorPointers :: AbstractDeclarator i -> [Pointer]
abstractDeclaratorDirect :: AbstractDeclarator i -> Maybe (DirectAbstractDeclarator i)
abstract_declarator :: CParser i m => m (AbstractDeclarator i)
data DirectAbstractDeclarator i
ArrayOrProtoHere :: (ArrayOrProto i) -> DirectAbstractDeclarator i
ArrayOrProtoThere :: (DirectAbstractDeclarator i) -> (ArrayOrProto i) -> DirectAbstractDeclarator i
AbstractDeclaratorParens :: (AbstractDeclarator i) -> DirectAbstractDeclarator i
direct_abstract_declarator :: CParser i m => m (DirectAbstractDeclarator i)
cIdentStart :: [Char]
cIdentLetter :: [Char]
cReservedWords :: HashSet String
-- | Type used to generate an Arbitrary ParameterDeclaration
-- with arbitrary allowed type names.
data ParameterDeclarationWithTypeNames i
ParameterDeclarationWithTypeNames :: HashSet CIdentifier -> (ParameterDeclaration i) -> ParameterDeclarationWithTypeNames i
pdwtnTypeNames :: ParameterDeclarationWithTypeNames i -> HashSet CIdentifier
pdwtnParameterDeclaration :: ParameterDeclarationWithTypeNames i -> (ParameterDeclaration i)
arbitraryParameterDeclarationWithTypeNames :: (Arbitrary i, Hashable i) => (i -> String) -> Gen (ParameterDeclarationWithTypeNames i)
instance Typeable CIdentifier
instance Typeable StorageClassSpecifier
instance Typeable TypeSpecifier
instance Typeable TypeQualifier
instance Typeable FunctionSpecifier
instance Typeable DeclarationSpecifier
instance Typeable ArrayType
instance Typeable Pointer
instance Typeable DirectAbstractDeclarator
instance Typeable AbstractDeclarator
instance Typeable ArrayOrProto
instance Typeable ParameterDeclaration
instance Typeable DeclaratorOrAbstractDeclarator
instance Typeable Declarator
instance Typeable DirectDeclarator
instance Typeable OneOfSized
instance Typeable ParameterDeclarationWithTypeNames
instance Eq CIdentifier
instance Ord CIdentifier
instance Show CIdentifier
instance Hashable CIdentifier
instance Eq StorageClassSpecifier
instance Show StorageClassSpecifier
instance Eq TypeSpecifier
instance Show TypeSpecifier
instance Eq TypeQualifier
instance Show TypeQualifier
instance Eq FunctionSpecifier
instance Show FunctionSpecifier
instance Eq DeclarationSpecifier
instance Show DeclarationSpecifier
instance Eq i => Eq (ArrayType i)
instance Show i => Show (ArrayType i)
instance Functor ArrayType
instance Foldable ArrayType
instance Traversable ArrayType
instance Eq Pointer
instance Show Pointer
instance Eq i => Eq (DirectAbstractDeclarator i)
instance Show i => Show (DirectAbstractDeclarator i)
instance Functor DirectAbstractDeclarator
instance Foldable DirectAbstractDeclarator
instance Traversable DirectAbstractDeclarator
instance Eq i => Eq (AbstractDeclarator i)
instance Show i => Show (AbstractDeclarator i)
instance Functor AbstractDeclarator
instance Foldable AbstractDeclarator
instance Traversable AbstractDeclarator
instance Eq i => Eq (ArrayOrProto i)
instance Show i => Show (ArrayOrProto i)
instance Functor ArrayOrProto
instance Foldable ArrayOrProto
instance Traversable ArrayOrProto
instance Eq i => Eq (ParameterDeclaration i)
instance Show i => Show (ParameterDeclaration i)
instance Functor ParameterDeclaration
instance Foldable ParameterDeclaration
instance Traversable ParameterDeclaration
instance Eq i => Eq (DeclaratorOrAbstractDeclarator i)
instance Show i => Show (DeclaratorOrAbstractDeclarator i)
instance Functor DeclaratorOrAbstractDeclarator
instance Foldable DeclaratorOrAbstractDeclarator
instance Traversable DeclaratorOrAbstractDeclarator
instance Eq i => Eq (Declarator i)
instance Show i => Show (Declarator i)
instance Functor Declarator
instance Foldable Declarator
instance Traversable Declarator
instance Eq i => Eq (DirectDeclarator i)
instance Show i => Show (DirectDeclarator i)
instance Functor DirectDeclarator
instance Foldable DirectDeclarator
instance Traversable DirectDeclarator
instance Eq a => Eq (OneOfSized a)
instance Show a => Show (OneOfSized a)
instance Eq i => Eq (ParameterDeclarationWithTypeNames i)
instance Show i => Show (ParameterDeclarationWithTypeNames i)
instance Arbitrary Pointer
instance Arbitrary FunctionSpecifier
instance Arbitrary TypeQualifier
instance Arbitrary StorageClassSpecifier
instance Arbitrary CIdentifier
instance Pretty i => Pretty (DirectAbstractDeclarator i)
instance Pretty i => Pretty (AbstractDeclarator i)
instance Pretty i => Pretty (ParameterDeclaration i)
instance Pretty i => Pretty (ArrayType i)
instance Pretty i => Pretty (ArrayOrProto i)
instance Pretty i => Pretty (DirectDeclarator i)
instance Pretty Pointer
instance Pretty i => Pretty (Declarator i)
instance Pretty FunctionSpecifier
instance Pretty TypeQualifier
instance Pretty TypeSpecifier
instance Pretty StorageClassSpecifier
instance Pretty DeclarationSpecifier
instance Pretty CIdentifier
instance IsString CIdentifier
module Language.C.Inline.HaskellIdentifier
-- | A possibly qualified Haskell identifier.
data HaskellIdentifier
unHaskellIdentifier :: HaskellIdentifier -> String
haskellIdentifierFromString :: String -> Either String HaskellIdentifier
haskellCParserContext :: TypeNames -> CParserContext HaskellIdentifier
-- | See
-- https://www.haskell.org/onlinereport/haskell2010/haskellch2.html#x7-160002.2.
parseHaskellIdentifier :: CParser i m => m HaskellIdentifier
-- | Mangles an HaskellIdentifier to produce a valid
-- CIdentifier which still sort of resembles the
-- HaskellIdentifier.
mangleHaskellIdentifier :: HaskellIdentifier -> CIdentifier
instance Typeable HaskellIdentifier
instance Eq HaskellIdentifier
instance Ord HaskellIdentifier
instance Show HaskellIdentifier
instance Hashable HaskellIdentifier
instance Arbitrary HaskellIdentifier
instance Pretty HaskellIdentifier
instance IsString HaskellIdentifier
-- | Views of C datatypes. While Language.C.Types.Parse defines
-- datatypes for representing the concrete syntax tree of C types, this
-- module provides friendlier views of C types, by turning them into a
-- data type matching more closely how we read and think about types,
-- both in Haskell and in C. To appreciate the difference, look at the
-- difference between ParameterDeclaration and
-- ParameterDeclaration.
--
-- As a bonus, routines are provided for describing types in natural
-- language (English) -- see describeParameterDeclaration and
-- describeType.
module Language.C.Types
-- | A type for C identifiers.
data CIdentifier
unCIdentifier :: CIdentifier -> String
cIdentifierFromString :: String -> Either String CIdentifier
data StorageClassSpecifier
TYPEDEF :: StorageClassSpecifier
EXTERN :: StorageClassSpecifier
STATIC :: StorageClassSpecifier
AUTO :: StorageClassSpecifier
REGISTER :: StorageClassSpecifier
data TypeQualifier
CONST :: TypeQualifier
RESTRICT :: TypeQualifier
VOLATILE :: TypeQualifier
data FunctionSpecifier
INLINE :: FunctionSpecifier
data ArrayType i
VariablySized :: ArrayType i
Unsized :: ArrayType i
SizedByInteger :: Integer -> ArrayType i
SizedByIdentifier :: i -> ArrayType i
data Specifiers
Specifiers :: [StorageClassSpecifier] -> [TypeQualifier] -> [FunctionSpecifier] -> Specifiers
storageClassSpecifiers :: Specifiers -> [StorageClassSpecifier]
typeQualifiers :: Specifiers -> [TypeQualifier]
functionSpecifiers :: Specifiers -> [FunctionSpecifier]
data Type i
TypeSpecifier :: Specifiers -> TypeSpecifier -> Type i
Ptr :: [TypeQualifier] -> (Type i) -> Type i
Array :: (ArrayType i) -> (Type i) -> Type i
Proto :: (Type i) -> [ParameterDeclaration i] -> Type i
data TypeSpecifier
Void :: TypeSpecifier
Char :: (Maybe Sign) -> TypeSpecifier
Short :: Sign -> TypeSpecifier
Int :: Sign -> TypeSpecifier
Long :: Sign -> TypeSpecifier
LLong :: Sign -> TypeSpecifier
Float :: TypeSpecifier
Double :: TypeSpecifier
LDouble :: TypeSpecifier
TypeName :: CIdentifier -> TypeSpecifier
Struct :: CIdentifier -> TypeSpecifier
Enum :: CIdentifier -> TypeSpecifier
data Sign
Signed :: Sign
Unsigned :: Sign
data ParameterDeclaration i
ParameterDeclaration :: Maybe i -> (Type i) -> ParameterDeclaration i
parameterDeclarationId :: ParameterDeclaration i -> Maybe i
parameterDeclarationType :: ParameterDeclaration i -> (Type i)
-- | A collection of named types (typedefs)
type TypeNames = HashSet CIdentifier
-- | All the parsing is done using the type classes provided by the
-- parsers package. You can use the parsing routines with any of
-- the parsers that implement the classes, such as parsec or
-- trifecta.
--
-- We parametrize the parsing by the type of the variable identifiers,
-- i. We do so because we use this parser to implement
-- anti-quoters referring to Haskell variables, and thus we need to parse
-- Haskell identifiers in certain positions.
type CParser i m = (Monad m, Functor m, Applicative m, MonadPlus m, Parsing m, CharParsing m, TokenParsing m, LookAheadParsing m, MonadReader (CParserContext i) m, Hashable i)
data CParserContext i
cCParserContext :: TypeNames -> CParserContext CIdentifier
-- | Runs a CParser using parsec.
runCParser :: Stream s Identity Char => CParserContext i -> String -> s -> (ReaderT (CParserContext i) (Parsec s ()) a) -> Either ParseError a
-- | Useful for quick testing. Uses "quickCParser" as source name,
-- and throws an error if parsing fails.
quickCParser :: CParserContext i -> String -> (ReaderT (CParserContext i) (Parsec String ()) a) -> a
-- | Like quickCParser, but uses cCParserContext
-- (const False) as CParserContext.
quickCParser_ :: String -> (ReaderT (CParserContext CIdentifier) (Parsec String ()) a) -> a
parseParameterDeclaration :: (CParser i m, Pretty i) => m (ParameterDeclaration i)
parseParameterList :: (CParser i m, Pretty i) => m [ParameterDeclaration i]
parseIdentifier :: CParser i m => m i
parseType :: (CParser i m, Pretty i) => m (Type i)
data UntangleErr
MultipleDataTypes :: [DeclarationSpecifier] -> UntangleErr
NoDataTypes :: [DeclarationSpecifier] -> UntangleErr
IllegalSpecifiers :: String -> [TypeSpecifier] -> UntangleErr
untangleParameterDeclaration :: ParameterDeclaration i -> Either UntangleErr (ParameterDeclaration i)
tangleParameterDeclaration :: ParameterDeclaration i -> ParameterDeclaration i
describeParameterDeclaration :: Pretty i => ParameterDeclaration i -> Doc
describeType :: Pretty i => Type i -> Doc
instance Typeable Specifiers
instance Typeable Sign
instance Typeable TypeSpecifier
instance Typeable ParameterDeclaration
instance Typeable Type
instance Typeable UntangleErr
instance Show Specifiers
instance Eq Specifiers
instance Show Sign
instance Eq Sign
instance Ord Sign
instance Show TypeSpecifier
instance Eq TypeSpecifier
instance Ord TypeSpecifier
instance Show i => Show (ParameterDeclaration i)
instance Eq i => Eq (ParameterDeclaration i)
instance Functor ParameterDeclaration
instance Foldable ParameterDeclaration
instance Traversable ParameterDeclaration
instance Show i => Show (Type i)
instance Eq i => Eq (Type i)
instance Functor Type
instance Foldable Type
instance Traversable Type
instance Show UntangleErr
instance Eq UntangleErr
instance Pretty i => Pretty (Type i)
instance Pretty i => Pretty (ParameterDeclaration i)
instance Pretty UntangleErr
instance Pretty TypeSpecifier
instance Monoid Specifiers
-- | A Context is used to define the capabilities of the Template
-- Haskell code that handles the inline C code. See the documentation of
-- the data type for more details.
--
-- In practice, a Context will have to be defined for each library
-- that defines new C types, to allow the TemplateHaskell code to
-- interpret said types correctly.
module Language.C.Inline.Context
-- | A mapping from TypeSpecifiers to Haskell types. Needed both to
-- parse C types, and to convert them to Haskell types.
type TypesTable = Map TypeSpecifier TypeQ
-- | A data type to indicate whether the user requested pure or IO function
-- from Haskell
data Purity
Pure :: Purity
IO :: Purity
-- | Given a Context, it uses its ctxTypesTable to convert
-- arbitrary C types.
convertType :: Purity -> TypesTable -> Type CIdentifier -> Q (Maybe Type)
-- | An alias for Ptr.
type CArray = Ptr
typeNamesFromTypesTable :: TypesTable -> TypeNames
-- | Specifies how to parse and process an antiquotation in the C code.
--
-- All antiquotations (apart from plain variable capture) have syntax
--
--
-- $XXX:YYY
--
--
-- Where XXX is the name of the antiquoter and YYY is
-- something parseable by the respective aqParser.
data AntiQuoter a
AntiQuoter :: (forall m. CParser HaskellIdentifier m => m (CIdentifier, Type CIdentifier, a)) -> (Purity -> TypesTable -> Type CIdentifier -> a -> Q (Type, Exp)) -> AntiQuoter a
-- | Parses the body of the antiquotation, returning a hint for the name to
-- assign to the variable that will replace the anti-quotation, the type
-- of said variable, and some arbitrary data which will then be fed to
-- aqMarshaller.
--
-- The Type has Void as an identifier type to make sure
-- that no names appear in it.
aqParser :: AntiQuoter a -> forall m. CParser HaskellIdentifier m => m (CIdentifier, Type CIdentifier, a)
-- | Takes the requested purity, the current TypesTable, and the
-- type and the body returned by aqParser.
--
-- Returns the Haskell type for the parameter, and the Haskell expression
-- that will be passed in as the parameter.
--
-- If the the type returned is ty, the Exp must
-- have type forall a. (ty -> IO a) -> IO a. This allows
-- to do resource handling when preparing C values.
--
-- Care must be taken regarding Purity. Specifically, the
-- generated IO computation must be idempotent to guarantee its safety
-- when used in pure code. We cannot prevent the IO computation from
-- being inlined, hence potentially duplicated. If non-idempotent
-- marshallers are required (e.g. if an update to some global state is
-- needed), it is best to throw an error when Purity is
-- Pure (for example "you cannot use context X with
-- pure"), which will show up at compile time.
aqMarshaller :: AntiQuoter a -> Purity -> TypesTable -> Type CIdentifier -> a -> Q (Type, Exp)
-- | An identifier for a AntiQuoter.
type AntiQuoterId = String
-- | Existential wrapper around AntiQuoter.
data SomeAntiQuoter
SomeAntiQuoter :: (AntiQuoter a) -> SomeAntiQuoter
type AntiQuoters = Map AntiQuoterId SomeAntiQuoter
-- | A Context stores various information needed to produce the
-- files with the C code derived from the inline C snippets.
--
-- Contexts can be composed with their Monoid instance,
-- where mappend is right-biased -- in mappend x y
-- y will take precedence over x.
data Context
Context :: TypesTable -> AntiQuoters -> Maybe String -> Maybe (String -> String) -> Context
-- | Needed to convert C types to Haskell types.
ctxTypesTable :: Context -> TypesTable
-- | Needed to parse and process antiquotations.
ctxAntiQuoters :: Context -> AntiQuoters
-- | Will determine the extension of the file containing the inline C
-- snippets.
ctxFileExtension :: Context -> Maybe String
-- | This function is used to post-process the functions generated from the
-- C snippets. Currently just used to specify C linkage when generating
-- C++ code.
ctxOutput :: Context -> Maybe (String -> String)
-- | Context useful to work with vanilla C. Used by default.
--
-- ctxTypesTable: converts C basic types to their counterparts in
-- Foreign.C.Types.
--
-- No ctxAntiQuoters.
baseCtx :: Context
-- | This Context includes a AntiQuoter that removes the need
-- for explicitely creating FunPtrs, named "fun".
--
-- For example, we can capture function f of type CInt ->
-- CInt -> IO CInt in C code using $fun:(int (*f)(int,
-- int)).
--
-- When used in a pure embedding, the Haskell function will have
-- to be pure too. Continuing the example above we'll have CInt ->
-- CInt -> IO CInt.
--
-- Does not include the baseCtx, since most of the time it's going
-- to be included as part of larger contexts.
funCtx :: Context
-- | This Context includes two AntiQuoters that allow to
-- easily use Haskell vectors in C.
--
-- Specifically, the vec-len and vec-ptr will get the
-- length and the pointer underlying mutable (IOVector) and
-- immutable (Vector) storable vectors.
--
-- Note that if you use vecCtx to manipulate immutable vectors you
-- must make sure that the vector is not modified in the C code.
--
-- To use vec-len, simply write $vec-len:x, where
-- x is something of type IOVector a or
-- Vector a, for some a. To use vec-ptr
-- you need to specify the type of the pointer, e.g. $vec-len:(int
-- *x) will work if x has type IOVector
-- CInt.
vecCtx :: Context
-- | Type class used to implement the anti-quoters in vecCtx.
class VecCtx a where type family VecCtxScalar a :: *
vecCtxLength :: VecCtx a => a -> Int
vecCtxUnsafeWith :: VecCtx a => a -> (Ptr (VecCtxScalar a) -> IO b) -> IO b
-- | bsCtx serves exactly the same purpose as vecCtx, but
-- only for ByteString. vec-ptr becomes bs-ptr,
-- and vec-len becomes bs-len. You don't need to
-- specify the type of the pointer in bs-ptr, it will always be
-- char*.
bsCtx :: Context
instance Eq Purity
instance Show Purity
instance Storable a => VecCtx (IOVector a)
instance Storable a => VecCtx (Vector a)
instance Monoid Context
module Language.C.Inline.Internal
-- | 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.
setContext :: Context -> Q ()
-- | Gets the current Context. Also makes sure that the current
-- module is initialised.
getContext :: Q Context
-- | Simply appends some string to the module's C file. Use with care.
emitVerbatim :: String -> DecsQ
-- | 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.
data Code
Code :: Safety -> TypeQ -> String -> String -> Code
-- | Safety of the foreign call.
codeCallSafety :: Code -> Safety
-- | Type of the foreign call.
codeType :: Code -> TypeQ
-- | Name of the function to call in the code below.
codeFunName :: Code -> String
-- | The C code.
codeDefs :: Code -> String
-- | 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 = $(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; }")
--
inlineCode :: Code -> ExpQ
-- | Same as inlineCItems, but with a single expression.
--
--
-- c_cos :: Double -> Double
-- c_cos = $(inlineExp
-- TH.Unsafe
-- [t| Double -> Double |]
-- (quickCParser_ "double" parseType)
-- [("x", quickCParser_ "double") parseType]
-- "cos(x)")
--
inlineExp :: Safety -> TypeQ -> Type CIdentifier -> [(CIdentifier, Type CIdentifier)] -> String -> 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 = $(inlineItems
-- TH.Unsafe
-- [t| Double -> Double |]
-- (quickCParser_ "double" parseType)
-- [("x", quickCParser_ "double" parseType)]
-- "return cos(x);")
--
inlineItems :: Safety -> 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
Plain :: HaskellIdentifier -> ParameterType
AntiQuote :: AntiQuoterId -> SomeEq -> ParameterType
data ParseTypedC
ParseTypedC :: Type CIdentifier -> [(CIdentifier, Type CIdentifier, ParameterType)] -> String -> ParseTypedC
ptcReturnType :: ParseTypedC -> Type CIdentifier
ptcParameters :: ParseTypedC -> [(CIdentifier, Type CIdentifier, ParameterType)]
ptcBody :: ParseTypedC -> String
parseTypedC :: CParser HaskellIdentifier m => AntiQuoters -> m ParseTypedC
runParserInQ :: String -> TypeNames -> (forall m. CParser HaskellIdentifier m => m a) -> Q a
genericQuote :: Purity -> (TypeQ -> Type CIdentifier -> [(CIdentifier, Type CIdentifier)] -> String -> ExpQ) -> QuasiQuoter
instance Show ParameterType
instance Eq ParameterType
instance Show SomeEq
instance Eq SomeEq
-- | unsafe variants of the Language.C.Inline
-- quasi-quoters, to call the C code unsafely in the sense of
-- https://www.haskell.org/onlinereport/haskell2010/haskellch8.html#x15-1590008.4.3.
-- In GHC, unsafe foreign calls are faster than safe foreign calls, but
-- the user must guarantee the control flow will never enter Haskell code
-- (via a callback or otherwise) before the call is done.
--
-- This module is intended to be imported qualified:
--
--
-- import qualified Language.C.Inline.Unsafe as CU
--
module Language.C.Inline.Unsafe
-- | C expressions.
exp :: QuasiQuoter
-- | Variant of exp, for use with expressions known to have no side
-- effects.
--
-- BEWARE: use this function with caution, only when you know what you
-- are doing. If an expression does in fact have side-effects, then
-- indiscriminate use of pure may endanger referential
-- transparency, and in principle even type safety.
pure :: QuasiQuoter
-- | C code blocks (i.e. statements).
block :: QuasiQuoter
-- | Enable painless embedding of C code in Haskell code. If you're
-- interested in how to use the library, skip to the "Inline C" section.
-- To build, read the first two sections.
--
-- This module is intended to be imported qualified:
--
--
-- import qualified Language.C.Inline as C
--
module Language.C.Inline
-- | A Context stores various information needed to produce the
-- files with the C code derived from the inline C snippets.
--
-- Contexts can be composed with their Monoid instance,
-- where mappend is right-biased -- in mappend x y
-- y will take precedence over x.
data Context
-- | Context useful to work with vanilla C. Used by default.
--
-- ctxTypesTable: converts C basic types to their counterparts in
-- Foreign.C.Types.
--
-- No ctxAntiQuoters.
baseCtx :: Context
-- | This Context includes a AntiQuoter that removes the need
-- for explicitely creating FunPtrs, named "fun".
--
-- For example, we can capture function f of type CInt ->
-- CInt -> IO CInt in C code using $fun:(int (*f)(int,
-- int)).
--
-- When used in a pure embedding, the Haskell function will have
-- to be pure too. Continuing the example above we'll have CInt ->
-- CInt -> IO CInt.
--
-- Does not include the baseCtx, since most of the time it's going
-- to be included as part of larger contexts.
funCtx :: Context
-- | This Context includes two AntiQuoters that allow to
-- easily use Haskell vectors in C.
--
-- Specifically, the vec-len and vec-ptr will get the
-- length and the pointer underlying mutable (IOVector) and
-- immutable (Vector) storable vectors.
--
-- Note that if you use vecCtx to manipulate immutable vectors you
-- must make sure that the vector is not modified in the C code.
--
-- To use vec-len, simply write $vec-len:x, where
-- x is something of type IOVector a or
-- Vector a, for some a. To use vec-ptr
-- you need to specify the type of the pointer, e.g. $vec-len:(int
-- *x) will work if x has type IOVector
-- CInt.
vecCtx :: Context
-- | bsCtx serves exactly the same purpose as vecCtx, but
-- only for ByteString. vec-ptr becomes bs-ptr,
-- and vec-len becomes bs-len. You don't need to
-- specify the type of the pointer in bs-ptr, it will always be
-- char*.
bsCtx :: Context
-- | 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.
context :: Context -> DecsQ
-- | C expressions.
exp :: QuasiQuoter
-- | Variant of exp, for use with expressions known to have no side
-- effects.
--
-- BEWARE: use this function with caution, only when you know what you
-- are doing. If an expression does in fact have side-effects, then
-- indiscriminate use of pure may endanger referential
-- transparency, and in principle even type safety.
pure :: QuasiQuoter
-- | C code blocks (i.e. statements).
block :: QuasiQuoter
-- | Emits a CPP include directive for C code associated with the current
-- module. To avoid having to escape quotes, the function itself adds
-- them when appropriate, so that
--
--
-- include "foo.h" ==> #include "foo.h"
--
--
-- but
--
--
-- include "<foo>" ==> #include <foo>
--
include :: String -> DecsQ
-- | Emits an arbitrary C string to the C code associated with the current
-- module. Use with care.
verbatim :: String -> DecsQ
-- | Like alloca, but also peeks the contents of the Ptr and
-- returns them once the provided action has finished.
withPtr :: Storable a => (Ptr a -> IO b) -> IO (a, b)
withPtr_ :: Storable a => (Ptr a -> IO ()) -> IO a
-- | Type class with methods useful to allocate and peek multiple pointers
-- at once:
--
--
-- withPtrs_ :: (Storable a, Storable b) => ((Ptr a, Ptr b) -> IO ()) -> IO (a, b)
-- withPtrs_ :: (Storable a, Storable b, Storable c) => ((Ptr a, Ptr b, Ptr c) -> IO ()) -> IO (a, b, c)
-- ...
--
class WithPtrs a where type family WithPtrsPtrs a :: * withPtrs_ f = do { (x, _) <- withPtrs f; return x }
withPtrs :: WithPtrs a => (WithPtrsPtrs a -> IO b) -> IO (a, b)
withPtrs_ :: WithPtrs a => (WithPtrsPtrs a -> IO ()) -> IO a
-- | $(mkFunPtr [t| CDouble -> IO
-- CDouble |] generates a foreign import wrapper of type
--
--
-- (CDouble -> IO CDouble) -> IO (FunPtr (CDouble -> IO CDouble))
--
--
-- And invokes it.
mkFunPtr :: TypeQ -> ExpQ
-- | $(mkFunPtrFromName 'foo), if foo ::
-- CDouble -> IO CDouble, splices in an
-- expression of type IO (FunPtr (CDouble
-- -> IO CDouble)).
mkFunPtrFromName :: Name -> ExpQ
-- | $(peekFunPtr [t| CDouble -> IO
-- CDouble |]) generates a foreign import dynamic of type
--
--
-- FunPtr (CDouble -> IO CDouble) -> (CDouble -> IO CDouble)
--
--
-- And invokes it.
peekFunPtr :: TypeQ -> ExpQ
instance (Storable a, Storable b, Storable c, Storable d, Storable e, Storable f, Storable g) => WithPtrs (a, b, c, d, e, f, g)
instance (Storable a, Storable b, Storable c, Storable d, Storable e, Storable f) => WithPtrs (a, b, c, d, e, f)
instance (Storable a, Storable b, Storable c, Storable d, Storable e) => WithPtrs (a, b, c, d, e)
instance (Storable a, Storable b, Storable c, Storable d) => WithPtrs (a, b, c, d)
instance (Storable a, Storable b, Storable c) => WithPtrs (a, b, c)
instance (Storable a, Storable b) => WithPtrs (a, b)