{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE StrictData #-}
module Language.Cimple.Program
( Program
, fromList
, toList
, includeGraph
) where
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import Data.Text (Text)
import Language.Cimple.Ast (Node)
import Language.Cimple.Graph (Graph)
import qualified Language.Cimple.Graph as Graph
import Language.Cimple.Lexer (Lexeme (..))
import Language.Cimple.SemCheck.Includes (collectIncludes,
normaliseIncludes)
import Language.Cimple.TranslationUnit (TranslationUnit)
data Program text = Program
{ Program text -> Map FilePath [Node (Lexeme text)]
progAsts :: Map FilePath [Node (Lexeme text)]
, Program text -> Graph () FilePath
progIncludes :: Graph () FilePath
}
toList :: Program a -> [TranslationUnit a]
toList :: Program a -> [TranslationUnit a]
toList = Map FilePath [Node (Lexeme a)] -> [TranslationUnit a]
forall k a. Map k a -> [(k, a)]
Map.toList (Map FilePath [Node (Lexeme a)] -> [TranslationUnit a])
-> (Program a -> Map FilePath [Node (Lexeme a)])
-> Program a
-> [TranslationUnit a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Program a -> Map FilePath [Node (Lexeme a)]
forall text. Program text -> Map FilePath [Node (Lexeme text)]
progAsts
includeGraph :: Program a -> [(FilePath, FilePath)]
includeGraph :: Program a -> [(FilePath, FilePath)]
includeGraph = Graph () FilePath -> [(FilePath, FilePath)]
forall node key. Graph node key -> [(key, key)]
Graph.edges (Graph () FilePath -> [(FilePath, FilePath)])
-> (Program a -> Graph () FilePath)
-> Program a
-> [(FilePath, FilePath)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Program a -> Graph () FilePath
forall text. Program text -> Graph () FilePath
progIncludes
fromList :: [TranslationUnit Text] -> Either String (Program Text)
fromList :: [TranslationUnit Text] -> Either FilePath (Program Text)
fromList [TranslationUnit Text]
tus = do
let tusWithIncludes :: [(TranslationUnit Text, [FilePath])]
tusWithIncludes = (TranslationUnit Text -> (TranslationUnit Text, [FilePath]))
-> [TranslationUnit Text] -> [(TranslationUnit Text, [FilePath])]
forall a b. (a -> b) -> [a] -> [b]
map TranslationUnit Text -> (TranslationUnit Text, [FilePath])
normaliseIncludes [TranslationUnit Text]
tus
let progAsts :: Map FilePath [Node (Lexeme Text)]
progAsts = [TranslationUnit Text] -> Map FilePath [Node (Lexeme Text)]
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList ([TranslationUnit Text] -> Map FilePath [Node (Lexeme Text)])
-> ([(TranslationUnit Text, [FilePath])] -> [TranslationUnit Text])
-> [(TranslationUnit Text, [FilePath])]
-> Map FilePath [Node (Lexeme Text)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((TranslationUnit Text, [FilePath]) -> TranslationUnit Text)
-> [(TranslationUnit Text, [FilePath])] -> [TranslationUnit Text]
forall a b. (a -> b) -> [a] -> [b]
map (TranslationUnit Text, [FilePath]) -> TranslationUnit Text
forall a b. (a, b) -> a
fst ([(TranslationUnit Text, [FilePath])]
-> Map FilePath [Node (Lexeme Text)])
-> [(TranslationUnit Text, [FilePath])]
-> Map FilePath [Node (Lexeme Text)]
forall a b. (a -> b) -> a -> b
$ [(TranslationUnit Text, [FilePath])]
tusWithIncludes
[((), FilePath, [FilePath])]
includeEdges <- ((TranslationUnit Text, [FilePath])
-> Either FilePath ((), FilePath, [FilePath]))
-> [(TranslationUnit Text, [FilePath])]
-> Either FilePath [((), FilePath, [FilePath])]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM ((TranslationUnit Text
-> [FilePath] -> Either FilePath ((), FilePath, [FilePath]))
-> (TranslationUnit Text, [FilePath])
-> Either FilePath ((), FilePath, [FilePath])
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((TranslationUnit Text
-> [FilePath] -> Either FilePath ((), FilePath, [FilePath]))
-> (TranslationUnit Text, [FilePath])
-> Either FilePath ((), FilePath, [FilePath]))
-> (TranslationUnit Text
-> [FilePath] -> Either FilePath ((), FilePath, [FilePath]))
-> (TranslationUnit Text, [FilePath])
-> Either FilePath ((), FilePath, [FilePath])
forall a b. (a -> b) -> a -> b
$ [FilePath]
-> TranslationUnit Text
-> [FilePath]
-> Either FilePath ((), FilePath, [FilePath])
collectIncludes ([FilePath]
-> TranslationUnit Text
-> [FilePath]
-> Either FilePath ((), FilePath, [FilePath]))
-> [FilePath]
-> TranslationUnit Text
-> [FilePath]
-> Either FilePath ((), FilePath, [FilePath])
forall a b. (a -> b) -> a -> b
$ (TranslationUnit Text -> FilePath)
-> [TranslationUnit Text] -> [FilePath]
forall a b. (a -> b) -> [a] -> [b]
map TranslationUnit Text -> FilePath
forall a b. (a, b) -> a
fst [TranslationUnit Text]
tus) [(TranslationUnit Text, [FilePath])]
tusWithIncludes
let progIncludes :: Graph () FilePath
progIncludes = [((), FilePath, [FilePath])] -> Graph () FilePath
forall key node. Ord key => [(node, key, [key])] -> Graph node key
Graph.fromEdges [((), FilePath, [FilePath])]
includeEdges
Program Text -> Either FilePath (Program Text)
forall (m :: * -> *) a. Monad m => a -> m a
return Program :: forall text.
Map FilePath [Node (Lexeme text)]
-> Graph () FilePath -> Program text
Program{Map FilePath [Node (Lexeme Text)]
Graph () FilePath
progIncludes :: Graph () FilePath
progAsts :: Map FilePath [Node (Lexeme Text)]
progIncludes :: Graph () FilePath
progAsts :: Map FilePath [Node (Lexeme Text)]
..}