1
1
mirror of https://github.com/github/semantic.git synced 2024-11-28 10:15:55 +03:00

Specialize Concrete to Name.

This commit is contained in:
Rob Rix 2019-11-05 11:32:22 -05:00
parent 29b117033b
commit 398d377e35
No known key found for this signature in database
GPG Key ID: F188A01508EA1CF7

View File

@ -42,21 +42,21 @@ type Env name = Map.Map name Precise
newtype FrameId = FrameId { unFrameId :: Precise } newtype FrameId = FrameId { unFrameId :: Precise }
deriving (Eq, Ord, Show) deriving (Eq, Ord, Show)
data Concrete term name data Concrete term
= Closure Path.AbsRelFile Span name (term name) (Env name) = Closure Path.AbsRelFile Span Name term (Env Name)
| Unit | Unit
| Bool Bool | Bool Bool
| String Text | String Text
| Record (Env name) | Record (Env Name)
deriving (Eq, Ord, Show) deriving (Eq, Ord, Show)
-- NB: We derive the 'Semigroup' instance for 'Concrete' to take the second argument. This is equivalent to stating that the return value of an imperative sequence of statements is the value of its final statement. -- NB: We derive the 'Semigroup' instance for 'Concrete' to take the second argument. This is equivalent to stating that the return value of an imperative sequence of statements is the value of its final statement.
deriving Semigroup via Last (Concrete term name) deriving Semigroup via Last (Concrete term)
recordFrame :: Concrete term name -> Maybe (Env name) recordFrame :: Concrete term -> Maybe (Env Name)
recordFrame (Record frame) = Just frame recordFrame (Record frame) = Just frame
recordFrame _ = Nothing recordFrame _ = Nothing
type Heap term name = IntMap.IntMap (Concrete term name) type Heap term = IntMap.IntMap (Concrete term)
concrete concrete
@ -65,12 +65,12 @@ concrete
) )
=> (forall sig m => (forall sig m
. (Carrier sig m, Member (Reader Path.AbsRelFile) sig, Member (Reader Span) sig, MonadFail m) . (Carrier sig m, Member (Reader Path.AbsRelFile) sig, Member (Reader Span) sig, MonadFail m)
=> Analysis term Name Precise (Concrete term Name) m => Analysis term Name Precise (Concrete (term Name)) m
-> (term Name -> m (Concrete term Name)) -> (term Name -> m (Concrete (term Name)))
-> (term Name -> m (Concrete term Name)) -> (term Name -> m (Concrete (term Name)))
) )
-> [File (term Name)] -> [File (term Name)]
-> (Heap term Name, [File (Either (Path.AbsRelFile, Span, String) (Concrete term Name))]) -> (Heap (term Name), [File (Either (Path.AbsRelFile, Span, String) (Concrete (term Name)))])
concrete eval concrete eval
= run = run
. runFresh . runFresh
@ -83,18 +83,18 @@ runFile
, Effect sig , Effect sig
, Foldable term , Foldable term
, Member Fresh sig , Member Fresh sig
, Member (A.Heap Precise (Concrete term Name)) sig , Member (A.Heap Precise (Concrete (term Name))) sig
, Member (State (Heap term Name)) sig , Member (State (Heap (term Name))) sig
, Show (term Name) , Show (term Name)
) )
=> (forall sig m => (forall sig m
. (Carrier sig m, Member (Reader Path.AbsRelFile) sig, Member (Reader Span) sig, MonadFail m) . (Carrier sig m, Member (Reader Path.AbsRelFile) sig, Member (Reader Span) sig, MonadFail m)
=> Analysis term Name Precise (Concrete term Name) m => Analysis term Name Precise (Concrete (term Name)) m
-> (term Name -> m (Concrete term Name)) -> (term Name -> m (Concrete (term Name)))
-> (term Name -> m (Concrete term Name)) -> (term Name -> m (Concrete (term Name)))
) )
-> File (term Name) -> File (term Name)
-> m (File (Either (Path.AbsRelFile, Span, String) (Concrete term Name))) -> m (File (Either (Path.AbsRelFile, Span, String) (Concrete (term Name))))
runFile eval file = traverse run file runFile eval file = traverse run file
where run = runReader (filePath file) where run = runReader (filePath file)
. runReader (fileSpan file) . runReader (fileSpan file)
@ -108,15 +108,15 @@ concreteAnalysis
. ( Carrier sig m . ( Carrier sig m
, Foldable term , Foldable term
, Member (A.Env Name Precise) sig , Member (A.Env Name Precise) sig
, Member (A.Heap Precise (Concrete term Name)) sig , Member (A.Heap Precise (Concrete (term Name))) sig
, Member (Reader (Env Name)) sig , Member (Reader (Env Name)) sig
, Member (Reader Path.AbsRelFile) sig , Member (Reader Path.AbsRelFile) sig
, Member (Reader Span) sig , Member (Reader Span) sig
, Member (State (Heap term Name)) sig , Member (State (Heap (term Name))) sig
, MonadFail m , MonadFail m
, Show (term Name) , Show (term Name)
) )
=> Analysis term Name Precise (Concrete term Name) m => Analysis term Name Precise (Concrete (term Name)) m
concreteAnalysis = Analysis{..} concreteAnalysis = Analysis{..}
where abstract _ name body = do where abstract _ name body = do
path <- ask path <- ask
@ -143,12 +143,12 @@ concreteAnalysis = Analysis{..}
pure (name, addr) pure (name, addr)
pure (Record (Map.fromList fields')) pure (Record (Map.fromList fields'))
addr ... n = do addr ... n = do
val <- A.deref @Precise @(Concrete term Name) addr val <- A.deref @Precise @(Concrete (term Name)) addr
heap <- get heap <- get
pure (val >>= lookupConcrete heap n) pure (val >>= lookupConcrete heap n)
lookupConcrete :: Heap term Name -> Name -> Concrete term Name -> Maybe Precise lookupConcrete :: Heap (term Name) -> Name -> Concrete (term Name) -> Maybe Precise
lookupConcrete heap name = run . evalState IntSet.empty . runNonDet . inConcrete lookupConcrete heap name = run . evalState IntSet.empty . runNonDet . inConcrete
where -- look up the name in a concrete value where -- look up the name in a concrete value
inConcrete = inFrame <=< maybeA . recordFrame inConcrete = inFrame <=< maybeA . recordFrame
@ -170,7 +170,7 @@ lookupConcrete heap name = run . evalState IntSet.empty . runNonDet . inConcrete
-- > λ let (heap, res) = concrete [ruby] -- > λ let (heap, res) = concrete [ruby]
-- > λ writeFile "/Users/rob/Desktop/heap.dot" (export (addressStyle heap) (heapAddressGraph heap)) -- > λ writeFile "/Users/rob/Desktop/heap.dot" (export (addressStyle heap) (heapAddressGraph heap))
-- > λ :!dot -Tsvg < ~/Desktop/heap.dot > ~/Desktop/heap.svg -- > λ :!dot -Tsvg < ~/Desktop/heap.dot > ~/Desktop/heap.svg
heapGraph :: (Precise -> Concrete term Name -> a) -> (Either Edge Name -> Precise -> G.Graph a) -> Heap term Name -> G.Graph a heapGraph :: (Precise -> Concrete (term Name) -> a) -> (Either Edge Name -> Precise -> G.Graph a) -> Heap (term Name) -> G.Graph a
heapGraph vertex edge h = foldr (uncurry graph) G.empty (IntMap.toList h) 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 where graph k v rest = (G.vertex (vertex k v) `G.connect` outgoing v) `G.overlay` rest
outgoing = \case outgoing = \case
@ -180,14 +180,14 @@ heapGraph vertex edge h = foldr (uncurry graph) G.empty (IntMap.toList h)
Closure _ _ _ _ env -> foldr (G.overlay . edge (Left Lexical)) G.empty env Closure _ _ _ _ env -> foldr (G.overlay . edge (Left Lexical)) G.empty env
Record frame -> Map.foldrWithKey (\ k -> G.overlay . edge (Right k)) G.empty frame Record frame -> Map.foldrWithKey (\ k -> G.overlay . edge (Right k)) G.empty frame
heapValueGraph :: Heap term Name -> G.Graph (Concrete term Name) heapValueGraph :: Heap (term Name) -> G.Graph (Concrete (term Name))
heapValueGraph h = heapGraph (const id) (const fromAddr) h heapValueGraph h = heapGraph (const id) (const fromAddr) h
where fromAddr addr = maybe G.empty G.vertex (IntMap.lookup addr h) where fromAddr addr = maybe G.empty G.vertex (IntMap.lookup addr h)
heapAddressGraph :: Heap term Name -> G.Graph (EdgeType term Name, Precise) heapAddressGraph :: Heap (term Name) -> G.Graph (EdgeType (term Name) Name, Precise)
heapAddressGraph = heapGraph (\ addr v -> (Value v, addr)) (fmap G.vertex . (,) . either Edge Slot) heapAddressGraph = heapGraph (\ addr v -> (Value v, addr)) (fmap G.vertex . (,) . either Edge Slot)
addressStyle :: Heap term Name -> G.Style (EdgeType term Name, Precise) Text addressStyle :: Heap (term Name) -> G.Style (EdgeType (term Name) Name, Precise) Text
addressStyle heap = (G.defaultStyle vertex) { G.edgeAttributes } addressStyle heap = (G.defaultStyle vertex) { G.edgeAttributes }
where vertex (_, addr) = pack (show addr) <> " = " <> maybe "?" fromConcrete (IntMap.lookup addr heap) where vertex (_, addr) = pack (show addr) <> " = " <> maybe "?" fromConcrete (IntMap.lookup addr heap)
edgeAttributes _ (Slot name, _) = ["label" G.:= unName name] edgeAttributes _ (Slot name, _) = ["label" G.:= unName name]
@ -205,7 +205,7 @@ addressStyle heap = (G.defaultStyle vertex) { G.edgeAttributes }
data EdgeType term name data EdgeType term name
= Edge Edge = Edge Edge
| Slot name | Slot name
| Value (Concrete term name) | Value (Concrete term)
deriving (Eq, Ord, Show) deriving (Eq, Ord, Show)
data Edge = Lexical | Import data Edge = Lexical | Import