mirror of
https://github.com/github/semantic.git
synced 2024-11-28 18:23:44 +03:00
Move require/load from Data.Abstract.Evaluatable to Control.Abstract.Analysis.
This commit is contained in:
parent
0956d571b8
commit
40adaf2b3b
@ -2,6 +2,8 @@
|
||||
module Control.Abstract.Analysis
|
||||
( MonadAnalysis(..)
|
||||
, evaluateTerm
|
||||
, require
|
||||
, load
|
||||
, liftAnalyze
|
||||
, runAnalysis
|
||||
, module X
|
||||
@ -17,7 +19,10 @@ import Control.Monad.Effect.Fresh as X
|
||||
import Control.Monad.Effect.NonDet as X
|
||||
import Control.Monad.Effect.Reader as X
|
||||
import Control.Monad.Effect.State as X
|
||||
import Data.Abstract.ModuleTable
|
||||
import Data.Abstract.Value
|
||||
import Data.Coerce
|
||||
import Prelude hiding (fail)
|
||||
import Prologue
|
||||
|
||||
-- | A 'Monad' in which one can evaluate some specific term type to some specific value type.
|
||||
@ -41,6 +46,29 @@ evaluateTerm :: MonadAnalysis term value m => term -> m value
|
||||
evaluateTerm = foldSubterms analyzeTerm
|
||||
|
||||
|
||||
-- | Require/import another term/file and return an Effect.
|
||||
--
|
||||
-- Looks up the term's name in the cache of evaluated modules first, returns a value if found, otherwise loads/evaluates the module.
|
||||
require :: MonadAnalysis term value m
|
||||
=> ModuleName
|
||||
-> m (EnvironmentFor value)
|
||||
require name = getModuleTable >>= maybe (load name) pure . moduleTableLookup name
|
||||
|
||||
-- | Load another term/file and return an Effect.
|
||||
--
|
||||
-- Always loads/evaluates.
|
||||
load :: MonadAnalysis term value m
|
||||
=> ModuleName
|
||||
-> m (EnvironmentFor value)
|
||||
load name = askModuleTable >>= maybe notFound evalAndCache . moduleTableLookup name
|
||||
where notFound = fail ("cannot load module: " <> show name)
|
||||
evalAndCache e = do
|
||||
void $ evaluateModule e
|
||||
env <- getGlobalEnv
|
||||
modifyModuleTable (moduleTableInsert name env)
|
||||
pure env
|
||||
|
||||
|
||||
-- | Lift a 'SubtermAlgebra' for an underlying analysis into a containing analysis. Use this when defining an analysis which can be composed onto other analyses to ensure that a call to 'analyzeTerm' occurs in the inner analysis and not the outer one.
|
||||
liftAnalyze :: ( Coercible ( m term value (effects :: [* -> *]) value) (t m term value effects value)
|
||||
, Coercible (t m term value effects value) ( m term value effects value)
|
||||
|
@ -6,8 +6,6 @@ module Data.Abstract.Evaluatable
|
||||
, module FreeVariables
|
||||
, module Value
|
||||
, MonadEvaluator(..)
|
||||
, require
|
||||
, load
|
||||
, Imperative(..)
|
||||
) where
|
||||
|
||||
@ -15,7 +13,6 @@ import Control.Abstract.Addressable as Addressable
|
||||
import Control.Abstract.Analysis as Analysis
|
||||
import Control.Abstract.Value as Value
|
||||
import Data.Abstract.FreeVariables as FreeVariables
|
||||
import Data.Abstract.ModuleTable
|
||||
import Data.Abstract.Value
|
||||
import Data.Functor.Classes
|
||||
import Data.Proxy
|
||||
@ -56,29 +53,6 @@ instance Evaluatable [] where
|
||||
eval = maybe unit (runImperative . foldMap1 (Imperative . subtermValue)) . nonEmpty
|
||||
|
||||
|
||||
-- | Require/import another term/file and return an Effect.
|
||||
--
|
||||
-- Looks up the term's name in the cache of evaluated modules first, returns a value if found, otherwise loads/evaluates the module.
|
||||
require :: MonadAnalysis term value m
|
||||
=> ModuleName
|
||||
-> m (EnvironmentFor value)
|
||||
require name = getModuleTable >>= maybe (load name) pure . moduleTableLookup name
|
||||
|
||||
-- | Load another term/file and return an Effect.
|
||||
--
|
||||
-- Always loads/evaluates.
|
||||
load :: MonadAnalysis term value m
|
||||
=> ModuleName
|
||||
-> m (EnvironmentFor value)
|
||||
load name = askModuleTable >>= maybe notFound evalAndCache . moduleTableLookup name
|
||||
where notFound = fail ("cannot load module: " <> show name)
|
||||
evalAndCache e = do
|
||||
void $ evaluateModule e
|
||||
env <- getGlobalEnv
|
||||
modifyModuleTable (moduleTableInsert name env)
|
||||
pure env
|
||||
|
||||
|
||||
-- | A 'Semigroup' providing an imperative context which extends the local environment with new bindings.
|
||||
newtype Imperative m a = Imperative { runImperative :: m a }
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user