1
1
mirror of https://github.com/github/semantic.git synced 2024-12-20 05:11:44 +03:00

Merge branch 'master' into export-wrapper

This commit is contained in:
Timothy Clem 2018-03-16 08:38:57 -07:00 committed by GitHub
commit 3e5b9f8dbd
3 changed files with 51 additions and 6 deletions

View File

@ -48,6 +48,16 @@ class (Monad m, Show value) => MonadValue value m where
-- | Lift a Comparator (usually wrapping a function like == or <=) to a function on values. -- | Lift a Comparator (usually wrapping a function like == or <=) to a function on values.
liftComparison :: Comparator -> (value -> value -> m value) liftComparison :: Comparator -> (value -> value -> m value)
-- | Lift a unary bitwise operator to values. This is usually 'complement'.
liftBitwise :: (forall a . Bits a => a -> a)
-> (value -> m value)
-- | Lift a binary bitwise operator to values. The Integral constraint is
-- necessary to satisfy implementation details of Haskell left/right shift,
-- but it's fine, since these are only ever operating on integral values.
liftBitwise2 :: (forall a . (Integral a, Bits a) => a -> a -> a)
-> (value -> value -> m value)
-- | Construct an abstract boolean value. -- | Construct an abstract boolean value.
boolean :: Bool -> m value boolean :: Bool -> m value
@ -188,6 +198,15 @@ instance ( Monad m
pair = (left, right) pair = (left, right)
liftBitwise operator target
| Just (Value.Integer (Number.Integer i)) <- prjValue target = integer $ operator i
| otherwise = fail ("Type error: invalid unary bitwise operation on " <> show target)
liftBitwise2 operator left right
| Just (Value.Integer (Number.Integer i), Value.Integer (Number.Integer j)) <- prjPair pair = integer $ operator i j
| otherwise = fail ("Type error: invalid binary bitwise operation on " <> show pair)
where pair = (left, right)
abstract names (Subterm body _) = do abstract names (Subterm body _) = do
l <- label body l <- label body
injValue . Closure names l . bindEnv (foldr Set.delete (freeVariables body) names) <$> askLocalEnv injValue . Closure names l . bindEnv (foldr Set.delete (freeVariables body) names) <$> askLocalEnv
@ -236,6 +255,12 @@ instance (Alternative m, MonadEnvironment Type m, MonadFail m, MonadFresh m, Mon
(Int, Type.Float) -> pure Type.Float (Int, Type.Float) -> pure Type.Float
_ -> unify left right _ -> unify left right
liftBitwise _ Int = pure Int
liftBitwise _ t = fail ("Invalid type passed to unary bitwise operation: " <> show t)
liftBitwise2 _ Int Int = pure Int
liftBitwise2 _ t1 t2 = fail ("Invalid types passed to binary bitwise operation: " <> show (t1, t2))
liftComparison (Concrete _) left right = case (left, right) of liftComparison (Concrete _) left right = case (left, right) of
(Type.Float, Int) -> pure Bool (Type.Float, Int) -> pure Bool
(Int, Type.Float) -> pure Bool (Int, Type.Float) -> pure Bool

View File

@ -157,9 +157,18 @@ instance Eq1 Bitwise where liftEq = genericLiftEq
instance Ord1 Bitwise where liftCompare = genericLiftCompare instance Ord1 Bitwise where liftCompare = genericLiftCompare
instance Show1 Bitwise where liftShowsPrec = genericLiftShowsPrec instance Show1 Bitwise where liftShowsPrec = genericLiftShowsPrec
-- TODO: Implement Eval instance for Bitwise instance Evaluatable Bitwise where
instance Evaluatable Bitwise eval = traverse subtermValue >=> go where
genLShift x y = shiftL x (fromIntegral y)
genRShift x y = shiftR x (fromIntegral y)
go x = case x of
(BOr a b) -> liftBitwise2 (.|.) a b
(BAnd a b) -> liftBitwise2 (.&.) a b
(BXOr a b) -> liftBitwise2 xor a b
(LShift a b) -> liftBitwise2 genLShift a b
(RShift a b) -> liftBitwise2 genRShift a b
(UnsignedRShift a b) -> liftBitwise2 genRShift a b
(Complement a) -> liftBitwise complement a
-- | Member Access (e.g. a.b) -- | Member Access (e.g. a.b)
data MemberAccess a data MemberAccess a

View File

@ -1,11 +1,14 @@
{-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE UndecidableInstances #-}
module Prologue module Prologue
( module X ( module X
, foldMapA , foldMapA
) where , maybeM
, maybeFail
) where
import Data.Bifunctor.Join as X import Data.Bifunctor.Join as X
import Data.Bits as X
import Data.ByteString as X (ByteString) import Data.ByteString as X (ByteString)
import Data.Functor.Both as X (Both, runBothWith, both) import Data.Functor.Both as X (Both, runBothWith, both)
import Data.IntMap as X (IntMap) import Data.IntMap as X (IntMap)
@ -73,3 +76,11 @@ import GHC.Stack as X
-- | Fold a collection by mapping each element onto an 'Alternative' action. -- | Fold a collection by mapping each element onto an 'Alternative' action.
foldMapA :: (Alternative m, Foldable t) => (b -> m a) -> t b -> m a foldMapA :: (Alternative m, Foldable t) => (b -> m a) -> t b -> m a
foldMapA f = getAlt . foldMap (Alt . f) foldMapA f = getAlt . foldMap (Alt . f)
-- | Extract the 'Just' of a 'Maybe' in an 'Applicative' context or, given 'Nothing', run the provided action.
maybeM :: Applicative f => f a -> Maybe a -> f a
maybeM f = maybe f pure
-- | Either extract the 'Just' of a 'Maybe' or invoke 'fail' with the provided string.
maybeFail :: MonadFail m => String -> Maybe a -> m a
maybeFail s = maybeM (X.fail s)