1
1
mirror of https://github.com/github/semantic.git synced 2024-12-18 12:21:57 +03:00
semantic/semantic-core/test/Generators.hs

78 lines
2.6 KiB
Haskell
Raw Normal View History

2020-01-18 00:10:29 +03:00
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE 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
, expr
2019-06-04 18:26:42 +03:00
) where
2019-12-11 23:44:50 +03:00
import Hedgehog hiding (Var)
2019-06-04 18:26:42 +03:00
import qualified Hedgehog.Gen as Gen
import qualified Hedgehog.Range as Range
2019-12-11 23:44:50 +03:00
import Control.Algebra
import qualified Core.Core as Core
2020-01-18 00:10:29 +03:00
import Core.Name (Name, Named)
import qualified Core.Name as 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)
2020-01-18 00:10:29 +03:00
name = Gen.prune (Name.named' <$> names) where
names = Name.name <$> Gen.text (Range.linear 1 10) Gen.lower
2019-06-04 18:26:42 +03:00
2019-12-11 23:44:50 +03:00
boolean :: (Has Core.Core sig t, 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
variable :: (Applicative t, MonadGen m) => m (t Name)
2020-01-18 00:10:29 +03:00
variable = pure . Name.namedValue <$> name
2019-06-04 18:26:42 +03:00
2019-12-11 23:44:50 +03:00
ifthenelse :: (Has Core.Core sig t, 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-12-11 23:44:50 +03:00
apply :: (Has Core.Core sig t, 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-12-11 23:44:50 +03:00
lambda :: (Has Core.Core sig t, 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-12-11 23:44:50 +03:00
record :: (Has Core.Core sig t, MonadGen m) => m (t Name) -> m (t Name)
2020-01-18 00:10:29 +03:00
record bod = Core.record <$> Gen.list (Range.linear 0 5) ((,) . Name.namedValue <$> name <*> bod)
2019-07-22 22:26:02 +03:00
2019-12-11 23:44:50 +03:00
atoms :: (Has Core.Core sig t, 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-12-11 23:44:50 +03:00
literal :: (Has Core.Core sig t, MonadGen m) => m (t Name)
2019-07-22 22:26:02 +03:00
literal = Gen.recursive Gen.choice atoms [lambda literal, record literal]
2019-12-11 23:44:50 +03:00
expr :: (Has Core.Core sig t, MonadGen m) => m (t Name)
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
, 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
2020-01-18 00:10:29 +03:00
, Gen.subtermM expr (\ x -> (x Core....) . Name.namedValue <$> name)
, Gen.subtermM expr (\ x -> (x Core..?) . Name.namedValue <$> name)
2019-07-23 22:15:55 +03:00
, Gen.subterm2 expr expr (Core..=)
]