@@ -0,0 +1,75 @@
1+{-# OPTIONS_GHC -fno-warn-orphans #-}
2+module Tests.Property.Arbitrary where
4+import Control.Applicative ((<$>), (<*>), pure)
5+import Test.QuickCheck.Arbitrary
6+import Test.QuickCheck.Gen
8+import qualified Data.Set as Set
9+import qualified Parse.Helpers (reserveds)
11+import SourceSyntax.Literal
12+import SourceSyntax.Pattern
14+instance Arbitrary Literal where
15+ arbitrary = oneof [ IntNum <$> arbitrary
16+ , FloatNum <$> (arbitrary `suchThat` noE)
18+ -- This is too permissive
20+ -- Booleans aren't actually source syntax
21+ -- , Boolean <$> arbitrary
24+ IntNum n -> IntNum <$> shrink n
25+ FloatNum f -> FloatNum <$> (filter noE . shrink $ f)
26+ Chr c -> Chr <$> shrink c
27+ Str s -> Str <$> shrink s
28+ Boolean b -> Boolean <$> shrink b
31+noE = notElem 'e' . show
34+instance Arbitrary Pattern where
35+ arbitrary = sized pat
36+ where pat :: Int -> Gen Pattern
37+ pat n = oneof [ pure PAnything
39+ , PRecord <$> (listOf1 lowVar)
40+ , PLiteral <$> arbitrary
41+ , PAlias <$> lowVar <*> pat (n-1)
42+ , PData <$> capVar <*> sizedPats
46+ let m = n `div` len in
49+ shrink pat = case pat of
51+ PVar v -> PVar <$> shrinkWHead v
52+ PRecord fs -> PRecord <$> (filter (all $ not . null) . filter (not . null) $ shrink fs)
53+ PLiteral l -> PLiteral <$> shrink l
54+ PAlias s p -> p : (PAlias <$> shrinkWHead s <*> shrink p)
55+ PData s ps -> ps ++ (PData <$> shrinkWHead s <*> shrink ps)
56+ where shrinkWHead (x:xs) = (x:) <$> shrink xs
59+lowVar = notReserved $ (:) <$> lower <*> listOf varLetter
60+ where lower = elements ['a'..'z']
63+capVar = notReserved $ (:) <$> upper <*> listOf varLetter
64+ where upper = elements ['A'..'Z']
67+varLetter = elements $ ['a'..'z'] ++ ['A'..'Z'] ++ ['0'..'9'] ++ ['\'', '_']
69+notReserved :: Gen String -> Gen String
70+notReserved = flip exceptFor Parse.Helpers.reserveds
72+exceptFor :: (Ord a) => Gen a -> [a] -> Gen a
73+exceptFor g xs = g `suchThat` notAnX
74+ where notAnX = flip Set.notMember xset
75+ xset = Set.fromList xs