1
1
mirror of https://github.com/github/semantic.git synced 2024-11-24 08:54:07 +03:00

Rename Store to Heap.

This commit is contained in:
Rob Rix 2018-03-14 20:42:59 -04:00
parent f68da42754
commit fcf44b5a37
16 changed files with 123 additions and 123 deletions

View File

@ -47,10 +47,10 @@ library
, Data.Abstract.Environment
, Data.Abstract.Evaluatable
, Data.Abstract.FreeVariables
, Data.Abstract.Heap
, Data.Abstract.Live
, Data.Abstract.ModuleTable
, Data.Abstract.Number
, Data.Abstract.Store
, Data.Abstract.Type
, Data.Abstract.Value
-- General datatype definitions & generic algorithms

View File

@ -6,7 +6,7 @@ module Analysis.Abstract.Caching
import Control.Abstract.Analysis
import Data.Abstract.Cache
import Data.Abstract.Configuration
import Data.Abstract.Store
import Data.Abstract.Heap
import Data.Abstract.Value
import Data.Monoid (Alt (..))
import Prologue
@ -28,21 +28,21 @@ newtype Caching m term value (effects :: [* -> *]) a = Caching (m term value eff
deriving instance MonadControl term (m term value effects) => MonadControl term (Caching m term value effects)
deriving instance MonadEnvironment value (m term value effects) => MonadEnvironment value (Caching m term value effects)
deriving instance MonadStore value (m term value effects) => MonadStore value (Caching m term value effects)
deriving instance MonadHeap value (m term value effects) => MonadHeap value (Caching m term value effects)
deriving instance MonadModuleTable term value (m term value effects) => MonadModuleTable term value (Caching m term value effects)
deriving instance MonadEvaluator term value (m term value effects) => MonadEvaluator term value (Caching m term value effects)
-- | Functionality used to perform caching analysis. This is not exported, and exists primarily for organizational reasons.
class MonadEvaluator term value m => MonadCaching term value m where
-- | Look up the set of values for a given configuration in the in-cache.
consultOracle :: ConfigurationFor term value -> m (Set (value, StoreFor value))
consultOracle :: ConfigurationFor term value -> m (Set (value, HeapFor value))
-- | Run an action with the given in-cache.
withOracle :: CacheFor term value -> m a -> m a
-- | Look up the set of values for a given configuration in the out-cache.
lookupCache :: ConfigurationFor term value -> m (Maybe (Set (value, StoreFor value)))
-- | Run an action, caching its result and 'Store' under the given configuration.
caching :: ConfigurationFor term value -> Set (value, StoreFor value) -> m value -> m value
lookupCache :: ConfigurationFor term value -> m (Maybe (Set (value, HeapFor value)))
-- | Run an action, caching its result and 'Heap' under the given configuration.
caching :: ConfigurationFor term value -> Set (value, HeapFor value) -> m value -> m value
-- | Run an action starting from an empty out-cache, and return the out-cache afterwards.
isolateCache :: m a -> m (CacheFor term value)
@ -62,7 +62,7 @@ instance ( Effectful (m term value)
lookupCache configuration = raise (cacheLookup configuration <$> get)
caching configuration values action = do
raise (modify (cacheSet configuration values))
result <- (,) <$> action <*> getStore
result <- (,) <$> action <*> getHeap
raise (modify (cacheInsert configuration result))
pure (fst result)
@ -98,7 +98,7 @@ instance ( Corecursive term
c <- getConfiguration e
-- Convergence here is predicated upon an Eq instance, not α-equivalence
cache <- converge (\ prevCache -> isolateCache $ do
putStore (configurationStore c)
putHeap (configurationHeap c)
-- We need to reset fresh generation so that this invocation converges.
reset 0
-- This is subtle: though the calling context supports nondeterminism, we want
@ -125,5 +125,5 @@ converge f = loop
loop x'
-- | Nondeterministically write each of a collection of stores & return their associated results.
scatter :: (Alternative m, Foldable t, MonadEvaluator term value m) => t (a, Store (LocationFor value) value) -> m a
scatter = getAlt . foldMap (\ (value, store') -> Alt (putStore store' *> pure value))
scatter :: (Alternative m, Foldable t, MonadEvaluator term value m) => t (a, Heap (LocationFor value) value) -> m a
scatter = getAlt . foldMap (\ (value, heap') -> Alt (putHeap heap' *> pure value))

View File

@ -6,8 +6,8 @@ module Analysis.Abstract.Collecting
import Control.Abstract.Analysis
import Data.Abstract.Address
import Data.Abstract.Configuration
import Data.Abstract.Heap
import Data.Abstract.Live
import Data.Abstract.Store
import Data.Abstract.Value
import Prologue
@ -16,7 +16,7 @@ newtype Collecting m term value (effects :: [* -> *]) a = Collecting (m term val
deriving instance MonadControl term (m term value effects) => MonadControl term (Collecting m term value effects)
deriving instance MonadEnvironment value (m term value effects) => MonadEnvironment value (Collecting m term value effects)
deriving instance MonadStore value (m term value effects) => MonadStore value (Collecting m term value effects)
deriving instance MonadHeap value (m term value effects) => MonadHeap value (Collecting m term value effects)
deriving instance MonadModuleTable term value (m term value effects) => MonadModuleTable term value (Collecting m term value effects)
instance ( Effectful (m term value)
@ -24,7 +24,7 @@ instance ( Effectful (m term value)
, MonadEvaluator term value (m term value effects)
)
=> MonadEvaluator term value (Collecting m term value effects) where
getConfiguration term = Configuration term <$> askRoots <*> askLocalEnv <*> getStore
getConfiguration term = Configuration term <$> askRoots <*> askLocalEnv <*> getHeap
instance ( Effectful (m term value)
@ -43,7 +43,7 @@ instance ( Effectful (m term value)
analyzeTerm term = do
roots <- askRoots
v <- liftAnalyze analyzeTerm term
modifyStore (gc (roots <> valueRoots v))
modifyHeap (gc (roots <> valueRoots v))
pure v
@ -56,27 +56,27 @@ askRoots = raise ask
-- extraRoots roots = raise . local (<> roots) . lower
-- | Collect any addresses in the store not rooted in or reachable from the given 'Live' set.
-- | Collect any addresses in the heap not rooted in or reachable from the given 'Live' set.
gc :: ( Ord (LocationFor value)
, Foldable (Cell (LocationFor value))
, ValueRoots value
)
=> LiveFor value -- ^ The set of addresses to consider rooted.
-> StoreFor value -- ^ A store to collect unreachable addresses within.
-> StoreFor value -- ^ A garbage-collected store.
gc roots store = storeRestrict store (reachable roots store)
=> LiveFor value -- ^ The set of addresses to consider rooted.
-> HeapFor value -- ^ A heap to collect unreachable addresses within.
-> HeapFor value -- ^ A garbage-collected heap.
gc roots heap = heapRestrict heap (reachable roots heap)
-- | Compute the set of addresses reachable from a given root set in a given store.
-- | Compute the set of addresses reachable from a given root set in a given heap.
reachable :: ( Ord (LocationFor value)
, Foldable (Cell (LocationFor value))
, ValueRoots value
)
=> LiveFor value -- ^ The set of root addresses.
-> StoreFor value -- ^ The store to trace addresses through.
-> LiveFor value -- ^ The set of addresses reachable from the root set.
reachable roots store = go mempty roots
=> LiveFor value -- ^ The set of root addresses.
-> HeapFor value -- ^ The heap to trace addresses through.
-> LiveFor value -- ^ The set of addresses reachable from the root set.
reachable roots heap = go mempty roots
where go seen set = case liveSplit set of
Nothing -> seen
Just (a, as) -> go (liveInsert a seen) (case storeLookupAll a store of
Just (a, as) -> go (liveInsert a seen) (case heapLookupAll a heap of
Just values -> liveDifference (foldr ((<>) . valueRoots) mempty values <> as) seen
_ -> seen)

View File

@ -14,7 +14,7 @@ newtype DeadCode m term value (effects :: [* -> *]) a = DeadCode (m term value e
deriving instance MonadControl term (m term value effects) => MonadControl term (DeadCode m term value effects)
deriving instance MonadEnvironment value (m term value effects) => MonadEnvironment value (DeadCode m term value effects)
deriving instance MonadStore value (m term value effects) => MonadStore value (DeadCode m term value effects)
deriving instance MonadHeap value (m term value effects) => MonadHeap value (DeadCode m term value effects)
deriving instance MonadModuleTable term value (m term value effects) => MonadModuleTable term value (DeadCode m term value effects)
deriving instance MonadEvaluator term value (m term value effects) => MonadEvaluator term value (DeadCode m term value effects)

View File

@ -13,7 +13,7 @@ newtype Elaborating m term value (effects :: [* -> *]) a = Elaborating (m term v
deriving instance MonadControl term (m term value effects) => MonadControl term (Elaborating m term value effects)
deriving instance MonadEnvironment value (m term value effects) => MonadEnvironment value (Elaborating m term value effects)
deriving instance MonadStore value (m term value effects) => MonadStore value (Elaborating m term value effects)
deriving instance MonadHeap value (m term value effects) => MonadHeap value (Elaborating m term value effects)
deriving instance MonadModuleTable term value (m term value effects) => MonadModuleTable term value (Elaborating m term value effects)
deriving instance MonadEvaluator term value (m term value effects) => MonadEvaluator term value (Elaborating m term value effects)

View File

@ -81,7 +81,7 @@ type EvaluatingEffects term value
= '[ Fail -- Failure with an error message
, Reader (EnvironmentFor value) -- Local environment (e.g. binding over a closure)
, State (EnvironmentFor value) -- Global (imperative) environment
, State (StoreFor value) -- The heap
, State (HeapFor value) -- The heap
, Reader (ModuleTable [term]) -- Cache of unevaluated modules
, State (ModuleTable (EnvironmentFor value)) -- Cache of evaluated modules
@ -110,9 +110,9 @@ instance Members '[State (Map Name (Name, Maybe (Address (LocationFor value) val
askLocalEnv = raise ask
localEnv f a = raise (local f (lower a))
instance Member (State (StoreFor value)) effects => MonadStore value (Evaluating term value effects) where
getStore = raise get
putStore = raise . put
instance Member (State (HeapFor value)) effects => MonadHeap value (Evaluating term value effects) where
getHeap = raise get
putHeap = raise . put
instance Members '[Reader (ModuleTable [term]), State (ModuleTable (EnvironmentFor value))] effects => MonadModuleTable term value (Evaluating term value effects) where
getModuleTable = raise get
@ -122,7 +122,7 @@ instance Members '[Reader (ModuleTable [term]), State (ModuleTable (EnvironmentF
localModuleTable f a = raise (local f (lower a))
instance Members (EvaluatingEffects term value) effects => MonadEvaluator term value (Evaluating term value effects) where
getConfiguration term = Configuration term mempty <$> askLocalEnv <*> getStore
getConfiguration term = Configuration term mempty <$> askLocalEnv <*> getHeap
instance ( Evaluatable (Base term)
, FreeVariables term

View File

@ -19,7 +19,7 @@ newtype Tracing (trace :: * -> *) m term value (effects :: [* -> *]) a = Tracing
deriving instance MonadControl term (m term value effects) => MonadControl term (Tracing trace m term value effects)
deriving instance MonadEnvironment value (m term value effects) => MonadEnvironment value (Tracing trace m term value effects)
deriving instance MonadStore value (m term value effects) => MonadStore value (Tracing trace m term value effects)
deriving instance MonadHeap value (m term value effects) => MonadHeap value (Tracing trace m term value effects)
deriving instance MonadModuleTable term value (m term value effects) => MonadModuleTable term value (Tracing trace m term value effects)
deriving instance MonadEvaluator term value (m term value effects) => MonadEvaluator term value (Tracing trace m term value effects)

View File

@ -7,14 +7,14 @@ import Control.Monad ((<=<))
import Data.Abstract.Address
import Data.Abstract.Environment
import Data.Abstract.FreeVariables
import Data.Abstract.Store
import Data.Abstract.Heap
import Data.Abstract.Value
import Data.Foldable (asum, toList)
import Data.Semigroup
import Data.Semigroup.Reducer
import Prelude hiding (fail)
-- | Defines 'alloc'ation and 'deref'erencing of 'Address'es in a Store.
-- | Defines 'alloc'ation and 'deref'erencing of 'Address'es in a Heap.
class (Monad m, Ord l, l ~ LocationFor value, Reducer value (Cell l value)) => MonadAddressable l value m where
deref :: Address l value -> m value
@ -25,7 +25,7 @@ class (Monad m, Ord l, l ~ LocationFor value, Reducer value (Cell l value)) => M
-- The term is expected to contain one and only one free 'Name', meaning that care should be taken to apply this only to e.g. identifiers.
lookupOrAlloc :: ( FreeVariables term
, MonadAddressable (LocationFor value) value m
, MonadStore value m
, MonadHeap value m
, Semigroup (CellFor value)
)
=> term
@ -38,7 +38,7 @@ lookupOrAlloc term = let [name] = toList (freeVariables term) in
-- | Look up or allocate an address for a 'Name' & assign it a given value, returning the 'Name' paired with the address.
lookupOrAlloc' :: ( Semigroup (CellFor value)
, MonadAddressable (LocationFor value) value m
, MonadStore value m
, MonadHeap value m
)
=> Name
-> value
@ -52,7 +52,7 @@ lookupOrAlloc' name v env = do
letrec :: ( MonadAddressable (LocationFor value) value m
, MonadEnvironment value m
, MonadStore value m
, MonadHeap value m
)
=> Name
-> m value
@ -67,18 +67,18 @@ letrec name body = do
-- Instances
-- | 'Precise' locations are always 'alloc'ated a fresh 'Address', and 'deref'erence to the 'Latest' value written.
instance (MonadFail m, LocationFor value ~ Precise, MonadStore value m) => MonadAddressable Precise value m where
deref = maybe uninitializedAddress (pure . unLatest) <=< flip fmap getStore . storeLookup
instance (MonadFail m, LocationFor value ~ Precise, MonadHeap value m) => MonadAddressable Precise value m where
deref = maybe uninitializedAddress (pure . unLatest) <=< flip fmap getHeap . heapLookup
where
-- | Fail with a message denoting an uninitialized address (i.e. one which was 'alloc'ated, but never 'assign'ed a value before being 'deref'erenced).
uninitializedAddress :: MonadFail m => m a
uninitializedAddress = fail "uninitialized address"
alloc _ = fmap (Address . Precise . storeSize) getStore
alloc _ = fmap (Address . Precise . heapSize) getHeap
-- | 'Monovariant' locations 'alloc'ate one 'Address' per unique variable name, and 'deref'erence once per stored value, nondeterministically.
instance (Alternative m, LocationFor value ~ Monovariant, MonadStore value m, Ord value) => MonadAddressable Monovariant value m where
deref = asum . maybe [] (map pure . toList) <=< flip fmap getStore . storeLookup
instance (Alternative m, LocationFor value ~ Monovariant, MonadHeap value m, Ord value) => MonadAddressable Monovariant value m where
deref = asum . maybe [] (map pure . toList) <=< flip fmap getHeap . heapLookup
alloc = pure . Address . Monovariant

View File

@ -3,8 +3,8 @@ module Control.Abstract.Evaluator
( MonadEvaluator(..)
, MonadEnvironment(..)
, modifyGlobalEnv
, MonadStore(..)
, modifyStore
, MonadHeap(..)
, modifyHeap
, assign
, MonadModuleTable(..)
, modifyModuleTable
@ -14,8 +14,8 @@ module Control.Abstract.Evaluator
import Data.Abstract.Address
import Data.Abstract.Configuration
import Data.Abstract.FreeVariables
import Data.Abstract.Heap
import Data.Abstract.ModuleTable
import Data.Abstract.Store
import Data.Abstract.Value
import Data.Semigroup.Reducer
import Prelude hiding (fail)
@ -31,7 +31,7 @@ class ( MonadControl term m
, MonadEnvironment value m
, MonadFail m
, MonadModuleTable term value m
, MonadStore value m
, MonadHeap value m
)
=> MonadEvaluator term value m | m -> term, m -> value where
-- | Get the current 'Configuration' with a passed-in term.
@ -65,27 +65,27 @@ modifyGlobalEnv f = do
-- | A 'Monad' abstracting a heap of values.
class Monad m => MonadStore value m | m -> value where
class Monad m => MonadHeap value m | m -> value where
-- | Retrieve the heap.
getStore :: m (StoreFor value)
getHeap :: m (HeapFor value)
-- | Set the heap.
putStore :: StoreFor value -> m ()
putHeap :: HeapFor value -> m ()
-- | Update the heap.
modifyStore :: MonadStore value m => (StoreFor value -> StoreFor value) -> m ()
modifyStore f = do
s <- getStore
putStore $! f s
modifyHeap :: MonadHeap value m => (HeapFor value -> HeapFor value) -> m ()
modifyHeap f = do
s <- getHeap
putHeap $! f s
-- | Write a value to the given 'Address' in the 'Store'.
assign :: ( Ord (LocationFor value)
, MonadStore value m
, MonadHeap value m
, Reducer value (CellFor value)
)
=> Address (LocationFor value) value
-> value
-> m ()
assign address = modifyStore . storeInsert address
assign address = modifyHeap . heapInsert address
-- | A 'Monad' abstracting tables of modules available for import.

View File

@ -199,7 +199,7 @@ instance ( Monad m
loop = fix
-- | Discard the value arguments (if any), constructing a 'Type' instead.
instance (Alternative m, MonadEnvironment Type m, MonadFail m, MonadFresh m, MonadStore Type m) => MonadValue Type m where
instance (Alternative m, MonadEnvironment Type m, MonadFail m, MonadFresh m, MonadHeap Type m) => MonadValue Type m where
abstract names (Subterm _ body) = do
(env, tvars) <- foldr (\ name rest -> do
a <- alloc name

View File

@ -3,30 +3,30 @@ module Data.Abstract.Cache where
import Data.Abstract.Address
import Data.Abstract.Configuration
import Data.Abstract.Store
import Data.Abstract.Heap
import Data.Map.Monoidal as Monoidal
import Prologue
-- | A map of 'Configuration's to 'Set's of resulting values & 'Store's.
newtype Cache l t v = Cache { unCache :: Monoidal.Map (Configuration l t v) (Set (v, Store l v)) }
-- | A map of 'Configuration's to 'Set's of resulting values & 'Heap's.
newtype Cache l t v = Cache { unCache :: Monoidal.Map (Configuration l t v) (Set (v, Heap l v)) }
deriving instance (Eq l, Eq t, Eq v, Eq (Cell l v)) => Eq (Cache l t v)
deriving instance (Ord l, Ord t, Ord v, Ord (Cell l v)) => Ord (Cache l t v)
deriving instance (Show l, Show t, Show v, Show (Cell l v)) => Show (Cache l t v)
deriving instance (Ord l, Ord t, Ord v, Ord (Cell l v)) => Semigroup (Cache l t v)
deriving instance (Ord l, Ord t, Ord v, Ord (Cell l v)) => Monoid (Cache l t v)
deriving instance (Ord l, Ord t, Ord v, Ord (Cell l v)) => Reducer (Configuration l t v, (v, Store l v)) (Cache l t v)
deriving instance (Ord l, Ord t, Ord v, Ord (Cell l v)) => Reducer (Configuration l t v, (v, Heap l v)) (Cache l t v)
-- | Look up the resulting value & 'Store' for a given 'Configuration'.
cacheLookup :: (Ord l, Ord t, Ord v, Ord (Cell l v)) => Configuration l t v -> Cache l t v -> Maybe (Set (v, Store l v))
-- | Look up the resulting value & 'Heap' for a given 'Configuration'.
cacheLookup :: (Ord l, Ord t, Ord v, Ord (Cell l v)) => Configuration l t v -> Cache l t v -> Maybe (Set (v, Heap l v))
cacheLookup key = Monoidal.lookup key . unCache
-- | Set the resulting value & 'Store' for a given 'Configuration', overwriting any previous entry.
cacheSet :: (Ord l, Ord t, Ord v, Ord (Cell l v)) => Configuration l t v -> Set (v, Store l v) -> Cache l t v -> Cache l t v
-- | Set the resulting value & 'Heap' for a given 'Configuration', overwriting any previous entry.
cacheSet :: (Ord l, Ord t, Ord v, Ord (Cell l v)) => Configuration l t v -> Set (v, Heap l v) -> Cache l t v -> Cache l t v
cacheSet key value = Cache . Monoidal.insert key value . unCache
-- | Insert the resulting value & 'Store' for a given 'Configuration', appending onto any previous entry.
cacheInsert :: (Ord l, Ord t, Ord v, Ord (Cell l v)) => Configuration l t v -> (v, Store l v) -> Cache l t v -> Cache l t v
-- | Insert the resulting value & 'Heap' for a given 'Configuration', appending onto any previous entry.
cacheInsert :: (Ord l, Ord t, Ord v, Ord (Cell l v)) => Configuration l t v -> (v, Heap l v) -> Cache l t v -> Cache l t v
cacheInsert = curry cons
@ -40,7 +40,7 @@ instance (Show l, Show t, Show1 (Cell l)) => Show1 (Cache l t) where
liftShowsPrec spV slV d = showsUnaryWith (liftShowsPrec2 spKey slKey (liftShowsPrec spPair slPair) (liftShowList spPair slPair)) "Cache" d . unCache
where spKey = liftShowsPrec spV slV
slKey = liftShowList spV slV
spPair = liftShowsPrec2 spV slV spStore slStore
slPair = liftShowList2 spV slV spStore slStore
spStore = liftShowsPrec spV slV
slStore = liftShowList spV slV
spPair = liftShowsPrec2 spV slV spHeap slHeap
slPair = liftShowList2 spV slV spHeap slHeap
spHeap = liftShowsPrec spV slV
slHeap = liftShowList spV slV

View File

@ -3,8 +3,8 @@ module Data.Abstract.Configuration where
import Data.Abstract.Address
import Data.Abstract.Environment
import Data.Abstract.Heap
import Data.Abstract.Live
import Data.Abstract.Store
import Data.Abstract.Value
import Prologue
@ -17,7 +17,7 @@ data Configuration l t v
{ configurationTerm :: t -- ^ The “instruction,” i.e. the current term to evaluate.
, configurationRoots :: Live l v -- ^ The set of rooted addresses.
, configurationEnvironment :: Environment l v -- ^ The environment binding any free variables in 'configurationTerm'.
, configurationStore :: Store l v -- ^ The store of values.
, configurationHeap :: Heap l v -- ^ The heap of values.
}
deriving (Generic1)

45
src/Data/Abstract/Heap.hs Normal file
View File

@ -0,0 +1,45 @@
{-# LANGUAGE GeneralizedNewtypeDeriving, MultiParamTypeClasses, StandaloneDeriving, UndecidableInstances #-}
module Data.Abstract.Heap where
import Data.Abstract.Address
import Data.Abstract.Live
import qualified Data.Map.Monoidal as Monoidal
import Data.Semigroup.Reducer
import Prologue
-- | A map of addresses onto cells holding their values.
newtype Heap l a = Heap { unStore :: Monoidal.Map l (Cell l a) }
deriving (Generic1)
deriving instance (Eq l, Eq (Cell l a)) => Eq (Heap l a)
deriving instance (Ord l, Ord (Cell l a)) => Ord (Heap l a)
deriving instance (Show l, Show (Cell l a)) => Show (Heap l a)
instance (Eq l, Eq1 (Cell l)) => Eq1 (Heap l) where liftEq = genericLiftEq
instance (Ord l, Ord1 (Cell l)) => Ord1 (Heap l) where liftCompare = genericLiftCompare
instance (Show l, Show1 (Cell l)) => Show1 (Heap l) where liftShowsPrec = genericLiftShowsPrec
deriving instance Foldable (Cell l) => Foldable (Heap l)
deriving instance Functor (Cell l) => Functor (Heap l)
deriving instance Traversable (Cell l) => Traversable (Heap l)
deriving instance (Ord l, Semigroup (Cell l a)) => Semigroup (Heap l a)
deriving instance (Ord l, Semigroup (Cell l a)) => Monoid (Heap l a)
deriving instance (Ord l, Reducer a (Cell l a)) => Reducer (l, a) (Heap l a)
-- | Look up the cell of values for an 'Address' in a 'Heap', if any.
heapLookup :: Ord l => Address l a -> Heap l a -> Maybe (Cell l a)
heapLookup (Address address) = Monoidal.lookup address . unStore
-- | Look up the list of values stored for a given address, if any.
heapLookupAll :: (Ord l, Foldable (Cell l)) => Address l a -> Heap l a -> Maybe [a]
heapLookupAll address = fmap toList . heapLookup address
-- | Append a value onto the cell for a given address, inserting a new cell if none existed.
heapInsert :: (Ord l, Reducer a (Cell l a)) => Address l a -> a -> Heap l a -> Heap l a
heapInsert (Address address) value = flip snoc (address, value)
-- | The number of addresses extant in a 'Heap'.
heapSize :: Heap l a -> Int
heapSize = Monoidal.size . unStore
-- | Restrict a 'Heap' to only those 'Address'es in the given 'Live' set (in essence garbage collecting the rest).
heapRestrict :: Ord l => Heap l a -> Live l a -> Heap l a
heapRestrict (Heap m) roots = Heap (Monoidal.filterWithKey (\ address _ -> Address address `liveMember` roots) m)

View File

@ -1,45 +0,0 @@
{-# LANGUAGE GeneralizedNewtypeDeriving, MultiParamTypeClasses, StandaloneDeriving, UndecidableInstances #-}
module Data.Abstract.Store where
import Data.Abstract.Address
import Data.Abstract.Live
import qualified Data.Map.Monoidal as Monoidal
import Data.Semigroup.Reducer
import Prologue
-- | A map of addresses onto cells holding their values.
newtype Store l a = Store { unStore :: Monoidal.Map l (Cell l a) }
deriving (Generic1)
deriving instance (Eq l, Eq (Cell l a)) => Eq (Store l a)
deriving instance (Ord l, Ord (Cell l a)) => Ord (Store l a)
deriving instance (Show l, Show (Cell l a)) => Show (Store l a)
instance (Eq l, Eq1 (Cell l)) => Eq1 (Store l) where liftEq = genericLiftEq
instance (Ord l, Ord1 (Cell l)) => Ord1 (Store l) where liftCompare = genericLiftCompare
instance (Show l, Show1 (Cell l)) => Show1 (Store l) where liftShowsPrec = genericLiftShowsPrec
deriving instance Foldable (Cell l) => Foldable (Store l)
deriving instance Functor (Cell l) => Functor (Store l)
deriving instance Traversable (Cell l) => Traversable (Store l)
deriving instance (Ord l, Semigroup (Cell l a)) => Semigroup (Store l a)
deriving instance (Ord l, Semigroup (Cell l a)) => Monoid (Store l a)
deriving instance (Ord l, Reducer a (Cell l a)) => Reducer (l, a) (Store l a)
-- | Look up the cell of values for an 'Address' in a 'Store', if any.
storeLookup :: Ord l => Address l a -> Store l a -> Maybe (Cell l a)
storeLookup (Address address) = Monoidal.lookup address . unStore
-- | Look up the list of values stored for a given address, if any.
storeLookupAll :: (Ord l, Foldable (Cell l)) => Address l a -> Store l a -> Maybe [a]
storeLookupAll address = fmap toList . storeLookup address
-- | Append a value onto the cell for a given address, inserting a new cell if none existed.
storeInsert :: (Ord l, Reducer a (Cell l a)) => Address l a -> a -> Store l a -> Store l a
storeInsert (Address address) value = flip snoc (address, value)
-- | The number of addresses extant in a 'Store'.
storeSize :: Store l a -> Int
storeSize = Monoidal.size . unStore
-- | Restrict a 'Store' to only those 'Address'es in the given 'Live' set (in essence garbage collecting the rest).
storeRestrict :: Ord l => Store l a -> Live l a -> Store l a
storeRestrict (Store m) roots = Store (Monoidal.filterWithKey (\ address _ -> Address address `liveMember` roots) m)

View File

@ -3,8 +3,8 @@ module Data.Abstract.Value where
import Data.Abstract.Address
import Data.Abstract.Environment
import Data.Abstract.Store
import Data.Abstract.FreeVariables
import Data.Abstract.Heap
import Data.Abstract.Live
import Data.Abstract.Number
import qualified Data.Abstract.Type as Type
@ -125,8 +125,8 @@ instance Show1 Tuple where liftShowsPrec = genericLiftShowsPrec
-- | The environment for an abstract value type.
type EnvironmentFor v = Environment (LocationFor v) v
-- | The store for an abstract value type.
type StoreFor v = Store (LocationFor v) v
-- | The 'Heap' for an abstract value type.
type HeapFor value = Heap (LocationFor value) value
-- | The cell for an abstract value type.
type CellFor value = Cell (LocationFor value) value

View File

@ -12,8 +12,8 @@ module SpecHelpers (
import Data.Abstract.Address as X
import Data.Abstract.Environment as X
import Data.Abstract.FreeVariables as X
import Data.Abstract.Heap as X
import Data.Abstract.ModuleTable as X
import Data.Abstract.Store as X
import Data.Blob as X
import Data.Functor.Listable as X
import Data.Language as X