From fcf654032cd0b5a72c4e969b1297738f75486021 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 10:05:07 -0400 Subject: [PATCH 01/40] Rename the name parameter to address. --- semantic-core/src/Analysis/FlowInsensitive.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/semantic-core/src/Analysis/FlowInsensitive.hs b/semantic-core/src/Analysis/FlowInsensitive.hs index fdf0cc7fa4..2a81207ca6 100644 --- a/semantic-core/src/Analysis/FlowInsensitive.hs +++ b/semantic-core/src/Analysis/FlowInsensitive.hs @@ -21,7 +21,7 @@ import qualified Data.Set as Set import Data.Term (Term) type Cache name a = Map.Map (Term (Core.Ann :+: Core.Core) name) (Set.Set a) -type Heap name a = Map.Map name (Set.Set a) +type Heap address a = Map.Map address (Set.Set a) newtype FrameId name = FrameId { unFrameId :: name } deriving (Eq, Ord, Show) @@ -65,7 +65,7 @@ cacheTerm eval term = do result <- eval term result <$ modify (Map.insertWith (<>) term (Set.singleton (result :: a))) -runHeap :: name -> ReaderC (FrameId name) (StateC (Heap name a) m) b -> m (Heap name a, b) +runHeap :: address -> ReaderC (FrameId address) (StateC (Heap address a) m) b -> m (Heap address a, b) runHeap addr m = runState (Map.singleton addr Set.empty) (runReader (FrameId addr) m) -- | Fold a collection by mapping each element onto an 'Alternative' action. From 56984fa7a66dea5d380ac09cafe69cc790d5fb08 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 11:52:48 -0400 Subject: [PATCH 02/40] Define Cache as a newtype. --- semantic-core/src/Analysis/FlowInsensitive.hs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/semantic-core/src/Analysis/FlowInsensitive.hs b/semantic-core/src/Analysis/FlowInsensitive.hs index 2a81207ca6..d234e45b73 100644 --- a/semantic-core/src/Analysis/FlowInsensitive.hs +++ b/semantic-core/src/Analysis/FlowInsensitive.hs @@ -20,7 +20,9 @@ import Data.Monoid (Alt(..)) import qualified Data.Set as Set import Data.Term (Term) -type Cache name a = Map.Map (Term (Core.Ann :+: Core.Core) name) (Set.Set a) +newtype Cache name a = Cache { unCache :: Map.Map (Term (Core.Ann :+: Core.Core) name) (Set.Set a) } + deriving (Eq, Ord, Show) + type Heap address a = Map.Map address (Set.Set a) newtype FrameId name = FrameId { unFrameId :: name } @@ -40,10 +42,10 @@ convergeTerm :: forall m sig a name -> m (Set.Set a) convergeTerm eval body = do heap <- get - (cache, _) <- converge (Map.empty :: Cache name a, heap :: Heap name a) $ \ (prevCache, _) -> runState Map.empty . runReader prevCache $ do + (cache, _) <- converge (Cache Map.empty :: Cache name a, heap :: Heap name a) $ \ (prevCache, _) -> runState (Cache Map.empty) . runReader prevCache $ do _ <- resetFresh . runNonDetM Set.singleton $ eval body get - pure (fromMaybe mempty (Map.lookup body cache)) + pure (fromMaybe mempty (Map.lookup body (unCache cache))) cacheTerm :: forall m sig a name . ( Alternative m @@ -56,14 +58,14 @@ cacheTerm :: forall m sig a name => (Term (Core.Ann :+: Core.Core) name -> m a) -> (Term (Core.Ann :+: Core.Core) name -> m a) cacheTerm eval term = do - cached <- gets (Map.lookup term) + cached <- gets (Map.lookup term . unCache) case cached :: Maybe (Set.Set a) of Just results -> foldMapA pure results Nothing -> do - results <- asks (fromMaybe mempty . Map.lookup term) - modify (Map.insert term (results :: Set.Set a)) + results <- asks (fromMaybe mempty . Map.lookup term . unCache) + modify (Cache . Map.insert term (results :: Set.Set a) . unCache) result <- eval term - result <$ modify (Map.insertWith (<>) term (Set.singleton (result :: a))) + result <$ modify (Cache . Map.insertWith (<>) term (Set.singleton (result :: a)) . unCache) runHeap :: address -> ReaderC (FrameId address) (StateC (Heap address a) m) b -> m (Heap address a, b) runHeap addr m = runState (Map.singleton addr Set.empty) (runReader (FrameId addr) m) From 7b6b6a4259f6c2f85b04e4b320a0a36009fed97e Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 11:54:57 -0400 Subject: [PATCH 03/40] Generalize convergeTerm over the address type. --- semantic-core/src/Analysis/FlowInsensitive.hs | 12 +++++++----- semantic-core/src/Analysis/ImportGraph.hs | 5 +++-- semantic-core/src/Analysis/Typecheck.hs | 3 ++- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/semantic-core/src/Analysis/FlowInsensitive.hs b/semantic-core/src/Analysis/FlowInsensitive.hs index d234e45b73..89474d898a 100644 --- a/semantic-core/src/Analysis/FlowInsensitive.hs +++ b/semantic-core/src/Analysis/FlowInsensitive.hs @@ -29,20 +29,22 @@ newtype FrameId name = FrameId { unFrameId :: name } deriving (Eq, Ord, Show) -convergeTerm :: forall m sig a name +convergeTerm :: forall m sig a name address proxy . ( Carrier sig m , Effect sig + , Eq address , Member Fresh sig - , Member (State (Heap name a)) sig + , Member (State (Heap address a)) sig , Ord a , Ord name ) - => (Term (Core.Ann :+: Core.Core) name -> NonDetC (ReaderC (Cache name a) (StateC (Cache name a) m)) a) + => proxy address + -> (Term (Core.Ann :+: Core.Core) name -> NonDetC (ReaderC (Cache name a) (StateC (Cache name a) m)) a) -> Term (Core.Ann :+: Core.Core) name -> m (Set.Set a) -convergeTerm eval body = do +convergeTerm _ eval body = do heap <- get - (cache, _) <- converge (Cache Map.empty :: Cache name a, heap :: Heap name a) $ \ (prevCache, _) -> runState (Cache Map.empty) . runReader prevCache $ do + (cache, _) <- converge (Cache Map.empty :: Cache name a, heap :: Heap address a) $ \ (prevCache, _) -> runState (Cache Map.empty) . runReader prevCache $ do _ <- resetFresh . runNonDetM Set.singleton $ eval body get pure (fromMaybe mempty (Map.lookup body (unCache cache))) diff --git a/semantic-core/src/Analysis/ImportGraph.hs b/semantic-core/src/Analysis/ImportGraph.hs index f5b8a8d827..f6a0f52237 100644 --- a/semantic-core/src/Analysis/ImportGraph.hs +++ b/semantic-core/src/Analysis/ImportGraph.hs @@ -1,4 +1,4 @@ -{-# LANGUAGE FlexibleContexts, OverloadedStrings, RecordWildCards, TypeOperators #-} +{-# LANGUAGE FlexibleContexts, OverloadedStrings, RecordWildCards, TypeApplications, TypeOperators #-} module Analysis.ImportGraph ( ImportGraph , importGraph @@ -21,6 +21,7 @@ import Data.List.NonEmpty (nonEmpty) import Data.Loc import qualified Data.Map as Map import Data.Name +import Data.Proxy import qualified Data.Set as Set import Data.Term import Data.Text (Text) @@ -67,7 +68,7 @@ runFile file = traverse run file where run = runReader (fileLoc file) . runFailWithLoc . fmap fold - . convergeTerm (fix (cacheTerm . eval importGraphAnalysis)) + . convergeTerm (Proxy @User) (fix (cacheTerm . eval importGraphAnalysis)) -- FIXME: decompose into a product domain and two atomic domains importGraphAnalysis :: ( Alternative m diff --git a/semantic-core/src/Analysis/Typecheck.hs b/semantic-core/src/Analysis/Typecheck.hs index 35c7eb266b..9926b83340 100644 --- a/semantic-core/src/Analysis/Typecheck.hs +++ b/semantic-core/src/Analysis/Typecheck.hs @@ -29,6 +29,7 @@ import Data.Loc import qualified Data.Map as Map import Data.Maybe (fromJust, fromMaybe) import Data.Name as Name +import Data.Proxy import Data.Scope import Data.Semigroup (Last (..)) import qualified Data.Set as Set @@ -118,7 +119,7 @@ runFile file = traverse run file v <- meta bs <- m v <$ for_ bs (unify v)) - . convergeTerm (fix (cacheTerm . eval typecheckingAnalysis)) + . convergeTerm (Proxy @User) (fix (cacheTerm . eval typecheckingAnalysis)) typecheckingAnalysis :: ( Alternative m From 05fa90ef8471d9d9451361c180f40cdcc0707e93 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 11:58:02 -0400 Subject: [PATCH 04/40] Generalize the Cache type over the term type. --- semantic-core/src/Analysis/FlowInsensitive.hs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/semantic-core/src/Analysis/FlowInsensitive.hs b/semantic-core/src/Analysis/FlowInsensitive.hs index 89474d898a..cb3ade20d3 100644 --- a/semantic-core/src/Analysis/FlowInsensitive.hs +++ b/semantic-core/src/Analysis/FlowInsensitive.hs @@ -20,7 +20,7 @@ import Data.Monoid (Alt(..)) import qualified Data.Set as Set import Data.Term (Term) -newtype Cache name a = Cache { unCache :: Map.Map (Term (Core.Ann :+: Core.Core) name) (Set.Set a) } +newtype Cache term a = Cache { unCache :: Map.Map term (Set.Set a) } deriving (Eq, Ord, Show) type Heap address a = Map.Map address (Set.Set a) @@ -39,12 +39,12 @@ convergeTerm :: forall m sig a name address proxy , Ord name ) => proxy address - -> (Term (Core.Ann :+: Core.Core) name -> NonDetC (ReaderC (Cache name a) (StateC (Cache name a) m)) a) + -> (Term (Core.Ann :+: Core.Core) name -> NonDetC (ReaderC (Cache (Term (Core.Ann :+: Core.Core) name) a) (StateC (Cache (Term (Core.Ann :+: Core.Core) name) a) m)) a) -> Term (Core.Ann :+: Core.Core) name -> m (Set.Set a) convergeTerm _ eval body = do heap <- get - (cache, _) <- converge (Cache Map.empty :: Cache name a, heap :: Heap address a) $ \ (prevCache, _) -> runState (Cache Map.empty) . runReader prevCache $ do + (cache, _) <- converge (Cache Map.empty :: Cache (Term (Core.Ann :+: Core.Core) name) a, heap :: Heap address a) $ \ (prevCache, _) -> runState (Cache Map.empty) . runReader prevCache $ do _ <- resetFresh . runNonDetM Set.singleton $ eval body get pure (fromMaybe mempty (Map.lookup body (unCache cache))) @@ -52,8 +52,8 @@ convergeTerm _ eval body = do cacheTerm :: forall m sig a name . ( Alternative m , Carrier sig m - , Member (Reader (Cache name a)) sig - , Member (State (Cache name a)) sig + , Member (Reader (Cache (Term (Core.Ann :+: Core.Core) name) a)) sig + , Member (State (Cache (Term (Core.Ann :+: Core.Core) name) a)) sig , Ord a , Ord name ) From fdc20a4256b246053f8c34aa222743f79d9a3320 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 11:58:44 -0400 Subject: [PATCH 05/40] Generalize convergeTerm over the term type. --- semantic-core/src/Analysis/FlowInsensitive.hs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/semantic-core/src/Analysis/FlowInsensitive.hs b/semantic-core/src/Analysis/FlowInsensitive.hs index cb3ade20d3..18a90b96de 100644 --- a/semantic-core/src/Analysis/FlowInsensitive.hs +++ b/semantic-core/src/Analysis/FlowInsensitive.hs @@ -29,22 +29,22 @@ newtype FrameId name = FrameId { unFrameId :: name } deriving (Eq, Ord, Show) -convergeTerm :: forall m sig a name address proxy +convergeTerm :: forall m sig a term address proxy . ( Carrier sig m , Effect sig , Eq address , Member Fresh sig , Member (State (Heap address a)) sig , Ord a - , Ord name + , Ord term ) => proxy address - -> (Term (Core.Ann :+: Core.Core) name -> NonDetC (ReaderC (Cache (Term (Core.Ann :+: Core.Core) name) a) (StateC (Cache (Term (Core.Ann :+: Core.Core) name) a) m)) a) - -> Term (Core.Ann :+: Core.Core) name + -> (term -> NonDetC (ReaderC (Cache term a) (StateC (Cache term a) m)) a) + -> term -> m (Set.Set a) convergeTerm _ eval body = do heap <- get - (cache, _) <- converge (Cache Map.empty :: Cache (Term (Core.Ann :+: Core.Core) name) a, heap :: Heap address a) $ \ (prevCache, _) -> runState (Cache Map.empty) . runReader prevCache $ do + (cache, _) <- converge (Cache Map.empty :: Cache term a, heap :: Heap address a) $ \ (prevCache, _) -> runState (Cache Map.empty) . runReader prevCache $ do _ <- resetFresh . runNonDetM Set.singleton $ eval body get pure (fromMaybe mempty (Map.lookup body (unCache cache))) From c82623db364882128bbe6a4837993f0c7530856a Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 11:59:30 -0400 Subject: [PATCH 06/40] Generalize cacheTerm over the term type. --- semantic-core/src/Analysis/FlowInsensitive.hs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/semantic-core/src/Analysis/FlowInsensitive.hs b/semantic-core/src/Analysis/FlowInsensitive.hs index 18a90b96de..de9a771764 100644 --- a/semantic-core/src/Analysis/FlowInsensitive.hs +++ b/semantic-core/src/Analysis/FlowInsensitive.hs @@ -13,12 +13,10 @@ import Control.Effect.Fresh import Control.Effect.NonDet import Control.Effect.Reader import Control.Effect.State -import qualified Data.Core as Core import qualified Data.Map as Map import Data.Maybe (fromMaybe) import Data.Monoid (Alt(..)) import qualified Data.Set as Set -import Data.Term (Term) newtype Cache term a = Cache { unCache :: Map.Map term (Set.Set a) } deriving (Eq, Ord, Show) @@ -49,16 +47,16 @@ convergeTerm _ eval body = do get pure (fromMaybe mempty (Map.lookup body (unCache cache))) -cacheTerm :: forall m sig a name +cacheTerm :: forall m sig a term . ( Alternative m , Carrier sig m - , Member (Reader (Cache (Term (Core.Ann :+: Core.Core) name) a)) sig - , Member (State (Cache (Term (Core.Ann :+: Core.Core) name) a)) sig + , Member (Reader (Cache term a)) sig + , Member (State (Cache term a)) sig , Ord a - , Ord name + , Ord term ) - => (Term (Core.Ann :+: Core.Core) name -> m a) - -> (Term (Core.Ann :+: Core.Core) name -> m a) + => (term -> m a) + -> (term -> m a) cacheTerm eval term = do cached <- gets (Map.lookup term . unCache) case cached :: Maybe (Set.Set a) of From 104bdacaae5c2be315f7e62f3d2cf75bebd771c4 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 12:03:12 -0400 Subject: [PATCH 07/40] Generalize Analysis over the term type. --- semantic-core/src/Analysis/Concrete.hs | 2 +- semantic-core/src/Analysis/Eval.hs | 8 ++++---- semantic-core/src/Analysis/ImportGraph.hs | 2 +- semantic-core/src/Analysis/Typecheck.hs | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/semantic-core/src/Analysis/Concrete.hs b/semantic-core/src/Analysis/Concrete.hs index d9be8e44f6..011bd82a06 100644 --- a/semantic-core/src/Analysis/Concrete.hs +++ b/semantic-core/src/Analysis/Concrete.hs @@ -96,7 +96,7 @@ concreteAnalysis :: ( Carrier sig m , Member (State Heap) sig , MonadFail m ) - => Analysis Precise Concrete m + => Analysis (Term (Core.Ann :+: Core.Core)) Precise Concrete m concreteAnalysis = Analysis{..} where alloc _ = fresh bind name addr m = local (Map.insert name addr) m diff --git a/semantic-core/src/Analysis/Eval.hs b/semantic-core/src/Analysis/Eval.hs index 767a658754..161a5e6209 100644 --- a/semantic-core/src/Analysis/Eval.hs +++ b/semantic-core/src/Analysis/Eval.hs @@ -33,7 +33,7 @@ eval :: ( Carrier sig m , MonadFail m , Semigroup value ) - => Analysis address value m + => Analysis (Term (Ann :+: Core)) address value m -> (Term (Ann :+: Core) User -> m value) -> (Term (Ann :+: Core) User -> m value) eval Analysis{..} eval = \case @@ -211,14 +211,14 @@ ruby = fromBody $ annWith callStack (rec (named' __semantic_global) (do' stateme __semantic_truthy = "__semantic_truthy" -data Analysis address value m = Analysis +data Analysis term address value m = Analysis { alloc :: User -> m address , bind :: forall a . User -> address -> m a -> m a , lookupEnv :: User -> m (Maybe address) , deref :: address -> m (Maybe value) , assign :: address -> value -> m () - , abstract :: (Term (Ann :+: Core) User -> m value) -> User -> Term (Ann :+: Core) User -> m value - , apply :: (Term (Ann :+: Core) User -> m value) -> value -> value -> m value + , abstract :: (term User -> m value) -> User -> term User -> m value + , apply :: (term User -> m value) -> value -> value -> m value , unit :: m value , bool :: Bool -> m value , asBool :: value -> m Bool diff --git a/semantic-core/src/Analysis/ImportGraph.hs b/semantic-core/src/Analysis/ImportGraph.hs index f6a0f52237..d009793528 100644 --- a/semantic-core/src/Analysis/ImportGraph.hs +++ b/semantic-core/src/Analysis/ImportGraph.hs @@ -78,7 +78,7 @@ importGraphAnalysis :: ( Alternative m , Member (State (Heap User Value)) sig , MonadFail m ) - => Analysis User Value m + => Analysis (Term (Core.Ann :+: Core.Core)) User Value m importGraphAnalysis = Analysis{..} where alloc = pure bind _ _ m = m diff --git a/semantic-core/src/Analysis/Typecheck.hs b/semantic-core/src/Analysis/Typecheck.hs index 9926b83340..926e4626db 100644 --- a/semantic-core/src/Analysis/Typecheck.hs +++ b/semantic-core/src/Analysis/Typecheck.hs @@ -128,7 +128,7 @@ typecheckingAnalysis , Member (State (Set.Set Constraint)) sig , Member (State (Heap User (Term Monotype Meta))) sig ) - => Analysis User (Term Monotype Meta) m + => Analysis term User (Term Monotype Meta) m typecheckingAnalysis = Analysis{..} where alloc = pure bind _ _ m = m From 465319b8d40a89ea5a12223c1423c233e37f7fc1 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Fri, 26 Jul 2019 16:29:58 -0400 Subject: [PATCH 08/40] Simplify deref for Typecheck & ImportGraph. --- semantic-core/src/Analysis/ImportGraph.hs | 3 ++- semantic-core/src/Analysis/Typecheck.hs | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/semantic-core/src/Analysis/ImportGraph.hs b/semantic-core/src/Analysis/ImportGraph.hs index d009793528..934cd34990 100644 --- a/semantic-core/src/Analysis/ImportGraph.hs +++ b/semantic-core/src/Analysis/ImportGraph.hs @@ -13,6 +13,7 @@ import Control.Effect.Fail import Control.Effect.Fresh import Control.Effect.Reader import Control.Effect.State +import Control.Monad ((>=>)) import qualified Data.Core as Core import Data.File import Data.Foldable (fold) @@ -83,7 +84,7 @@ importGraphAnalysis = Analysis{..} where alloc = pure bind _ _ m = m lookupEnv = pure . Just - deref addr = gets (Map.lookup addr) >>= maybe (pure Nothing) (foldMapA (pure . Just)) . nonEmpty . maybe [] Set.toList + deref addr = gets (Map.lookup addr >=> nonEmpty . Set.toList) >>= maybe (pure Nothing) (foldMapA (pure . Just)) assign addr ty = modify (Map.insertWith (<>) addr (Set.singleton ty)) abstract _ name body = do loc <- ask diff --git a/semantic-core/src/Analysis/Typecheck.hs b/semantic-core/src/Analysis/Typecheck.hs index 926e4626db..069f58a684 100644 --- a/semantic-core/src/Analysis/Typecheck.hs +++ b/semantic-core/src/Analysis/Typecheck.hs @@ -15,7 +15,7 @@ import Control.Effect.Fail import Control.Effect.Fresh as Fresh import Control.Effect.Reader hiding (Local) import Control.Effect.State -import Control.Monad (unless) +import Control.Monad ((>=>), unless) import Control.Monad.Module import qualified Data.Core as Core import Data.File @@ -133,7 +133,7 @@ typecheckingAnalysis = Analysis{..} where alloc = pure bind _ _ m = m lookupEnv = pure . Just - deref addr = gets (Map.lookup addr) >>= maybe (pure Nothing) (foldMapA (pure . Just)) . nonEmpty . maybe [] Set.toList + deref addr = gets (Map.lookup addr >=> nonEmpty . Set.toList) >>= maybe (pure Nothing) (foldMapA (pure . Just)) assign addr ty = modify (Map.insertWith (<>) addr (Set.singleton ty)) abstract eval name body = do -- FIXME: construct the associated scope From 9acaaaedc0ae5a9fd797339def4358973aeffdee Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 12:10:48 -0400 Subject: [PATCH 09/40] :fire: the parentAddr in ImportGraph. --- semantic-core/src/Analysis/ImportGraph.hs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/semantic-core/src/Analysis/ImportGraph.hs b/semantic-core/src/Analysis/ImportGraph.hs index 934cd34990..9b37bb4a7f 100644 --- a/semantic-core/src/Analysis/ImportGraph.hs +++ b/semantic-core/src/Analysis/ImportGraph.hs @@ -43,7 +43,7 @@ instance Monoid Value where mempty = Value Abstract mempty data Semi - = Closure Loc User (Term (Core.Ann :+: Core.Core) User) User + = Closure Loc User (Term (Core.Ann :+: Core.Core) User) (Set.Set User) -- FIXME: Bound String values. | String Text | Abstract @@ -60,7 +60,6 @@ importGraph runFile :: ( Carrier sig m , Effect sig , Member Fresh sig - , Member (Reader (FrameId User)) sig , Member (State (Heap User Value)) sig ) => File (Term (Core.Ann :+: Core.Core) User) @@ -74,7 +73,6 @@ runFile file = traverse run file -- FIXME: decompose into a product domain and two atomic domains importGraphAnalysis :: ( Alternative m , Carrier sig m - , Member (Reader (FrameId User)) sig , Member (Reader Loc) sig , Member (State (Heap User Value)) sig , MonadFail m @@ -88,8 +86,8 @@ importGraphAnalysis = Analysis{..} assign addr ty = modify (Map.insertWith (<>) addr (Set.singleton ty)) abstract _ name body = do loc <- ask - FrameId parentAddr <- ask - pure (Value (Closure loc name body parentAddr) mempty) + env <- gets @(Heap User Value) Map.keysSet + pure (Value (Closure loc name body env) mempty) apply eval (Value (Closure loc name body _) _) a = local (const loc) $ do addr <- alloc name assign addr a From 65e218417f176cc6fa426cb359ba2b6c30842d56 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 12:11:54 -0400 Subject: [PATCH 10/40] =?UTF-8?q?Import=20graphs=20don=E2=80=99t=20need=20?= =?UTF-8?q?to=20collect=20the=20set=20of=20addresses=20in=20scope=20when?= =?UTF-8?q?=20abstracting.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- semantic-core/src/Analysis/ImportGraph.hs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/semantic-core/src/Analysis/ImportGraph.hs b/semantic-core/src/Analysis/ImportGraph.hs index 9b37bb4a7f..80487df910 100644 --- a/semantic-core/src/Analysis/ImportGraph.hs +++ b/semantic-core/src/Analysis/ImportGraph.hs @@ -43,7 +43,7 @@ instance Monoid Value where mempty = Value Abstract mempty data Semi - = Closure Loc User (Term (Core.Ann :+: Core.Core) User) (Set.Set User) + = Closure Loc User (Term (Core.Ann :+: Core.Core) User) -- FIXME: Bound String values. | String Text | Abstract @@ -86,9 +86,8 @@ importGraphAnalysis = Analysis{..} assign addr ty = modify (Map.insertWith (<>) addr (Set.singleton ty)) abstract _ name body = do loc <- ask - env <- gets @(Heap User Value) Map.keysSet - pure (Value (Closure loc name body env) mempty) - apply eval (Value (Closure loc name body _) _) a = local (const loc) $ do + pure (Value (Closure loc name body) mempty) + apply eval (Value (Closure loc name body) _) a = local (const loc) $ do addr <- alloc name assign addr a bind name addr (eval body) From 54430ac56dda57464a3966694b04254137b8f455 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 12:13:15 -0400 Subject: [PATCH 11/40] Abstract Semi over the term type. --- semantic-core/src/Analysis/ImportGraph.hs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/semantic-core/src/Analysis/ImportGraph.hs b/semantic-core/src/Analysis/ImportGraph.hs index 80487df910..d9dbef8395 100644 --- a/semantic-core/src/Analysis/ImportGraph.hs +++ b/semantic-core/src/Analysis/ImportGraph.hs @@ -31,7 +31,7 @@ import Prelude hiding (fail) type ImportGraph = Map.Map Text (Set.Set Text) data Value = Value - { valueSemi :: Semi + { valueSemi :: Semi (Term (Core.Ann :+: Core.Core) User) , valueGraph :: ImportGraph } deriving (Eq, Ord, Show) @@ -42,8 +42,8 @@ instance Semigroup Value where instance Monoid Value where mempty = Value Abstract mempty -data Semi - = Closure Loc User (Term (Core.Ann :+: Core.Core) User) +data Semi term + = Closure Loc User term -- FIXME: Bound String values. | String Text | Abstract From 3387eacf98dc481233e8a68008ec18405964e130 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 12:14:07 -0400 Subject: [PATCH 12/40] Abstract Value over the term type. --- semantic-core/src/Analysis/ImportGraph.hs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/semantic-core/src/Analysis/ImportGraph.hs b/semantic-core/src/Analysis/ImportGraph.hs index d9dbef8395..4567f612e6 100644 --- a/semantic-core/src/Analysis/ImportGraph.hs +++ b/semantic-core/src/Analysis/ImportGraph.hs @@ -30,16 +30,16 @@ import Prelude hiding (fail) type ImportGraph = Map.Map Text (Set.Set Text) -data Value = Value - { valueSemi :: Semi (Term (Core.Ann :+: Core.Core) User) +data Value term = Value + { valueSemi :: Semi term , valueGraph :: ImportGraph } deriving (Eq, Ord, Show) -instance Semigroup Value where +instance Semigroup (Value term) where Value _ g1 <> Value _ g2 = Value Abstract (Map.unionWith (<>) g1 g2) -instance Monoid Value where +instance Monoid (Value term) where mempty = Value Abstract mempty data Semi term @@ -50,7 +50,7 @@ data Semi term deriving (Eq, Ord, Show) -importGraph :: [File (Term (Core.Ann :+: Core.Core) User)] -> (Heap User Value, [File (Either (Loc, String) Value)]) +importGraph :: [File (Term (Core.Ann :+: Core.Core) User)] -> (Heap User (Value (Term (Core.Ann :+: Core.Core) User)), [File (Either (Loc, String) (Value (Term (Core.Ann :+: Core.Core) User)))]) importGraph = run . runFresh @@ -60,10 +60,10 @@ importGraph runFile :: ( Carrier sig m , Effect sig , Member Fresh sig - , Member (State (Heap User Value)) sig + , Member (State (Heap User (Value (Term (Core.Ann :+: Core.Core) User)))) sig ) => File (Term (Core.Ann :+: Core.Core) User) - -> m (File (Either (Loc, String) Value)) + -> m (File (Either (Loc, String) (Value (Term (Core.Ann :+: Core.Core) User)))) runFile file = traverse run file where run = runReader (fileLoc file) . runFailWithLoc @@ -74,10 +74,10 @@ runFile file = traverse run file importGraphAnalysis :: ( Alternative m , Carrier sig m , Member (Reader Loc) sig - , Member (State (Heap User Value)) sig + , Member (State (Heap User (Value (Term (Core.Ann :+: Core.Core) User)))) sig , MonadFail m ) - => Analysis (Term (Core.Ann :+: Core.Core)) User Value m + => Analysis (Term (Core.Ann :+: Core.Core)) User (Value (Term (Core.Ann :+: Core.Core) User)) m importGraphAnalysis = Analysis{..} where alloc = pure bind _ _ m = m From e022b47eeffab650a16a4c708bcbbce23410c1fa Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 12:14:31 -0400 Subject: [PATCH 13/40] Reformat the signature for importGraph. --- semantic-core/src/Analysis/ImportGraph.hs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/semantic-core/src/Analysis/ImportGraph.hs b/semantic-core/src/Analysis/ImportGraph.hs index 4567f612e6..94295c9dfd 100644 --- a/semantic-core/src/Analysis/ImportGraph.hs +++ b/semantic-core/src/Analysis/ImportGraph.hs @@ -50,7 +50,11 @@ data Semi term deriving (Eq, Ord, Show) -importGraph :: [File (Term (Core.Ann :+: Core.Core) User)] -> (Heap User (Value (Term (Core.Ann :+: Core.Core) User)), [File (Either (Loc, String) (Value (Term (Core.Ann :+: Core.Core) User)))]) +importGraph + :: [File (Term (Core.Ann :+: Core.Core) User)] + -> ( Heap User (Value (Term (Core.Ann :+: Core.Core) User)) + , [File (Either (Loc, String) (Value (Term (Core.Ann :+: Core.Core) User)))] + ) importGraph = run . runFresh From 7e7f33c6d119d838d8759b0452c1d5929b091acf Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 12:15:22 -0400 Subject: [PATCH 14/40] Generalize importGraphAnalysis over the term type. --- semantic-core/src/Analysis/ImportGraph.hs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/semantic-core/src/Analysis/ImportGraph.hs b/semantic-core/src/Analysis/ImportGraph.hs index 94295c9dfd..1e9cd9c343 100644 --- a/semantic-core/src/Analysis/ImportGraph.hs +++ b/semantic-core/src/Analysis/ImportGraph.hs @@ -78,10 +78,12 @@ runFile file = traverse run file importGraphAnalysis :: ( Alternative m , Carrier sig m , Member (Reader Loc) sig - , Member (State (Heap User (Value (Term (Core.Ann :+: Core.Core) User)))) sig + , Member (State (Heap User (Value (term User)))) sig , MonadFail m + , Ord (term User) + , Show (term User) ) - => Analysis (Term (Core.Ann :+: Core.Core)) User (Value (Term (Core.Ann :+: Core.Core) User)) m + => Analysis term User (Value (term User)) m importGraphAnalysis = Analysis{..} where alloc = pure bind _ _ m = m From 99d9a8d94df8c312a961defe8937901482f46521 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 12:19:10 -0400 Subject: [PATCH 15/40] Parameterize runFile by the evaluator. --- semantic-core/src/Analysis/Typecheck.hs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/semantic-core/src/Analysis/Typecheck.hs b/semantic-core/src/Analysis/Typecheck.hs index 069f58a684..0cece6bd79 100644 --- a/semantic-core/src/Analysis/Typecheck.hs +++ b/semantic-core/src/Analysis/Typecheck.hs @@ -1,4 +1,4 @@ -{-# LANGUAGE DeriveGeneric, DeriveTraversable, DerivingVia, FlexibleContexts, FlexibleInstances, LambdaCase, OverloadedStrings, QuantifiedConstraints, RecordWildCards, ScopedTypeVariables, StandaloneDeriving, TypeApplications, TypeOperators #-} +{-# LANGUAGE DeriveGeneric, DeriveTraversable, DerivingVia, FlexibleContexts, FlexibleInstances, LambdaCase, OverloadedStrings, QuantifiedConstraints, RankNTypes, RecordWildCards, ScopedTypeVariables, StandaloneDeriving, TypeApplications, TypeOperators #-} module Analysis.Typecheck ( Monotype (..) , Meta @@ -93,16 +93,17 @@ typecheckingFlowInsensitive . runFresh . runHeap "__semantic_root" . fmap (fmap (fmap (fmap generalize))) - . traverse runFile + . traverse (runFile eval) runFile :: ( Carrier sig m , Effect sig , Member Fresh sig , Member (State (Heap User (Term Monotype Meta))) sig ) - => File (Term (Core.Ann :+: Core.Core) User) + => (forall sig m . (Carrier sig m, Member (Reader Loc) sig, MonadFail m) => Analysis (Term (Core.Ann :+: Core.Core)) User (Term Monotype Meta) m -> (Term (Core.Ann :+: Core.Core) User -> m (Term Monotype Meta)) -> (Term (Core.Ann :+: Core.Core) User -> m (Term Monotype Meta))) + -> File (Term (Core.Ann :+: Core.Core) User) -> m (File (Either (Loc, String) (Term Monotype Meta))) -runFile file = traverse run file +runFile eval file = traverse run file where run = (\ m -> do (subst, t) <- m From 2666f6cbc8afdab05798f7cebafad88b0b83bd54 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 12:20:25 -0400 Subject: [PATCH 16/40] Generalize runFile over the term type. --- semantic-core/src/Analysis/Typecheck.hs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/semantic-core/src/Analysis/Typecheck.hs b/semantic-core/src/Analysis/Typecheck.hs index 0cece6bd79..8fb39ac3a2 100644 --- a/semantic-core/src/Analysis/Typecheck.hs +++ b/semantic-core/src/Analysis/Typecheck.hs @@ -99,9 +99,10 @@ runFile :: ( Carrier sig m , Effect sig , Member Fresh sig , Member (State (Heap User (Term Monotype Meta))) sig + , Ord (term User) ) - => (forall sig m . (Carrier sig m, Member (Reader Loc) sig, MonadFail m) => Analysis (Term (Core.Ann :+: Core.Core)) User (Term Monotype Meta) m -> (Term (Core.Ann :+: Core.Core) User -> m (Term Monotype Meta)) -> (Term (Core.Ann :+: Core.Core) User -> m (Term Monotype Meta))) - -> File (Term (Core.Ann :+: Core.Core) User) + => (forall sig m . (Carrier sig m, Member (Reader Loc) sig, MonadFail m) => Analysis term User (Term Monotype Meta) m -> (term User -> m (Term Monotype Meta)) -> (term User -> m (Term Monotype Meta))) + -> File (term User) -> m (File (Either (Loc, String) (Term Monotype Meta))) runFile eval file = traverse run file where run From 5c67ea0322b48137eb87c068a676ccc8a9f59adb Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 12:20:55 -0400 Subject: [PATCH 17/40] Reformat the signature for typecheckingFlowInsensitive. --- semantic-core/src/Analysis/Typecheck.hs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/semantic-core/src/Analysis/Typecheck.hs b/semantic-core/src/Analysis/Typecheck.hs index 8fb39ac3a2..3b11ba4798 100644 --- a/semantic-core/src/Analysis/Typecheck.hs +++ b/semantic-core/src/Analysis/Typecheck.hs @@ -87,7 +87,11 @@ generalize :: Term Monotype Meta -> Term (Polytype :+: Monotype) Void generalize ty = fromJust (closed (forAlls (IntSet.toList (mvs ty)) (hoistTerm R ty))) -typecheckingFlowInsensitive :: [File (Term (Core.Ann :+: Core.Core) User)] -> (Heap User (Term Monotype Meta), [File (Either (Loc, String) (Term (Polytype :+: Monotype) Void))]) +typecheckingFlowInsensitive + :: [File (Term (Core.Ann :+: Core.Core) User)] + -> ( Heap User (Term Monotype Meta) + , [File (Either (Loc, String) (Term (Polytype :+: Monotype) Void))] + ) typecheckingFlowInsensitive = run . runFresh From 665252017574ab2cf7e39f9c90edca6812f7d751 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 12:21:50 -0400 Subject: [PATCH 18/40] Reformat the signature for runFile. --- semantic-core/src/Analysis/Typecheck.hs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/semantic-core/src/Analysis/Typecheck.hs b/semantic-core/src/Analysis/Typecheck.hs index 3b11ba4798..5934a3819e 100644 --- a/semantic-core/src/Analysis/Typecheck.hs +++ b/semantic-core/src/Analysis/Typecheck.hs @@ -99,15 +99,16 @@ typecheckingFlowInsensitive . fmap (fmap (fmap (fmap generalize))) . traverse (runFile eval) -runFile :: ( Carrier sig m - , Effect sig - , Member Fresh sig - , Member (State (Heap User (Term Monotype Meta))) sig - , Ord (term User) - ) - => (forall sig m . (Carrier sig m, Member (Reader Loc) sig, MonadFail m) => Analysis term User (Term Monotype Meta) m -> (term User -> m (Term Monotype Meta)) -> (term User -> m (Term Monotype Meta))) - -> File (term User) - -> m (File (Either (Loc, String) (Term Monotype Meta))) +runFile + :: ( Carrier sig m + , Effect sig + , Member Fresh sig + , Member (State (Heap User (Term Monotype Meta))) sig + , Ord (term User) + ) + => (forall sig m . (Carrier sig m, Member (Reader Loc) sig, MonadFail m) => Analysis term User (Term Monotype Meta) m -> (term User -> m (Term Monotype Meta)) -> (term User -> m (Term Monotype Meta))) + -> File (term User) + -> m (File (Either (Loc, String) (Term Monotype Meta))) runFile eval file = traverse run file where run = (\ m -> do From 97ae6e9b21f2aefa24220fc8bf579938d788d446 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 12:23:07 -0400 Subject: [PATCH 19/40] Use a type synonym for types. --- semantic-core/src/Analysis/Typecheck.hs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/semantic-core/src/Analysis/Typecheck.hs b/semantic-core/src/Analysis/Typecheck.hs index 5934a3819e..b9f46cef38 100644 --- a/semantic-core/src/Analysis/Typecheck.hs +++ b/semantic-core/src/Analysis/Typecheck.hs @@ -46,6 +46,8 @@ data Monotype f a | Record (Map.Map User (f a)) deriving (Foldable, Functor, Generic1, Traversable) +type Type = Term Monotype Meta + -- FIXME: Union the effects/annotations on the operands. deriving via (Last (Term Monotype a)) instance Semigroup (Term Monotype a) @@ -89,7 +91,7 @@ generalize ty = fromJust (closed (forAlls (IntSet.toList (mvs ty)) (hoistTerm R typecheckingFlowInsensitive :: [File (Term (Core.Ann :+: Core.Core) User)] - -> ( Heap User (Term Monotype Meta) + -> ( Heap User Type , [File (Either (Loc, String) (Term (Polytype :+: Monotype) Void))] ) typecheckingFlowInsensitive @@ -103,17 +105,17 @@ runFile :: ( Carrier sig m , Effect sig , Member Fresh sig - , Member (State (Heap User (Term Monotype Meta))) sig + , Member (State (Heap User Type)) sig , Ord (term User) ) - => (forall sig m . (Carrier sig m, Member (Reader Loc) sig, MonadFail m) => Analysis term User (Term Monotype Meta) m -> (term User -> m (Term Monotype Meta)) -> (term User -> m (Term Monotype Meta))) + => (forall sig m . (Carrier sig m, Member (Reader Loc) sig, MonadFail m) => Analysis term User Type m -> (term User -> m Type) -> (term User -> m Type)) -> File (term User) - -> m (File (Either (Loc, String) (Term Monotype Meta))) + -> m (File (Either (Loc, String) Type)) runFile eval file = traverse run file where run = (\ m -> do (subst, t) <- m - modify @(Heap User (Term Monotype Meta)) (fmap (Set.map (substAll subst))) + modify @(Heap User Type) (fmap (Set.map (substAll subst))) pure (substAll subst <$> t)) . runState (mempty :: Substitution) . runReader (fileLoc file) @@ -133,9 +135,9 @@ typecheckingAnalysis , Carrier sig m , Member Fresh sig , Member (State (Set.Set Constraint)) sig - , Member (State (Heap User (Term Monotype Meta))) sig + , Member (State (Heap User Type)) sig ) - => Analysis term User (Term Monotype Meta) m + => Analysis term User Type m typecheckingAnalysis = Analysis{..} where alloc = pure bind _ _ m = m @@ -175,7 +177,7 @@ data Solution infix 5 := -meta :: (Carrier sig m, Member Fresh sig) => m (Term Monotype Meta) +meta :: (Carrier sig m, Member Fresh sig) => m Type meta = pure <$> Fresh.fresh unify :: (Carrier sig m, Member (State (Set.Set Constraint)) sig) => Term Monotype Meta -> Term Monotype Meta -> m () @@ -183,7 +185,7 @@ unify t1 t2 | t1 == t2 = pure () | otherwise = modify (<> Set.singleton (t1 :===: t2)) -type Substitution = IntMap.IntMap (Term Monotype Meta) +type Substitution = IntMap.IntMap Type solve :: (Carrier sig m, Member (State Substitution) sig, MonadFail m) => Set.Set Constraint -> m () solve cs = for_ cs solve From 813cde359e50f4cae9cd0a6af38cef7f44a4aca6 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 12:23:52 -0400 Subject: [PATCH 20/40] Reformat the signature for runFile to accommodate the evaluator. --- semantic-core/src/Analysis/Typecheck.hs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/semantic-core/src/Analysis/Typecheck.hs b/semantic-core/src/Analysis/Typecheck.hs index b9f46cef38..2787ef9fec 100644 --- a/semantic-core/src/Analysis/Typecheck.hs +++ b/semantic-core/src/Analysis/Typecheck.hs @@ -108,7 +108,12 @@ runFile , Member (State (Heap User Type)) sig , Ord (term User) ) - => (forall sig m . (Carrier sig m, Member (Reader Loc) sig, MonadFail m) => Analysis term User Type m -> (term User -> m Type) -> (term User -> m Type)) + => (forall sig m + . (Carrier sig m, Member (Reader Loc) sig, MonadFail m) + => Analysis term User Type m + -> (term User -> m Type) + -> (term User -> m Type) + ) -> File (term User) -> m (File (Either (Loc, String) Type)) runFile eval file = traverse run file From e2875572b9103522d3009832e2fa565c021a4728 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 12:25:03 -0400 Subject: [PATCH 21/40] Generalize typecheckingFlowInsensitive over the term type. --- semantic-core/src/Analysis/Typecheck.hs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/semantic-core/src/Analysis/Typecheck.hs b/semantic-core/src/Analysis/Typecheck.hs index 2787ef9fec..f5ae632ddd 100644 --- a/semantic-core/src/Analysis/Typecheck.hs +++ b/semantic-core/src/Analysis/Typecheck.hs @@ -17,7 +17,6 @@ import Control.Effect.Reader hiding (Local) import Control.Effect.State import Control.Monad ((>=>), unless) import Control.Monad.Module -import qualified Data.Core as Core import Data.File import Data.Foldable (for_) import Data.Function (fix) @@ -90,11 +89,18 @@ generalize ty = fromJust (closed (forAlls (IntSet.toList (mvs ty)) (hoistTerm R typecheckingFlowInsensitive - :: [File (Term (Core.Ann :+: Core.Core) User)] + :: Ord (term User) + => (forall sig m + . (Carrier sig m, Member (Reader Loc) sig, MonadFail m) + => Analysis term User Type m + -> (term User -> m Type) + -> (term User -> m Type) + ) + -> [File (term User)] -> ( Heap User Type , [File (Either (Loc, String) (Term (Polytype :+: Monotype) Void))] ) -typecheckingFlowInsensitive +typecheckingFlowInsensitive eval = run . runFresh . runHeap "__semantic_root" From 8b8a33071e893d16d7272b5f6d09bd370f99cb16 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 12:28:18 -0400 Subject: [PATCH 22/40] Generalize runFile over the term type. --- semantic-core/src/Analysis/ImportGraph.hs | 29 +++++++++++++++-------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/semantic-core/src/Analysis/ImportGraph.hs b/semantic-core/src/Analysis/ImportGraph.hs index 1e9cd9c343..c7a11f5514 100644 --- a/semantic-core/src/Analysis/ImportGraph.hs +++ b/semantic-core/src/Analysis/ImportGraph.hs @@ -1,4 +1,4 @@ -{-# LANGUAGE FlexibleContexts, OverloadedStrings, RecordWildCards, TypeApplications, TypeOperators #-} +{-# LANGUAGE FlexibleContexts, OverloadedStrings, RankNTypes, RecordWildCards, TypeApplications, TypeOperators #-} module Analysis.ImportGraph ( ImportGraph , importGraph @@ -59,16 +59,25 @@ importGraph = run . runFresh . runHeap "__semantic_root" - . traverse runFile + . traverse (runFile eval) -runFile :: ( Carrier sig m - , Effect sig - , Member Fresh sig - , Member (State (Heap User (Value (Term (Core.Ann :+: Core.Core) User)))) sig - ) - => File (Term (Core.Ann :+: Core.Core) User) - -> m (File (Either (Loc, String) (Value (Term (Core.Ann :+: Core.Core) User)))) -runFile file = traverse run file +runFile + :: ( Carrier sig m + , Effect sig + , Member Fresh sig + , Member (State (Heap User (Value (term User)))) sig + , Ord (term User) + , Show (term User) + ) + => (forall sig m + . (Carrier sig m, Member (Reader Loc) sig, MonadFail m) + => Analysis term User (Value (term User)) m + -> (term User -> m (Value (term User))) + -> (term User -> m (Value (term User))) + ) + -> File (term User) + -> m (File (Either (Loc, String) (Value (term User)))) +runFile eval file = traverse run file where run = runReader (fileLoc file) . runFailWithLoc . fmap fold From b92611458ebb9599a0e1a643e3c339e0580a860d Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 12:30:38 -0400 Subject: [PATCH 23/40] Change the kind of the term field to *. --- semantic-core/src/Analysis/Concrete.hs | 2 +- semantic-core/src/Analysis/Eval.hs | 6 +++--- semantic-core/src/Analysis/ImportGraph.hs | 24 +++++++++++------------ semantic-core/src/Analysis/Typecheck.hs | 16 +++++++-------- 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/semantic-core/src/Analysis/Concrete.hs b/semantic-core/src/Analysis/Concrete.hs index 011bd82a06..f9cd7ac8da 100644 --- a/semantic-core/src/Analysis/Concrete.hs +++ b/semantic-core/src/Analysis/Concrete.hs @@ -96,7 +96,7 @@ concreteAnalysis :: ( Carrier sig m , Member (State Heap) sig , MonadFail m ) - => Analysis (Term (Core.Ann :+: Core.Core)) Precise Concrete m + => Analysis (Term (Core.Ann :+: Core.Core) User) Precise Concrete m concreteAnalysis = Analysis{..} where alloc _ = fresh bind name addr m = local (Map.insert name addr) m diff --git a/semantic-core/src/Analysis/Eval.hs b/semantic-core/src/Analysis/Eval.hs index 161a5e6209..b34cb8a23e 100644 --- a/semantic-core/src/Analysis/Eval.hs +++ b/semantic-core/src/Analysis/Eval.hs @@ -33,7 +33,7 @@ eval :: ( Carrier sig m , MonadFail m , Semigroup value ) - => Analysis (Term (Ann :+: Core)) address value m + => Analysis (Term (Ann :+: Core) User) address value m -> (Term (Ann :+: Core) User -> m value) -> (Term (Ann :+: Core) User -> m value) eval Analysis{..} eval = \case @@ -217,8 +217,8 @@ data Analysis term address value m = Analysis , lookupEnv :: User -> m (Maybe address) , deref :: address -> m (Maybe value) , assign :: address -> value -> m () - , abstract :: (term User -> m value) -> User -> term User -> m value - , apply :: (term User -> m value) -> value -> value -> m value + , abstract :: (term -> m value) -> User -> term -> m value + , apply :: (term -> m value) -> value -> value -> m value , unit :: m value , bool :: Bool -> m value , asBool :: value -> m Bool diff --git a/semantic-core/src/Analysis/ImportGraph.hs b/semantic-core/src/Analysis/ImportGraph.hs index c7a11f5514..5c66f2d043 100644 --- a/semantic-core/src/Analysis/ImportGraph.hs +++ b/semantic-core/src/Analysis/ImportGraph.hs @@ -65,18 +65,18 @@ runFile :: ( Carrier sig m , Effect sig , Member Fresh sig - , Member (State (Heap User (Value (term User)))) sig - , Ord (term User) - , Show (term User) + , Member (State (Heap User (Value term))) sig + , Ord term + , Show term ) => (forall sig m . (Carrier sig m, Member (Reader Loc) sig, MonadFail m) - => Analysis term User (Value (term User)) m - -> (term User -> m (Value (term User))) - -> (term User -> m (Value (term User))) + => Analysis term User (Value term) m + -> (term -> m (Value term)) + -> (term -> m (Value term)) ) - -> File (term User) - -> m (File (Either (Loc, String) (Value (term User)))) + -> File term + -> m (File (Either (Loc, String) (Value term))) runFile eval file = traverse run file where run = runReader (fileLoc file) . runFailWithLoc @@ -87,12 +87,12 @@ runFile eval file = traverse run file importGraphAnalysis :: ( Alternative m , Carrier sig m , Member (Reader Loc) sig - , Member (State (Heap User (Value (term User)))) sig + , Member (State (Heap User (Value term))) sig , MonadFail m - , Ord (term User) - , Show (term User) + , Ord term + , Show term ) - => Analysis term User (Value (term User)) m + => Analysis term User (Value term) m importGraphAnalysis = Analysis{..} where alloc = pure bind _ _ m = m diff --git a/semantic-core/src/Analysis/Typecheck.hs b/semantic-core/src/Analysis/Typecheck.hs index f5ae632ddd..de920811ba 100644 --- a/semantic-core/src/Analysis/Typecheck.hs +++ b/semantic-core/src/Analysis/Typecheck.hs @@ -89,14 +89,14 @@ generalize ty = fromJust (closed (forAlls (IntSet.toList (mvs ty)) (hoistTerm R typecheckingFlowInsensitive - :: Ord (term User) + :: Ord term => (forall sig m . (Carrier sig m, Member (Reader Loc) sig, MonadFail m) => Analysis term User Type m - -> (term User -> m Type) - -> (term User -> m Type) + -> (term -> m Type) + -> (term -> m Type) ) - -> [File (term User)] + -> [File term] -> ( Heap User Type , [File (Either (Loc, String) (Term (Polytype :+: Monotype) Void))] ) @@ -112,15 +112,15 @@ runFile , Effect sig , Member Fresh sig , Member (State (Heap User Type)) sig - , Ord (term User) + , Ord term ) => (forall sig m . (Carrier sig m, Member (Reader Loc) sig, MonadFail m) => Analysis term User Type m - -> (term User -> m Type) - -> (term User -> m Type) + -> (term -> m Type) + -> (term -> m Type) ) - -> File (term User) + -> File term -> m (File (Either (Loc, String) Type)) runFile eval file = traverse run file where run From 4553d59faf237f16c5f5b187e48bf5fcdc7b0b54 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 12:31:52 -0400 Subject: [PATCH 24/40] Generalize importGraph over the term type. --- semantic-core/src/Analysis/ImportGraph.hs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/semantic-core/src/Analysis/ImportGraph.hs b/semantic-core/src/Analysis/ImportGraph.hs index 5c66f2d043..bf93232e22 100644 --- a/semantic-core/src/Analysis/ImportGraph.hs +++ b/semantic-core/src/Analysis/ImportGraph.hs @@ -14,7 +14,6 @@ import Control.Effect.Fresh import Control.Effect.Reader import Control.Effect.State import Control.Monad ((>=>)) -import qualified Data.Core as Core import Data.File import Data.Foldable (fold) import Data.Function (fix) @@ -24,7 +23,6 @@ import qualified Data.Map as Map import Data.Name import Data.Proxy import qualified Data.Set as Set -import Data.Term import Data.Text (Text) import Prelude hiding (fail) @@ -51,11 +49,18 @@ data Semi term importGraph - :: [File (Term (Core.Ann :+: Core.Core) User)] - -> ( Heap User (Value (Term (Core.Ann :+: Core.Core) User)) - , [File (Either (Loc, String) (Value (Term (Core.Ann :+: Core.Core) User)))] + :: (Ord term, Show term) + => (forall sig m + . (Carrier sig m, Member (Reader Loc) sig, MonadFail m) + => Analysis term User (Value term) m + -> (term -> m (Value term)) + -> (term -> m (Value term)) ) -importGraph + -> [File term] + -> ( Heap User (Value term) + , [File (Either (Loc, String) (Value term))] + ) +importGraph eval = run . runFresh . runHeap "__semantic_root" From fde2a448d38415ecc0de259784b22779bd27eaa9 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 12:34:04 -0400 Subject: [PATCH 25/40] Abstract Concrete over the term type. --- semantic-core/src/Analysis/Concrete.hs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/semantic-core/src/Analysis/Concrete.hs b/semantic-core/src/Analysis/Concrete.hs index f9cd7ac8da..ba1a617d08 100644 --- a/semantic-core/src/Analysis/Concrete.hs +++ b/semantic-core/src/Analysis/Concrete.hs @@ -41,16 +41,16 @@ type Env = Map.Map User Precise newtype FrameId = FrameId { unFrameId :: Precise } deriving (Eq, Ord, Show) -data Concrete - = Closure Loc User (Term (Core.Ann :+: Core.Core) User) Env +data Concrete term + = Closure Loc User term Env | Unit | Bool Bool | String Text | Record Env deriving (Eq, Ord, Show) - deriving Semigroup via Last Concrete + deriving Semigroup via Last (Concrete term) -recordFrame :: Concrete -> Maybe Env +recordFrame :: Concrete term -> Maybe Env recordFrame (Record frame) = Just frame recordFrame _ = Nothing @@ -59,7 +59,7 @@ newtype Frame = Frame } deriving (Eq, Ord, Show) -type Heap = IntMap.IntMap Concrete +type Heap = IntMap.IntMap (Concrete (Term (Core.Ann :+: Core.Core) User)) data Edge = Lexical | Import deriving (Eq, Ord, Show) @@ -69,7 +69,7 @@ data Edge = Lexical | Import -- -- >>> map fileBody (snd (concrete [File (Loc "bool" emptySpan) (Core.bool True)])) -- [Right (Bool True)] -concrete :: [File (Term (Core.Ann :+: Core.Core) User)] -> (Heap, [File (Either (Loc, String) Concrete)]) +concrete :: [File (Term (Core.Ann :+: Core.Core) User)] -> (Heap, [File (Either (Loc, String) (Concrete (Term (Core.Ann :+: Core.Core) User)))]) concrete = run . runFresh @@ -82,7 +82,7 @@ runFile :: ( Carrier sig m , Member (State Heap) sig ) => File (Term (Core.Ann :+: Core.Core) User) - -> m (File (Either (Loc, String) Concrete)) + -> m (File (Either (Loc, String) (Concrete (Term (Core.Ann :+: Core.Core) User)))) runFile file = traverse run file where run = runReader (fileLoc file) . runFailWithLoc @@ -96,7 +96,7 @@ concreteAnalysis :: ( Carrier sig m , Member (State Heap) sig , MonadFail m ) - => Analysis (Term (Core.Ann :+: Core.Core) User) Precise Concrete m + => Analysis (Term (Core.Ann :+: Core.Core) User) Precise (Concrete (Term (Core.Ann :+: Core.Core) User)) m concreteAnalysis = Analysis{..} where alloc _ = fresh bind name addr m = local (Map.insert name addr) m @@ -132,7 +132,7 @@ concreteAnalysis = Analysis{..} pure (val >>= lookupConcrete heap n) -lookupConcrete :: Heap -> User -> Concrete -> Maybe Precise +lookupConcrete :: Heap -> User -> Concrete (Term (Core.Ann :+: Core.Core) User) -> Maybe Precise lookupConcrete heap name = run . evalState IntSet.empty . runNonDet . inConcrete where -- look up the name in a concrete value inConcrete = inFrame <=< maybeA . recordFrame @@ -158,7 +158,7 @@ runHeap = runState mempty -- > λ let (heap, res) = concrete [ruby] -- > λ writeFile "/Users/rob/Desktop/heap.dot" (export (addressStyle heap) (heapAddressGraph heap)) -- > λ :!dot -Tsvg < ~/Desktop/heap.dot > ~/Desktop/heap.svg -heapGraph :: (Precise -> Concrete -> a) -> (Either Edge User -> Precise -> G.Graph a) -> Heap -> G.Graph a +heapGraph :: (Precise -> Concrete (Term (Core.Ann :+: Core.Core) User) -> a) -> (Either Edge User -> Precise -> G.Graph a) -> Heap -> G.Graph a heapGraph vertex edge h = foldr (uncurry graph) G.empty (IntMap.toList h) where graph k v rest = (G.vertex (vertex k v) `G.connect` outgoing v) `G.overlay` rest outgoing = \case @@ -168,7 +168,7 @@ heapGraph vertex edge h = foldr (uncurry graph) G.empty (IntMap.toList h) Closure _ _ _ env -> foldr (G.overlay . edge (Left Lexical)) G.empty env Record frame -> foldr (G.overlay . uncurry (edge . Right)) G.empty (Map.toList frame) -heapValueGraph :: Heap -> G.Graph Concrete +heapValueGraph :: Heap -> G.Graph (Concrete (Term (Core.Ann :+: Core.Core) User)) heapValueGraph h = heapGraph (const id) (const fromAddr) h where fromAddr addr = maybe G.empty G.vertex (IntMap.lookup addr h) @@ -193,7 +193,7 @@ addressStyle heap = (G.defaultStyle vertex) { G.edgeAttributes } data EdgeType = Edge Edge | Slot User - | Value Concrete + | Value (Concrete (Term (Core.Ann :+: Core.Core) User)) deriving (Eq, Ord, Show) From 2559f589a8a91d97be488f460a8ab328dd05f13a Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 12:35:02 -0400 Subject: [PATCH 26/40] Generalize Heap over the term type. --- semantic-core/src/Analysis/Concrete.hs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/semantic-core/src/Analysis/Concrete.hs b/semantic-core/src/Analysis/Concrete.hs index ba1a617d08..d2375517a9 100644 --- a/semantic-core/src/Analysis/Concrete.hs +++ b/semantic-core/src/Analysis/Concrete.hs @@ -59,7 +59,7 @@ newtype Frame = Frame } deriving (Eq, Ord, Show) -type Heap = IntMap.IntMap (Concrete (Term (Core.Ann :+: Core.Core) User)) +type Heap term = IntMap.IntMap (Concrete term) data Edge = Lexical | Import deriving (Eq, Ord, Show) @@ -69,7 +69,7 @@ data Edge = Lexical | Import -- -- >>> map fileBody (snd (concrete [File (Loc "bool" emptySpan) (Core.bool True)])) -- [Right (Bool True)] -concrete :: [File (Term (Core.Ann :+: Core.Core) User)] -> (Heap, [File (Either (Loc, String) (Concrete (Term (Core.Ann :+: Core.Core) User)))]) +concrete :: [File (Term (Core.Ann :+: Core.Core) User)] -> (Heap (Term (Core.Ann :+: Core.Core) User), [File (Either (Loc, String) (Concrete (Term (Core.Ann :+: Core.Core) User)))]) concrete = run . runFresh @@ -79,7 +79,7 @@ concrete runFile :: ( Carrier sig m , Effect sig , Member Fresh sig - , Member (State Heap) sig + , Member (State (Heap (Term (Core.Ann :+: Core.Core) User))) sig ) => File (Term (Core.Ann :+: Core.Core) User) -> m (File (Either (Loc, String) (Concrete (Term (Core.Ann :+: Core.Core) User)))) @@ -93,7 +93,7 @@ concreteAnalysis :: ( Carrier sig m , Member Fresh sig , Member (Reader Env) sig , Member (Reader Loc) sig - , Member (State Heap) sig + , Member (State (Heap (Term (Core.Ann :+: Core.Core) User))) sig , MonadFail m ) => Analysis (Term (Core.Ann :+: Core.Core) User) Precise (Concrete (Term (Core.Ann :+: Core.Core) User)) m @@ -132,7 +132,7 @@ concreteAnalysis = Analysis{..} pure (val >>= lookupConcrete heap n) -lookupConcrete :: Heap -> User -> Concrete (Term (Core.Ann :+: Core.Core) User) -> Maybe Precise +lookupConcrete :: Heap (Term (Core.Ann :+: Core.Core) User) -> User -> Concrete (Term (Core.Ann :+: Core.Core) User) -> Maybe Precise lookupConcrete heap name = run . evalState IntSet.empty . runNonDet . inConcrete where -- look up the name in a concrete value inConcrete = inFrame <=< maybeA . recordFrame @@ -149,7 +149,7 @@ lookupConcrete heap name = run . evalState IntSet.empty . runNonDet . inConcrete maybeA = maybe empty pure -runHeap :: StateC Heap m a -> m (Heap, a) +runHeap :: StateC (Heap (Term (Core.Ann :+: Core.Core) User)) m a -> m (Heap (Term (Core.Ann :+: Core.Core) User), a) runHeap = runState mempty @@ -158,7 +158,7 @@ runHeap = runState mempty -- > λ let (heap, res) = concrete [ruby] -- > λ writeFile "/Users/rob/Desktop/heap.dot" (export (addressStyle heap) (heapAddressGraph heap)) -- > λ :!dot -Tsvg < ~/Desktop/heap.dot > ~/Desktop/heap.svg -heapGraph :: (Precise -> Concrete (Term (Core.Ann :+: Core.Core) User) -> a) -> (Either Edge User -> Precise -> G.Graph a) -> Heap -> G.Graph a +heapGraph :: (Precise -> Concrete (Term (Core.Ann :+: Core.Core) User) -> a) -> (Either Edge User -> Precise -> G.Graph a) -> Heap (Term (Core.Ann :+: Core.Core) User) -> G.Graph a heapGraph vertex edge h = foldr (uncurry graph) G.empty (IntMap.toList h) where graph k v rest = (G.vertex (vertex k v) `G.connect` outgoing v) `G.overlay` rest outgoing = \case @@ -168,14 +168,14 @@ heapGraph vertex edge h = foldr (uncurry graph) G.empty (IntMap.toList h) Closure _ _ _ env -> foldr (G.overlay . edge (Left Lexical)) G.empty env Record frame -> foldr (G.overlay . uncurry (edge . Right)) G.empty (Map.toList frame) -heapValueGraph :: Heap -> G.Graph (Concrete (Term (Core.Ann :+: Core.Core) User)) +heapValueGraph :: Heap (Term (Core.Ann :+: Core.Core) User) -> G.Graph (Concrete (Term (Core.Ann :+: Core.Core) User)) heapValueGraph h = heapGraph (const id) (const fromAddr) h where fromAddr addr = maybe G.empty G.vertex (IntMap.lookup addr h) -heapAddressGraph :: Heap -> G.Graph (EdgeType, Precise) +heapAddressGraph :: Heap (Term (Core.Ann :+: Core.Core) User) -> G.Graph (EdgeType, Precise) heapAddressGraph = heapGraph (\ addr v -> (Value v, addr)) (fmap G.vertex . (,) . either Edge Slot) -addressStyle :: Heap -> G.Style (EdgeType, Precise) Text +addressStyle :: Heap (Term (Core.Ann :+: Core.Core) User) -> G.Style (EdgeType, Precise) Text addressStyle heap = (G.defaultStyle vertex) { G.edgeAttributes } where vertex (_, addr) = pack (show addr) <> " = " <> maybe "?" fromConcrete (IntMap.lookup addr heap) edgeAttributes _ (Slot name, _) = ["label" G.:= name] From 2dde20051effa36381bb744bd378955f53ad0a56 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 12:35:59 -0400 Subject: [PATCH 27/40] Generalize lookupConcrete over the term type. --- semantic-core/src/Analysis/Concrete.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/semantic-core/src/Analysis/Concrete.hs b/semantic-core/src/Analysis/Concrete.hs index d2375517a9..09de90cc7b 100644 --- a/semantic-core/src/Analysis/Concrete.hs +++ b/semantic-core/src/Analysis/Concrete.hs @@ -132,7 +132,7 @@ concreteAnalysis = Analysis{..} pure (val >>= lookupConcrete heap n) -lookupConcrete :: Heap (Term (Core.Ann :+: Core.Core) User) -> User -> Concrete (Term (Core.Ann :+: Core.Core) User) -> Maybe Precise +lookupConcrete :: Heap term -> User -> Concrete term -> Maybe Precise lookupConcrete heap name = run . evalState IntSet.empty . runNonDet . inConcrete where -- look up the name in a concrete value inConcrete = inFrame <=< maybeA . recordFrame From 1192971d382f4a903413f560f27f6f0caa0ea370 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 12:36:14 -0400 Subject: [PATCH 28/40] Generalize concreteAnalysis over the term type. --- semantic-core/src/Analysis/Concrete.hs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/semantic-core/src/Analysis/Concrete.hs b/semantic-core/src/Analysis/Concrete.hs index 09de90cc7b..28048ae355 100644 --- a/semantic-core/src/Analysis/Concrete.hs +++ b/semantic-core/src/Analysis/Concrete.hs @@ -90,13 +90,15 @@ runFile file = traverse run file . fix (eval concreteAnalysis) concreteAnalysis :: ( Carrier sig m + , Foldable term , Member Fresh sig , Member (Reader Env) sig , Member (Reader Loc) sig - , Member (State (Heap (Term (Core.Ann :+: Core.Core) User))) sig + , Member (State (Heap (term User))) sig , MonadFail m + , Show (term User) ) - => Analysis (Term (Core.Ann :+: Core.Core) User) Precise (Concrete (Term (Core.Ann :+: Core.Core) User)) m + => Analysis (term User) Precise (Concrete (term User)) m concreteAnalysis = Analysis{..} where alloc _ = fresh bind name addr m = local (Map.insert name addr) m From c3cf286d9dee938a0e6fac7561b185fdb43c4469 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 12:36:44 -0400 Subject: [PATCH 29/40] Generalize EdgeType over the term type. --- semantic-core/src/Analysis/Concrete.hs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/semantic-core/src/Analysis/Concrete.hs b/semantic-core/src/Analysis/Concrete.hs index 28048ae355..5a230c0429 100644 --- a/semantic-core/src/Analysis/Concrete.hs +++ b/semantic-core/src/Analysis/Concrete.hs @@ -174,10 +174,10 @@ heapValueGraph :: Heap (Term (Core.Ann :+: Core.Core) User) -> G.Graph (Concrete heapValueGraph h = heapGraph (const id) (const fromAddr) h where fromAddr addr = maybe G.empty G.vertex (IntMap.lookup addr h) -heapAddressGraph :: Heap (Term (Core.Ann :+: Core.Core) User) -> G.Graph (EdgeType, Precise) +heapAddressGraph :: Heap (Term (Core.Ann :+: Core.Core) User) -> G.Graph (EdgeType (Term (Core.Ann :+: Core.Core) User), Precise) heapAddressGraph = heapGraph (\ addr v -> (Value v, addr)) (fmap G.vertex . (,) . either Edge Slot) -addressStyle :: Heap (Term (Core.Ann :+: Core.Core) User) -> G.Style (EdgeType, Precise) Text +addressStyle :: Heap (Term (Core.Ann :+: Core.Core) User) -> G.Style (EdgeType (Term (Core.Ann :+: Core.Core) User), Precise) Text addressStyle heap = (G.defaultStyle vertex) { G.edgeAttributes } where vertex (_, addr) = pack (show addr) <> " = " <> maybe "?" fromConcrete (IntMap.lookup addr heap) edgeAttributes _ (Slot name, _) = ["label" G.:= name] @@ -192,10 +192,10 @@ addressStyle heap = (G.defaultStyle vertex) { G.edgeAttributes } Record _ -> "{}" showPos (Pos l c) = pack (show l) <> ":" <> pack (show c) -data EdgeType +data EdgeType term = Edge Edge | Slot User - | Value (Concrete (Term (Core.Ann :+: Core.Core) User)) + | Value (Concrete term) deriving (Eq, Ord, Show) From ea174b2144407adc389d682f0068f28dc875a1dd Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 12:36:58 -0400 Subject: [PATCH 30/40] Generalize runHeap over the term type. --- semantic-core/src/Analysis/Concrete.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/semantic-core/src/Analysis/Concrete.hs b/semantic-core/src/Analysis/Concrete.hs index 5a230c0429..6e36ed5ff6 100644 --- a/semantic-core/src/Analysis/Concrete.hs +++ b/semantic-core/src/Analysis/Concrete.hs @@ -151,7 +151,7 @@ lookupConcrete heap name = run . evalState IntSet.empty . runNonDet . inConcrete maybeA = maybe empty pure -runHeap :: StateC (Heap (Term (Core.Ann :+: Core.Core) User)) m a -> m (Heap (Term (Core.Ann :+: Core.Core) User), a) +runHeap :: StateC (Heap term) m a -> m (Heap term, a) runHeap = runState mempty From 021350b6da2743f33cf002672a5bda0b242446d7 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 12:37:25 -0400 Subject: [PATCH 31/40] Generalize heapGraph over the term type. --- semantic-core/src/Analysis/Concrete.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/semantic-core/src/Analysis/Concrete.hs b/semantic-core/src/Analysis/Concrete.hs index 6e36ed5ff6..465920f3c2 100644 --- a/semantic-core/src/Analysis/Concrete.hs +++ b/semantic-core/src/Analysis/Concrete.hs @@ -160,7 +160,7 @@ runHeap = runState mempty -- > λ let (heap, res) = concrete [ruby] -- > λ writeFile "/Users/rob/Desktop/heap.dot" (export (addressStyle heap) (heapAddressGraph heap)) -- > λ :!dot -Tsvg < ~/Desktop/heap.dot > ~/Desktop/heap.svg -heapGraph :: (Precise -> Concrete (Term (Core.Ann :+: Core.Core) User) -> a) -> (Either Edge User -> Precise -> G.Graph a) -> Heap (Term (Core.Ann :+: Core.Core) User) -> G.Graph a +heapGraph :: (Precise -> Concrete term -> a) -> (Either Edge User -> Precise -> G.Graph a) -> Heap term -> G.Graph a heapGraph vertex edge h = foldr (uncurry graph) G.empty (IntMap.toList h) where graph k v rest = (G.vertex (vertex k v) `G.connect` outgoing v) `G.overlay` rest outgoing = \case From a549039dd3d21f4bd294fd034687df98e9462b35 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 12:37:39 -0400 Subject: [PATCH 32/40] Generalize heapValueGraph over the term type. --- semantic-core/src/Analysis/Concrete.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/semantic-core/src/Analysis/Concrete.hs b/semantic-core/src/Analysis/Concrete.hs index 465920f3c2..8a94d0dcb7 100644 --- a/semantic-core/src/Analysis/Concrete.hs +++ b/semantic-core/src/Analysis/Concrete.hs @@ -170,7 +170,7 @@ heapGraph vertex edge h = foldr (uncurry graph) G.empty (IntMap.toList h) Closure _ _ _ env -> foldr (G.overlay . edge (Left Lexical)) G.empty env Record frame -> foldr (G.overlay . uncurry (edge . Right)) G.empty (Map.toList frame) -heapValueGraph :: Heap (Term (Core.Ann :+: Core.Core) User) -> G.Graph (Concrete (Term (Core.Ann :+: Core.Core) User)) +heapValueGraph :: Heap term -> G.Graph (Concrete term) heapValueGraph h = heapGraph (const id) (const fromAddr) h where fromAddr addr = maybe G.empty G.vertex (IntMap.lookup addr h) From bd8f0ca4c16ca4dfd87e8f9669d69ba35c9bd5f5 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 12:37:54 -0400 Subject: [PATCH 33/40] Generalize heapAddressGraph over the term type. --- semantic-core/src/Analysis/Concrete.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/semantic-core/src/Analysis/Concrete.hs b/semantic-core/src/Analysis/Concrete.hs index 8a94d0dcb7..efe0e13361 100644 --- a/semantic-core/src/Analysis/Concrete.hs +++ b/semantic-core/src/Analysis/Concrete.hs @@ -174,7 +174,7 @@ heapValueGraph :: Heap term -> G.Graph (Concrete term) heapValueGraph h = heapGraph (const id) (const fromAddr) h where fromAddr addr = maybe G.empty G.vertex (IntMap.lookup addr h) -heapAddressGraph :: Heap (Term (Core.Ann :+: Core.Core) User) -> G.Graph (EdgeType (Term (Core.Ann :+: Core.Core) User), Precise) +heapAddressGraph :: Heap term -> G.Graph (EdgeType term, Precise) heapAddressGraph = heapGraph (\ addr v -> (Value v, addr)) (fmap G.vertex . (,) . either Edge Slot) addressStyle :: Heap (Term (Core.Ann :+: Core.Core) User) -> G.Style (EdgeType (Term (Core.Ann :+: Core.Core) User), Precise) Text From d8175305da9c18b1047f7c5c93824625c93bbd49 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 12:38:10 -0400 Subject: [PATCH 34/40] Generalize addressStyle over the term type. --- semantic-core/src/Analysis/Concrete.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/semantic-core/src/Analysis/Concrete.hs b/semantic-core/src/Analysis/Concrete.hs index efe0e13361..6ae8ffba9f 100644 --- a/semantic-core/src/Analysis/Concrete.hs +++ b/semantic-core/src/Analysis/Concrete.hs @@ -177,7 +177,7 @@ heapValueGraph h = heapGraph (const id) (const fromAddr) h heapAddressGraph :: Heap term -> G.Graph (EdgeType term, Precise) heapAddressGraph = heapGraph (\ addr v -> (Value v, addr)) (fmap G.vertex . (,) . either Edge Slot) -addressStyle :: Heap (Term (Core.Ann :+: Core.Core) User) -> G.Style (EdgeType (Term (Core.Ann :+: Core.Core) User), Precise) Text +addressStyle :: Heap term -> G.Style (EdgeType term, Precise) Text addressStyle heap = (G.defaultStyle vertex) { G.edgeAttributes } where vertex (_, addr) = pack (show addr) <> " = " <> maybe "?" fromConcrete (IntMap.lookup addr heap) edgeAttributes _ (Slot name, _) = ["label" G.:= name] From da0d780f8157fa7efb136d0c8c08a8af61116711 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 12:54:01 -0400 Subject: [PATCH 35/40] Generalize runFile over the term type. --- semantic-core/src/Analysis/Concrete.hs | 31 +++++++++++++++++--------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/semantic-core/src/Analysis/Concrete.hs b/semantic-core/src/Analysis/Concrete.hs index 6ae8ffba9f..b448703536 100644 --- a/semantic-core/src/Analysis/Concrete.hs +++ b/semantic-core/src/Analysis/Concrete.hs @@ -1,4 +1,4 @@ -{-# LANGUAGE DerivingVia, FlexibleContexts, FlexibleInstances, LambdaCase, MultiParamTypeClasses, NamedFieldPuns, OverloadedStrings, RecordWildCards, TypeOperators, UndecidableInstances #-} +{-# LANGUAGE DerivingVia, FlexibleContexts, FlexibleInstances, LambdaCase, MultiParamTypeClasses, NamedFieldPuns, OverloadedStrings, RankNTypes, RecordWildCards, TypeOperators, UndecidableInstances #-} module Analysis.Concrete ( Concrete(..) , concrete @@ -74,16 +74,25 @@ concrete = run . runFresh . runHeap - . traverse runFile - -runFile :: ( Carrier sig m - , Effect sig - , Member Fresh sig - , Member (State (Heap (Term (Core.Ann :+: Core.Core) User))) sig - ) - => File (Term (Core.Ann :+: Core.Core) User) - -> m (File (Either (Loc, String) (Concrete (Term (Core.Ann :+: Core.Core) User)))) -runFile file = traverse run file + . traverse (runFile eval) + +runFile + :: ( Carrier sig m + , Effect sig + , Foldable term + , Member Fresh sig + , Member (State (Heap (term User))) sig + , Show (term User) + ) + => (forall sig m + . (Carrier sig m, Member (Reader Loc) sig, MonadFail m) + => Analysis (term User) Precise (Concrete (term User)) m + -> (term User -> m (Concrete (term User))) + -> (term User -> m (Concrete (term User))) + ) + -> File (term User) + -> m (File (Either (Loc, String) (Concrete (term User)))) +runFile eval file = traverse run file where run = runReader (fileLoc file) . runFailWithLoc . runReader (mempty :: Env) From 15e5731d935eaa872706fe3acb56c570a9c00a23 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 12:55:13 -0400 Subject: [PATCH 36/40] Generalize concrete over the term types. --- semantic-core/src/Analysis/Concrete.hs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/semantic-core/src/Analysis/Concrete.hs b/semantic-core/src/Analysis/Concrete.hs index b448703536..3d22c21fd7 100644 --- a/semantic-core/src/Analysis/Concrete.hs +++ b/semantic-core/src/Analysis/Concrete.hs @@ -20,7 +20,6 @@ import Control.Effect.NonDet import Control.Effect.Reader hiding (Local) import Control.Effect.State import Control.Monad ((<=<), guard) -import qualified Data.Core as Core import Data.File import Data.Function (fix) import qualified Data.IntMap as IntMap @@ -30,7 +29,6 @@ import qualified Data.Map as Map import Data.Name import Data.Semigroup (Last (..)) import qualified Data.Set as Set -import Data.Term import Data.Text (Text, pack) import Data.Traversable (for) import Prelude hiding (fail) @@ -69,8 +67,17 @@ data Edge = Lexical | Import -- -- >>> map fileBody (snd (concrete [File (Loc "bool" emptySpan) (Core.bool True)])) -- [Right (Bool True)] -concrete :: [File (Term (Core.Ann :+: Core.Core) User)] -> (Heap (Term (Core.Ann :+: Core.Core) User), [File (Either (Loc, String) (Concrete (Term (Core.Ann :+: Core.Core) User)))]) concrete + :: (Foldable term, Show (term User)) + => (forall sig m + . (Carrier sig m, Member (Reader Loc) sig, MonadFail m) + => Analysis (term User) Precise (Concrete (term User)) m + -> (term User -> m (Concrete (term User))) + -> (term User -> m (Concrete (term User))) + ) + -> [File (term User)] + -> (Heap (term User), [File (Either (Loc, String) (Concrete (term User)))]) +concrete eval = run . runFresh . runHeap From 2c28e536e99ab87ce9dfda6daf75952ffe2e4726 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 12:57:44 -0400 Subject: [PATCH 37/40] :fire: the FrameId reader effect. --- semantic-core/src/Analysis/FlowInsensitive.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/semantic-core/src/Analysis/FlowInsensitive.hs b/semantic-core/src/Analysis/FlowInsensitive.hs index de9a771764..569dac1fa0 100644 --- a/semantic-core/src/Analysis/FlowInsensitive.hs +++ b/semantic-core/src/Analysis/FlowInsensitive.hs @@ -67,8 +67,8 @@ cacheTerm eval term = do result <- eval term result <$ modify (Cache . Map.insertWith (<>) term (Set.singleton (result :: a)) . unCache) -runHeap :: address -> ReaderC (FrameId address) (StateC (Heap address a) m) b -> m (Heap address a, b) -runHeap addr m = runState (Map.singleton addr Set.empty) (runReader (FrameId addr) m) +runHeap :: address -> StateC (Heap address a) m b -> m (Heap address a, b) +runHeap addr m = runState (Map.singleton addr Set.empty) m -- | Fold a collection by mapping each element onto an 'Alternative' action. foldMapA :: (Alternative m, Foldable t) => (b -> m a) -> t b -> m a From e9853c1a3ff8610be190d070c7874529bc2dce5c Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 12:58:20 -0400 Subject: [PATCH 38/40] Avoid allocating a useless cell. --- semantic-core/src/Analysis/FlowInsensitive.hs | 4 ++-- semantic-core/src/Analysis/ImportGraph.hs | 2 +- semantic-core/src/Analysis/Typecheck.hs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/semantic-core/src/Analysis/FlowInsensitive.hs b/semantic-core/src/Analysis/FlowInsensitive.hs index 569dac1fa0..b3c6bcaa08 100644 --- a/semantic-core/src/Analysis/FlowInsensitive.hs +++ b/semantic-core/src/Analysis/FlowInsensitive.hs @@ -67,8 +67,8 @@ cacheTerm eval term = do result <- eval term result <$ modify (Cache . Map.insertWith (<>) term (Set.singleton (result :: a)) . unCache) -runHeap :: address -> StateC (Heap address a) m b -> m (Heap address a, b) -runHeap addr m = runState (Map.singleton addr Set.empty) m +runHeap :: StateC (Heap address a) m b -> m (Heap address a, b) +runHeap m = runState (Map.empty) m -- | Fold a collection by mapping each element onto an 'Alternative' action. foldMapA :: (Alternative m, Foldable t) => (b -> m a) -> t b -> m a diff --git a/semantic-core/src/Analysis/ImportGraph.hs b/semantic-core/src/Analysis/ImportGraph.hs index bf93232e22..8f82308f07 100644 --- a/semantic-core/src/Analysis/ImportGraph.hs +++ b/semantic-core/src/Analysis/ImportGraph.hs @@ -63,7 +63,7 @@ importGraph importGraph eval = run . runFresh - . runHeap "__semantic_root" + . runHeap . traverse (runFile eval) runFile diff --git a/semantic-core/src/Analysis/Typecheck.hs b/semantic-core/src/Analysis/Typecheck.hs index de920811ba..e6c3ae79cb 100644 --- a/semantic-core/src/Analysis/Typecheck.hs +++ b/semantic-core/src/Analysis/Typecheck.hs @@ -103,7 +103,7 @@ typecheckingFlowInsensitive typecheckingFlowInsensitive eval = run . runFresh - . runHeap "__semantic_root" + . runHeap . fmap (fmap (fmap (fmap generalize))) . traverse (runFile eval) From 0b86f913ee628ab5608f6f2c4fb732f19990d28d Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 12:59:29 -0400 Subject: [PATCH 39/40] Clean up some language extensions. --- semantic-core/src/Analysis/ImportGraph.hs | 2 +- semantic-core/src/Analysis/Typecheck.hs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/semantic-core/src/Analysis/ImportGraph.hs b/semantic-core/src/Analysis/ImportGraph.hs index 8f82308f07..6b3bf28cdc 100644 --- a/semantic-core/src/Analysis/ImportGraph.hs +++ b/semantic-core/src/Analysis/ImportGraph.hs @@ -1,4 +1,4 @@ -{-# LANGUAGE FlexibleContexts, OverloadedStrings, RankNTypes, RecordWildCards, TypeApplications, TypeOperators #-} +{-# LANGUAGE FlexibleContexts, RankNTypes, RecordWildCards, TypeApplications #-} module Analysis.ImportGraph ( ImportGraph , importGraph diff --git a/semantic-core/src/Analysis/Typecheck.hs b/semantic-core/src/Analysis/Typecheck.hs index e6c3ae79cb..9f1e3f9fd3 100644 --- a/semantic-core/src/Analysis/Typecheck.hs +++ b/semantic-core/src/Analysis/Typecheck.hs @@ -1,4 +1,4 @@ -{-# LANGUAGE DeriveGeneric, DeriveTraversable, DerivingVia, FlexibleContexts, FlexibleInstances, LambdaCase, OverloadedStrings, QuantifiedConstraints, RankNTypes, RecordWildCards, ScopedTypeVariables, StandaloneDeriving, TypeApplications, TypeOperators #-} +{-# LANGUAGE DeriveGeneric, DeriveTraversable, DerivingVia, FlexibleContexts, FlexibleInstances, LambdaCase, QuantifiedConstraints, RankNTypes, RecordWildCards, ScopedTypeVariables, StandaloneDeriving, TypeApplications, TypeOperators #-} module Analysis.Typecheck ( Monotype (..) , Meta From bd5aea62b37c61cf86cb2ec5a5aaecc398de0668 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 29 Jul 2019 13:04:15 -0400 Subject: [PATCH 40/40] Fix the doctests of the concrete analysis. --- semantic-core/src/Analysis/Concrete.hs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/semantic-core/src/Analysis/Concrete.hs b/semantic-core/src/Analysis/Concrete.hs index 3d22c21fd7..4e454ab815 100644 --- a/semantic-core/src/Analysis/Concrete.hs +++ b/semantic-core/src/Analysis/Concrete.hs @@ -65,7 +65,7 @@ data Edge = Lexical | Import -- | Concrete evaluation of a term to a value. -- --- >>> map fileBody (snd (concrete [File (Loc "bool" emptySpan) (Core.bool True)])) +-- >>> map fileBody (snd (concrete eval [File (Loc "bool" emptySpan) (Core.bool True)])) -- [Right (Bool True)] concrete :: (Foldable term, Show (term User)) @@ -217,3 +217,4 @@ data EdgeType term -- $setup -- >>> :seti -XOverloadedStrings +-- >>> import qualified Data.Core as Core