2019-07-29 20:19:51 +03:00
|
|
|
{-# LANGUAGE FlexibleContexts, ScopedTypeVariables #-}
|
2019-06-04 18:26:42 +03:00
|
|
|
|
|
|
|
module Generators
|
|
|
|
( literal
|
|
|
|
, name
|
|
|
|
, variable
|
|
|
|
, boolean
|
|
|
|
, lambda
|
2019-07-22 22:26:02 +03:00
|
|
|
, record
|
2019-06-04 18:26:42 +03:00
|
|
|
, apply
|
|
|
|
, ifthenelse
|
2019-07-22 22:42:08 +03:00
|
|
|
, expr
|
2019-06-04 18:26:42 +03:00
|
|
|
) where
|
|
|
|
|
|
|
|
import Hedgehog hiding (Var)
|
|
|
|
import qualified Hedgehog.Gen as Gen
|
|
|
|
import qualified Hedgehog.Range as Range
|
|
|
|
|
2019-07-29 20:19:51 +03:00
|
|
|
import Control.Effect.Carrier
|
2019-10-10 22:07:49 +03:00
|
|
|
import qualified Core.Core as Core
|
|
|
|
import Core.Name
|
2019-06-04 18:26:42 +03:00
|
|
|
|
|
|
|
-- 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.
|
2019-08-06 18:18:54 +03:00
|
|
|
name :: MonadGen m => m (Named Name)
|
2019-07-22 22:33:47 +03:00
|
|
|
name = Gen.prune (named' <$> names) where
|
2019-10-08 00:08:07 +03:00
|
|
|
names = Name <$> Gen.text (Range.linear 1 10) Gen.lower
|
2019-06-04 18:26:42 +03:00
|
|
|
|
2019-08-06 18:18:54 +03:00
|
|
|
boolean :: (Carrier sig t, Member Core.Core sig, MonadGen m) => m (t Name)
|
2019-07-22 22:13:14 +03:00
|
|
|
boolean = Core.bool <$> Gen.bool
|
2019-06-04 18:26:42 +03:00
|
|
|
|
2019-10-11 16:13:30 +03:00
|
|
|
variable :: (Applicative t, MonadGen m) => m (t Name)
|
2019-07-17 19:44:27 +03:00
|
|
|
variable = pure . namedValue <$> name
|
2019-06-04 18:26:42 +03:00
|
|
|
|
2019-08-06 18:18:54 +03:00
|
|
|
ifthenelse :: (Carrier sig t, Member Core.Core sig, MonadGen m) => m (t Name) -> m (t Name)
|
2019-07-22 22:13:14 +03:00
|
|
|
ifthenelse bod = Gen.subterm3 boolean bod bod Core.if'
|
2019-06-04 18:26:42 +03:00
|
|
|
|
2019-08-06 18:18:54 +03:00
|
|
|
apply :: (Carrier sig t, Member Core.Core sig, MonadGen m) => m (t Name) -> m (t Name)
|
2019-06-04 18:26:42 +03:00
|
|
|
apply gen = go where
|
|
|
|
go = Gen.recursive
|
|
|
|
Gen.choice
|
2019-07-22 22:13:14 +03:00
|
|
|
[ Gen.subterm2 gen gen (Core.$$)]
|
|
|
|
[ Gen.subterm2 go go (Core.$$) -- balanced
|
|
|
|
, Gen.subtermM go (\x -> Core.lam <$> name <*> pure x)
|
2019-06-04 18:26:42 +03:00
|
|
|
]
|
|
|
|
|
2019-08-06 18:18:54 +03:00
|
|
|
lambda :: (Carrier sig t, Member Core.Core sig, MonadGen m) => m (t Name) -> m (t Name)
|
2019-06-04 18:26:42 +03:00
|
|
|
lambda bod = do
|
|
|
|
arg <- name
|
2019-07-22 22:13:14 +03:00
|
|
|
Gen.subterm bod (Core.lam arg)
|
2019-06-04 18:26:42 +03:00
|
|
|
|
2019-08-06 18:18:54 +03:00
|
|
|
record :: (Carrier sig t, Member Core.Core sig, MonadGen m) => m (t Name) -> m (t Name)
|
2019-07-22 22:26:02 +03:00
|
|
|
record bod = Core.record <$> Gen.list (Range.linear 0 5) ((,) . namedValue <$> name <*> bod)
|
|
|
|
|
2019-08-06 18:18:54 +03:00
|
|
|
atoms :: (Carrier sig t, Member Core.Core sig, MonadGen m) => [m (t Name)]
|
2019-07-23 22:43:11 +03:00
|
|
|
atoms = [variable, pure Core.unit, boolean, Core.string <$> Gen.text (Range.linear 1 10) Gen.lower]
|
2019-06-04 18:26:42 +03:00
|
|
|
|
2019-08-06 18:18:54 +03:00
|
|
|
literal :: (Carrier sig t, Member Core.Core sig, MonadGen m) => m (t Name)
|
2019-07-22 22:26:02 +03:00
|
|
|
literal = Gen.recursive Gen.choice atoms [lambda literal, record literal]
|
2019-07-22 22:42:08 +03:00
|
|
|
|
2019-08-06 18:18:54 +03:00
|
|
|
expr :: (Carrier sig t, Member Core.Core sig, MonadGen m) => m (t Name)
|
2019-07-22 22:42:08 +03:00
|
|
|
expr = Gen.recursive Gen.choice atoms
|
2019-07-23 22:18:04 +03:00
|
|
|
[ Gen.subtermM expr (\x -> flip Core.rec x <$> name)
|
2019-07-23 22:22:12 +03:00
|
|
|
, Gen.subterm2 expr expr (Core.>>>)
|
|
|
|
, Gen.subtermM2 expr expr (\ x y -> (Core.>>>= y) . (Core.:<- x) <$> name)
|
2019-07-23 22:18:04 +03:00
|
|
|
, lambda expr
|
2019-07-22 22:42:08 +03:00
|
|
|
, Gen.subterm2 expr expr (Core.$$)
|
|
|
|
, Gen.subterm3 expr expr expr Core.if'
|
2019-07-23 22:23:26 +03:00
|
|
|
, Gen.subterm expr Core.load
|
2019-07-23 22:22:12 +03:00
|
|
|
, record expr
|
2019-07-22 22:42:08 +03:00
|
|
|
, Gen.subtermM expr (\ x -> (x Core....) . namedValue <$> name)
|
2019-10-23 19:24:26 +03:00
|
|
|
, Gen.subtermM expr (\ x -> (x Core..?) . namedValue <$> name)
|
2019-07-23 22:15:55 +03:00
|
|
|
, Gen.subterm2 expr expr (Core..=)
|
2019-07-22 22:42:08 +03:00
|
|
|
]
|