content: {-# LANGUAGE QuasiQuotes #-}
  
  module CUDA (cudaTests) where
  
  import Test.Framework
  import Test.Framework.Providers.HUnit
  import Test.HUnit (Assertion, (@?=))
  
  import Language.C.Quote.CUDA
  import Language.C.Syntax
  import Data.Loc (noLoc)
  
  mkDeclarator :: [Param] -> Bool -> LambdaDeclarator
  mkDeclarator params mutability = LambdaDeclarator (Params params False noLoc) mutability Nothing noLoc
  
  mkIntroducer :: [CaptureListEntry] -> LambdaIntroducer
  mkIntroducer mode = (LambdaIntroducer mode noLoc)
  
  emptyLambda :: Exp
  emptyLambda = lambdaByCapture []
  
  lambdaByCapture :: [CaptureListEntry] -> Exp
  lambdaByCapture captureMode = Lambda (mkIntroducer captureMode) Nothing [] noLoc
  
  lambdaByCaptureBody :: [CaptureListEntry] -> [BlockItem] -> Exp
  lambdaByCaptureBody captureMode statements = Lambda (mkIntroducer captureMode) Nothing statements noLoc
  
  lambdaByCaptureParams :: [CaptureListEntry] -> [Param] -> Exp
  lambdaByCaptureParams captureMode params = Lambda (mkIntroducer captureMode) (Just $ mkDeclarator params False) [] noLoc
  
  lambdaByParams :: [Param] -> Exp
  lambdaByParams params = Lambda (mkIntroducer []) (Just $ mkDeclarator params False) [] noLoc
  
  mutableLambdaByParams :: [Param] -> Exp
  mutableLambdaByParams params = Lambda (mkIntroducer []) (Just $ mkDeclarator params True) [] noLoc
  
  cudaTests :: Test
  cudaTests = testGroup "CUDA"
      $ map (testCase "lambda-expressions parsing") lambdas
    where
      lambdas :: [Assertion]
      lambdas = [ [cexp|[=] {}|] @?= lambdaByCapture [DefaultByValue]
                , [cexp|[&] {}|] @?= lambdaByCapture[DefaultByReference]
                , [cexp|[] {}|] @?= lambdaByCapture []
                , [cexp|[] {}|] @?= emptyLambda
                , [cexp|[] () {}|] @?= lambdaByParams []
                , [cexp|[] (int i) {}|] @?= lambdaByParams [param_int_i]
                , [cexp|[] (int i, double j) {}|] @?= lambdaByParams [param_int_i, param_double_h]
                , [cexp|[] ($param:param_int_i) {}|] @?= lambdaByParams [param_int_i]
                , [cexp|[] (int i) mutable {}|] @?= mutableLambdaByParams [param_int_i]
                , [cexp|[&] (int i) {}|] @?= lambdaByCaptureParams [DefaultByReference] [param_int_i]
                , [cexp|[&] { $item:item_return_7 } |] @?= lambdaCapturingByRefAndReturning7
                , [cexp|[&] { return $exp:exp_7; } |] @?= lambdaCapturingByRefAndReturning7
                , [cexp|[]{}()|] @?= FnCall emptyLambda [] noLoc
                , [cexp|[](){}()|] @?= FnCall (lambdaByParams []) [] noLoc
                ]
  
      lambdaCapturingByRefAndReturning7 = lambdaByCaptureBody [DefaultByReference] [item_return_7]
      exp_7 = [cexp|7|]
      item_return_7 = [citem|return 7;|]
      param_int_i = [cparam|int i|]
      param_double_h = [cparam|double j|]
  