1
1
mirror of https://github.com/github/semantic.git synced 2024-11-25 11:04:00 +03:00
semantic/semantic-core/test/Generators.hs
2019-06-25 14:21:36 -04:00

57 lines
1.3 KiB
Haskell

{-# LANGUAGE ScopedTypeVariables #-}
module Generators
( literal
, name
, variable
, boolean
, lambda
, apply
, ifthenelse
) where
import Prelude hiding (span)
import Hedgehog hiding (Var)
import qualified Hedgehog.Gen as Gen
import qualified Hedgehog.Range as Range
import Data.Core
import Data.Name
-- The 'prune' call here ensures that we don't spend all our time just generating
-- fresh names for variables, since the length of variable names is not an
-- interesting property as they parse regardless.
name :: MonadGen m => m Name
name = Gen.prune (User <$> names) where
names = Gen.text (Range.linear 1 10) Gen.lower
boolean :: MonadGen m => m Core
boolean = Bool <$> Gen.bool
variable :: MonadGen m => m Core
variable = Var <$> name
ifthenelse :: MonadGen m => m Core -> m Core
ifthenelse bod = Gen.subterm3 boolean bod bod If
apply :: MonadGen m => m Core -> m Core
apply gen = go where
go = Gen.recursive
Gen.choice
[ Gen.subterm2 gen gen (:$)]
[ Gen.subterm2 go go (:$) -- balanced
, Gen.subtermM go (\x -> Lam <$> name <*> pure x)
]
lambda :: MonadGen m => m Core -> m Core
lambda bod = do
arg <- name
Gen.subterm bod (Lam arg)
atoms :: MonadGen m => [m Core]
atoms = [boolean, variable, pure Unit, pure Frame]
literal :: MonadGen m => m Core
literal = Gen.recursive Gen.choice atoms [lambda literal]