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