inline-c-0.5.5.3: Write Haskell source files including C code inline. No FFI required.

Language.C.Inline.Context

Description

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.

Synopsis

# TypesTable

A mapping from TypeSpecifiers to Haskell types. Needed both to parse C types, and to convert them to Haskell types.

data Purity Source #

A data type to indicate whether the user requested pure or IO function from Haskell

Constructors

 Pure IO

Instances

 Source # Methods(==) :: Purity -> Purity -> Bool #(/=) :: Purity -> Purity -> Bool # Source # MethodsshowsPrec :: Int -> Purity -> ShowS #showList :: [Purity] -> ShowS #

Given a Context, it uses its ctxTypesTable to convert arbitrary C types.

type CArray = Ptr Source #

An alias for Ptr.

# AntiQuoter

data AntiQuoter a Source #

Constructors

 AntiQuoter FieldsaqParser :: forall m. CParser HaskellIdentifier m => m (CIdentifier, Type CIdentifier, 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.aqMarshaller :: Purity -> TypesTable -> Type CIdentifier -> a -> Q (Type, Exp)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.

An identifier for a AntiQuoter.

Existential wrapper around AntiQuoter.

Constructors

 (Eq a, Typeable a) => SomeAntiQuoter (AntiQuoter a)

# Context

data Context Source #

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.

Constructors

 Context FieldsctxTypesTable :: TypesTableNeeded to convert C types to Haskell types.ctxAntiQuoters :: AntiQuotersNeeded to parse and process antiquotations.ctxFileExtension :: Maybe StringWill determine the extension of the file containing the inline C snippets.ctxOutput :: Maybe (String -> 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.

Instances

 Source # Methodsmconcat :: [Context] -> 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.

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. 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.

class VecCtx a where Source #

Type class used to implement the anti-quoters in vecCtx.

Minimal complete definition

Associated Types

type VecCtxScalar a :: * Source #

Methods

vecCtxLength :: a -> Int Source #

vecCtxUnsafeWith :: a -> (Ptr (VecCtxScalar a) -> IO b) -> IO b Source #

Instances

 Storable a => VecCtx (Vector a) Source # Associated Typestype VecCtxScalar (Vector a) :: * Source # MethodsvecCtxUnsafeWith :: Vector a -> (Ptr (VecCtxScalar (Vector a)) -> IO b) -> IO b Source # Storable a => VecCtx (IOVector a) Source # Associated Typestype VecCtxScalar (IOVector a) :: * Source # MethodsvecCtxUnsafeWith :: IOVector a -> (Ptr (VecCtxScalar (IOVector a)) -> IO b) -> IO b Source #

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*.