    -- |
    -- Module      :  Language.C.Quote.CUDA
    -- Copyright   :  (c) 2006-2011 Harvard University
    --                (c) 2011-2013 Geoffrey Mainland
    --             :  (c) 2013-2015 Drexel University
    -- License     :  BSD-style
    -- Maintainer  :  mainland@drexel.edu
    -- The quasiquoters exposed by this module support the CUDA extensions, including CUDA-specific declaration specifiers and @\<\<\<…>>>@ kernel invocation syntax.
    --
    -- It includees partial support for C++11 lambda expressions syntax.
    --
    -- Support for lambda-expressions has the following limitations:
    --
    --  * the capture list must either be empty or have only the default capture mode specifier;
    --
    --  * the return type cannot be explicitly specified;
    --
    --  * the package supports C language, not C++, therefore lambda parameter list and body must be in valid C syntax.
    --
    -- Examples of lambdas supported by the 'cexp' quasiquoter:
    --
    -- > [] (int i) mutable {}
    --
    -- > [&] { return 7; }
    --

    module Language.C.Quote.CUDA (
        ToIdent(..),
        ToConst(..),
        ToExp(..),
        cexp,
        cedecl,
        cdecl,
        csdecl,
        cenum,
        ctyquals,
        cty,
        cparam,
        cparams,
        cinit,
        cstm,
        cstms,
        citem,
        citems,
        cunit,
        cfun
      ) where

    import qualified Language.C.Parser as P
    import qualified Language.C.Syntax as C
    import Language.C.Quote.Base (ToIdent(..), ToConst(..), ToExp(..), quasiquote)
    import Language.Haskell.TH.Quote (QuasiQuoter)

    exts :: [C.Extensions]
    exts :: [Extensions]
    exts = [Extensions
    C.CUDA]

    typenames :: [String]
    typenames :: [String]
    typenames =
      (String -> [String]) -> [String] -> [String]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap (Int -> String -> [String]
    typeN Int
    4) [String
    "char", String
    "uchar", String
    "short", String
    "ushort",
                           String
    "int",  String
    "uint",  String
    "long",  String
    "ulong",
                           String
    "longlong", String
    "ulonglong",
                           String
    "float", String
    "double"] [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++
      [String
    "dim3"]

    typeN :: Int -> String -> [String]
    typeN :: Int -> String -> [String]
    typeN Int
    k String
    typename = [String
    typename String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Int -> String
    forall a. Show a => a -> String
    show Int
    n | Int
    n <- [Int
    1..Int
    k]]

    cdecl, cedecl, cenum, cexp, cfun, cinit, cparam, cparams, csdecl, cstm, cstms :: QuasiQuoter
    citem, citems, ctyquals, cty, cunit :: QuasiQuoter
    cdecl :: QuasiQuoter
    cdecl    = [Extensions] -> [String] -> P InitGroup -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P InitGroup
    P.parseDecl
    cedecl :: QuasiQuoter
    cedecl   = [Extensions] -> [String] -> P Definition -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P Definition
    P.parseEdecl
    cenum :: QuasiQuoter
    cenum    = [Extensions] -> [String] -> P CEnum -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P CEnum
    P.parseEnum
    cexp :: QuasiQuoter
    cexp     = [Extensions] -> [String] -> P Exp -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P Exp
    P.parseExp
    cfun :: QuasiQuoter
    cfun     = [Extensions] -> [String] -> P Func -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P Func
    P.parseFunc
    cinit :: QuasiQuoter
    cinit    = [Extensions] -> [String] -> P Initializer -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P Initializer
    P.parseInit
    cparam :: QuasiQuoter
    cparam   = [Extensions] -> [String] -> P Param -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P Param
    P.parseParam
    cparams :: QuasiQuoter
    cparams  = [Extensions] -> [String] -> P [Param] -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P [Param]
    P.parseParams
    csdecl :: QuasiQuoter
    csdecl   = [Extensions] -> [String] -> P FieldGroup -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P FieldGroup
    P.parseStructDecl
    cstm :: QuasiQuoter
    cstm     = [Extensions] -> [String] -> P Stm -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P Stm
    P.parseStm
    cstms :: QuasiQuoter
    cstms    = [Extensions] -> [String] -> P [Stm] -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P [Stm]
    P.parseStms
    citem :: QuasiQuoter
    citem    = [Extensions] -> [String] -> P BlockItem -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P BlockItem
    P.parseBlockItem
    citems :: QuasiQuoter
    citems   = [Extensions] -> [String] -> P [BlockItem] -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P [BlockItem]
    P.parseBlockItems
    ctyquals :: QuasiQuoter
    ctyquals = [Extensions] -> [String] -> P [TypeQual] -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P [TypeQual]
    P.parseTypeQuals
    cty :: QuasiQuoter
    cty      = [Extensions] -> [String] -> P Type -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P Type
    P.parseType
    cunit :: QuasiQuoter
    cunit    = [Extensions] -> [String] -> P [Definition] -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P [Definition]
    P.parseUnit