{- sv2v - Author: Zachary Snow <zach@zachjs.com> -} module Language.SystemVerilog.Parser ( parseFiles ) where import Control.Monad.Except import qualified Data.Map.Strict as Map import Language.SystemVerilog.AST (AST) import Language.SystemVerilog.Parser.Lex (lexStr) import Language.SystemVerilog.Parser.Parse (parse) import Language.SystemVerilog.Parser.Preprocess (preprocess, annotate, Env) -- parses a compilation unit given include search paths and predefined macros parseFiles :: [FilePath] -> [(String, String)] -> Bool -> Bool -> [FilePath] -> IO (Either String [AST]) parseFiles includePaths defines siloed skipPreprocessor paths = do let env = Map.map (\a -> (a, [])) $ Map.fromList defines runExceptT (parseFiles' includePaths env siloed skipPreprocessor paths) -- parses a compilation unit given include search paths and predefined macros parseFiles' :: [FilePath] -> Env -> Bool -> Bool -> [FilePath] -> ExceptT String IO [AST] parseFiles' _ _ _ _ [] = return [] parseFiles' includePaths env siloed skipPreprocessor (path : paths) = do (ast, envEnd) <- parseFile' includePaths env skipPreprocessor path let envNext = if siloed then env else envEnd asts <- parseFiles' includePaths envNext siloed skipPreprocessor paths return $ ast : asts -- parses a file given include search paths, a table of predefined macros, and -- the file path parseFile' :: [String] -> Env -> Bool -> FilePath -> ExceptT String IO (AST, Env) parseFile' includePaths env skipPreprocessor path = do let runner = if skipPreprocessor then annotate else preprocess preResult <- liftIO $ runner includePaths env path (contents, env') <- liftEither preResult tokens <- liftEither $ uncurry lexStr $ unzip contents ast <- parse tokens return (ast, env')