1
1
mirror of https://github.com/github/semantic.git synced 2024-12-22 22:31:36 +03:00

Move require/load into Data.Abstract.Evaluatable.

This commit is contained in:
Rob Rix 2018-03-01 16:30:26 -05:00
parent 106819c39e
commit dcc332a75b
2 changed files with 39 additions and 35 deletions

View File

@ -17,8 +17,6 @@ import Prelude hiding (fail)
import qualified Data.Map as Map import qualified Data.Map as Map
import System.FilePath.Posix import System.FilePath.Posix
import qualified Data.ByteString.Char8 as BC
-- | The effects necessary for concrete interpretation. -- | The effects necessary for concrete interpretation.
type Evaluating t v type Evaluating t v
= '[ Fail -- Failure with an error message = '[ Fail -- Failure with an error message
@ -29,39 +27,6 @@ type Evaluating t v
, State (Linker v) -- Cache of evaluated modules , State (Linker v) -- Cache of evaluated modules
] ]
-- | 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 :: ( FreeVariables term
, MonadAnalysis term v m
, MonadEvaluator term v m
)
=> term
-> m v
require term = getModuleTable >>= maybe (load term) pure . linkerLookup name
where name = moduleName term
-- | Load another term/file and return an Effect.
--
-- Always loads/evaluates.
load :: ( FreeVariables term
, MonadAnalysis term v m
, MonadEvaluator term v m
)
=> term
-> m v
load term = askModuleTable >>= maybe notFound evalAndCache . linkerLookup name
where name = moduleName term
notFound = fail ("cannot find " <> show name)
evalAndCache e = do
v <- evaluateTerm e
modifyModuleTable (linkerInsert name v)
pure v
-- | Get a module name from a term (expects single free variables).
moduleName :: FreeVariables term => term -> Prelude.String
moduleName term = let [n] = toList (freeVariables term) in BC.unpack n
-- | Evaluate a term to a value. -- | Evaluate a term to a value.
evaluate :: forall v term evaluate :: forall v term

View File

@ -7,6 +7,8 @@ module Data.Abstract.Evaluatable
, module FreeVariables , module FreeVariables
, module Function , module Function
, MonadEvaluator(..) , MonadEvaluator(..)
, require
, load
) where ) where
import Control.Abstract.Addressable as Addressable import Control.Abstract.Addressable as Addressable
@ -18,14 +20,17 @@ import Control.Monad.Effect.Internal
import Data.Abstract.Address import Data.Abstract.Address
import Data.Abstract.Environment import Data.Abstract.Environment
import Data.Abstract.FreeVariables as FreeVariables import Data.Abstract.FreeVariables as FreeVariables
import Data.Abstract.Linker
import Data.Abstract.Value import Data.Abstract.Value
import Data.Algebra import Data.Algebra
import qualified Data.ByteString.Char8 as BC
import Data.Functor.Classes import Data.Functor.Classes
import Data.Proxy import Data.Proxy
import Data.Semigroup import Data.Semigroup
import Data.Term import Data.Term
import Data.Union (Apply) import Data.Union (Apply)
import Prelude hiding (fail) import Prelude hiding (fail)
import Prologue
import qualified Data.Union as U import qualified Data.Union as U
@ -73,3 +78,37 @@ instance Evaluatable [] where
-- environment each time where the free variables in those terms are bound -- environment each time where the free variables in those terms are bound
-- to the global environment. -- to the global environment.
localEnv (const (bindEnv (liftFreeVariables (freeVariables . subterm) xs) env)) (eval xs) localEnv (const (bindEnv (liftFreeVariables (freeVariables . subterm) xs) env)) (eval xs)
-- | 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 :: ( FreeVariables term
, MonadAnalysis term v m
, MonadEvaluator term v m
)
=> term
-> m v
require term = getModuleTable >>= maybe (load term) pure . linkerLookup name
where name = moduleName term
-- | Load another term/file and return an Effect.
--
-- Always loads/evaluates.
load :: ( FreeVariables term
, MonadAnalysis term v m
, MonadEvaluator term v m
)
=> term
-> m v
load term = askModuleTable >>= maybe notFound evalAndCache . linkerLookup name
where name = moduleName term
notFound = fail ("cannot find " <> show name)
evalAndCache e = do
v <- evaluateTerm e
modifyModuleTable (linkerInsert name v)
pure v
-- | Get a module name from a term (expects single free variables).
moduleName :: FreeVariables term => term -> Prelude.String
moduleName term = let [n] = toList (freeVariables term) in BC.unpack n