{-# OPTIONS_GHC -fno-warn-orphans #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE FlexibleInstances #-} module QC where import Ivory.Compile.C.CmdlineFrontend import Ivory.Language import Ivory.QuickCheck import Test.QuickCheck.Arbitrary [ivory| struct foo { foo_a :: Stored IFloat ; foo_b :: Stored Uint8 } |] -- Function we want to generate inputs for. func :: Def ('[Uint8 , Ref s (Array 3 (Stored Uint8)) , Ref s (Struct "foo") ] :-> ()) func = proc "func" $ \u arr str -> body $ arrayMap $ \ix -> do a <- deref (arr ! ix) b <- deref (str ~> foo_b) store (arr ! ix) (a + b + u) type DriverDef = Def ('[] :-> ()) -- Driver function. Takes lists of the arguments we'll pass to the function -- test. driver :: [Uint8] -> [Init (Array 3 (Stored Uint8))] -> [Init (Struct "foo")] -> DriverDef driver as0 as1 as2 = proc "main" $ body $ do mapM_ oneCall (zip3 as0 as1 as2) where oneCall (a0, a1, a2) = do a1' <- local a1 a2' <- local a2 call_ func a0 a1' a2' -- Generate the random values to pass. runTest :: IvoryGen DriverDef runTest = do args0 <- samples num arbitrary args1 <- samples num arbitrary aFoos <- samples num foo_a bFoos <- samples num foo_b return $ driver args0 args1 (zipWith foo aFoos bFoos) where foo a b = istruct [ a, b ] num = 10 -- Compile! runTests :: IO () runTests = do d <- runIO runTest runCompiler [cmodule d] initialOpts { includeDir = "test" , srcDir = "test" , constFold = True } where cmodule d = package "qc" $ do incl d incl func