-
Notifications
You must be signed in to change notification settings - Fork 452
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #668 from github/modular-mechanics
Modular abstract interpretation
- Loading branch information
Showing
13 changed files
with
297 additions
and
129 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
test.json | ||
test.py |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
{-# LANGUAGE FlexibleInstances #-} | ||
{-# LANGUAGE GADTs #-} | ||
{-# LANGUAGE GeneralizedNewtypeDeriving #-} | ||
{-# LANGUAGE MultiParamTypeClasses #-} | ||
{-# LANGUAGE TypeOperators #-} | ||
{-# LANGUAGE UndecidableInstances #-} | ||
module Analysis.Carrier.Statement.State | ||
( -- * Messages | ||
Message(..) | ||
-- * Statement carrier | ||
, runStatement | ||
, StatementC(..) | ||
-- * Statement effect | ||
, module Analysis.Effect.Statement | ||
) where | ||
|
||
import Analysis.Effect.Statement hiding (Import) | ||
import qualified Analysis.Effect.Statement as S | ||
import Control.Algebra | ||
import Control.Carrier.State.Church | ||
import Control.Monad.Fail as Fail | ||
import Data.List.NonEmpty (NonEmpty) | ||
import Data.Text (Text) | ||
|
||
-- Messages | ||
|
||
newtype Message | ||
= Import (NonEmpty Text) | ||
deriving (Eq, Ord, Show) | ||
|
||
|
||
-- Statement carrier | ||
|
||
runStatement :: ([Message] -> a -> m r) -> StatementC m a -> m r | ||
runStatement k (StatementC m) = runState (k . reverse) [] m | ||
|
||
newtype StatementC m a = StatementC { runStatementC :: StateC [Message] m a } | ||
deriving (Applicative, Functor, Monad, Fail.MonadFail) | ||
|
||
instance Algebra sig m => Algebra (S.Statement :+: sig) (StatementC m) where | ||
alg hdl sig ctx = case sig of | ||
L (S.Import ns) -> StatementC ((<$ ctx) <$> modify (Import ns:)) | ||
R other -> StatementC (alg (runStatementC . hdl) (R other) ctx) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
{-# LANGUAGE GADTs #-} | ||
{-# LANGUAGE KindSignatures #-} | ||
{- | | ||
The @'Statement'@ effect is designed to provide instrumentation for source-level interactions we need visibility into which are nevertheless not (currently) modelled by expressions: e.g. statements, declarations, certain directives, etc. | ||
Currently this is limited to imports, where the value-level semantics are (for many languages) essentially the unit value, but where the effect of bringing an environment and entire subset of the store into scope are essential to track for modular interpretation. | ||
-} | ||
module Analysis.Effect.Statement | ||
( -- * Statement effect | ||
simport | ||
, Statement(..) | ||
) where | ||
|
||
import Control.Algebra | ||
import Data.Kind as K | ||
import Data.List.NonEmpty (NonEmpty) | ||
import Data.Text | ||
|
||
-- Statement effect | ||
|
||
simport :: Has Statement sig m => NonEmpty Text -> m () | ||
simport ns = send (Import ns) | ||
|
||
data Statement (m :: K.Type -> K.Type) k where | ||
Import :: NonEmpty Text -> Statement m () |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
module Analysis.Module | ||
( Module(..) | ||
, ModuleSet(..) | ||
, link | ||
) where | ||
|
||
import Analysis.Name | ||
import Data.Foldable (foldl') | ||
import qualified Data.Map as Map | ||
import qualified Data.Set as Set | ||
|
||
data Module a = Module | ||
{ body :: Map.Map Name a -> a | ||
, imports :: Set.Set Name | ||
, exports :: Map.Map Name a | ||
, unknown :: Set.Set Name | ||
} | ||
|
||
newtype ModuleSet a = ModuleSet { getModuleSet :: Map.Map Name (Module a) } | ||
|
||
instance Semigroup (ModuleSet a) where | ||
m1 <> m2 = ModuleSet ((link m2 <$> getModuleSet m1) <> (link m1 <$> getModuleSet m2)) | ||
|
||
link :: ModuleSet a -> Module a -> Module a | ||
link (ModuleSet ms) m = Module body' (imports m Set.\\ Map.keysSet ms) (exports m) unknown' where | ||
(unknown', body') = foldl' (uncurry resolveSymbolsInModule) (unknown m, body m) (Map.restrictKeys ms (imports m)) | ||
resolveSymbolsInModule unknown body m = (unknown Set.\\ Map.keysSet (exports m), body . mappend (Map.restrictKeys (exports m) unknown)) |
Oops, something went wrong.