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

Safe Haskell | None
Language | Haskell2010

Language.C.Inline.Internal

Contents

- Context handling
- Substitution
- Emitting and invoking C code
  - Emitting C code
  - Inlining C code
- Parsing
- Line directives
- Utility functions for writing quasiquoters

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
  - = Plain HaskellIdentifier
  - | AntiQuote AntiQuoterId SomeEq
- data ParseTypedC = ParseTypedC {
  - ptcReturnType :: Type CIdentifier
  - ptcParameters :: [(CIdentifier, Type CIdentifier, ParameterType)]
  - ptcBody :: String
  }
- parseTypedC :: CParser HaskellIdentifier m => Bool -> AntiQuoters -> m ParseTypedC
- runParserInQ :: Hashable ident => String -> CParserContext ident -> (forall (m :: Type -> Type). 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 #

Constructors

Substitutions |

Fields

- unSubstitutions :: Map String (String -> String)

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 Code Source #

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.

Constructors

Code |

Fields

- codeCallSafety :: Safety

  Safety of the foreign call.

- codeLoc :: Maybe Loc

  The haskell source location used for the #line directive

- codeType :: TypeQ

  Type of the foreign call.

- codeFunName :: String

  Name of the function to call in the code below.

- codeDefs :: String

  The C code.

- codeFunPtr :: Bool

  If `True`, the type will be wrapped in `FunPtr`, and the call will be static (e.g. prefixed by &).

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; }")

inlineExp Source #

Arguments

:: 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)")

inlineItems Source #

Arguments

:: 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 SomeEq Source #

#### Instances

Instances details

Show SomeEq Source # |
Instance details Defined in Language.C.Inline.Internal Methods showsPrec :: Int -> SomeEq -> ShowS Source # show :: SomeEq -> String Source # showList :: [SomeEq] -> ShowS Source #
Eq SomeEq Source # |
Instance details Defined in Language.C.Inline.Internal Methods (==) :: SomeEq -> SomeEq -> Bool Source # (/=) :: SomeEq -> SomeEq -> Bool Source #

toSomeEq :: (Eq a, Typeable a) => a -> SomeEq Source #

fromSomeEq :: (Eq a, Typeable a) => SomeEq -> Maybe a Source #

data ParameterType Source #

Constructors

Plain HaskellIdentifier |
AntiQuote AntiQuoterId SomeEq |

#### Instances

Instances details

Show ParameterType Source # |
Instance details Defined in Language.C.Inline.Internal Methods showsPrec :: Int -> ParameterType -> ShowS Source # show :: ParameterType -> String Source # showList :: [ParameterType] -> ShowS Source #
Eq ParameterType Source # |
Instance details Defined in Language.C.Inline.Internal Methods (==) :: ParameterType -> ParameterType -> Bool Source # (/=) :: ParameterType -> ParameterType -> Bool Source #

data ParseTypedC Source #

Constructors

ParseTypedC |

Fields

- ptcReturnType :: Type CIdentifier
- ptcParameters :: [(CIdentifier, Type CIdentifier, ParameterType)]
- ptcBody :: String

parseTypedC Source #

Arguments

:: 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 :: Type -> Type). CParser ident m => m a) -> Q a Source #

splitTypedC :: String -> (String, String, Int) Source #

Returns the type and the body separately.

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

here :: ExpQ Source #

Get the location of the code you're looking at, for use with `lineDirective`; place before generated code that user did not write.

shiftLines :: Int -> Loc -> Loc Source #

# Utility functions for writing quasiquoters

genericQuote Source #

Arguments

:: Purity |
-> (Loc -> TypeQ -> Type CIdentifier -> [(CIdentifier, Type CIdentifier)] -> String -> ExpQ) | Function building an Haskell expression, see `inlineExp` for guidance on the other args.
-> QuasiQuoter |

funPtrQuote :: Safety -> QuasiQuoter Source #