mirror of https://github.com/zachjs/sv2v.git
updated CLI to support include dirs and multiple files
This commit is contained in:
parent
7e37fe4338
commit
0d9ed3e1fa
|
|
@ -41,11 +41,12 @@ The interface for this tool has not yet been finalized. Currently, running `sv2v
|
|||
path/to/file.sv` will output the converted file to `stdout`.
|
||||
|
||||
```
|
||||
sv2v [OPTIONS] [FILE]
|
||||
sv2v [OPTIONS] [FILES]
|
||||
|
||||
Common flags:
|
||||
-e --exclude=CONV conversion to exclude (always, interface, logic); can
|
||||
be specified multiple times
|
||||
-i --incdir=DIR add directory to include search path
|
||||
-? --help Display help message
|
||||
-V --version Print version information
|
||||
--numeric-version Print just the version number
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ data Exclude
|
|||
|
||||
data Job = Job
|
||||
{ exclude :: [Exclude]
|
||||
, file :: FilePath
|
||||
, files :: [FilePath]
|
||||
, incdir :: [FilePath]
|
||||
} deriving (Show, Typeable, Data)
|
||||
|
||||
defaultJob :: Job
|
||||
|
|
@ -26,7 +27,8 @@ defaultJob = Job
|
|||
&= help
|
||||
("conversion to exclude (always, interface, logic)"
|
||||
++ "; can be specified multiple times")
|
||||
, file = def &= args &= typFile
|
||||
, files = def &= args &= typ "FILES"
|
||||
, incdir = def &= typDir &= help "add directory to include search path"
|
||||
}
|
||||
&= program "sv2v"
|
||||
&= summary "sv2v v0.0.1, (C) Zachary Snow 2019, Tom Hawkins, 2011-2015"
|
||||
|
|
|
|||
|
|
@ -6,17 +6,12 @@ module Language.SystemVerilog.Parser
|
|||
) where
|
||||
|
||||
import Language.SystemVerilog.AST
|
||||
import Language.SystemVerilog.Parser.Lex
|
||||
import Language.SystemVerilog.Parser.Parse
|
||||
import Language.SystemVerilog.Parser.Preprocess
|
||||
|
||||
import Control.Monad.State
|
||||
import qualified Data.Map.Strict as Map
|
||||
|
||||
-- parses a file given a table of predefined macros and the file name
|
||||
parseFile :: [(String, String)] -> FilePath -> IO AST
|
||||
parseFile env file = do
|
||||
let initialEnv = Map.map alexScanTokens $ Map.fromList env
|
||||
let initialState = PP initialEnv []
|
||||
ast <- evalStateT (loadFile file) initialState
|
||||
return $ descriptions ast
|
||||
parseFile :: [String] -> [(String, String)] -> FilePath -> IO AST
|
||||
parseFile includePaths env file =
|
||||
loadFile file >>=
|
||||
preprocess includePaths env >>=
|
||||
return . descriptions
|
||||
|
|
|
|||
|
|
@ -5,13 +5,15 @@
|
|||
-}
|
||||
module Language.SystemVerilog.Parser.Preprocess
|
||||
( loadFile
|
||||
, preprocess
|
||||
, PP (..)
|
||||
) where
|
||||
|
||||
import Control.Monad.State
|
||||
import Data.List (intercalate)
|
||||
import qualified Data.Map.Strict as Map
|
||||
import System.FilePath (replaceFileName)
|
||||
import System.FilePath (dropFileName)
|
||||
import System.Directory (findFile)
|
||||
|
||||
import Language.SystemVerilog.Parser.Lex
|
||||
import Language.SystemVerilog.Parser.Tokens
|
||||
|
|
@ -23,9 +25,6 @@ isNewline (Token t _ _) = t == Spe_Newline
|
|||
unskippableDirectives :: [String]
|
||||
unskippableDirectives = ["else", "elsif", "endif", "ifdef", "ifndef"]
|
||||
|
||||
preprocess :: [Token] -> (StateT PP IO) [Token]
|
||||
preprocess tokens = pp tokens >>= return . combineNumbers
|
||||
|
||||
-- a bit of a hack to allow things like: `WIDTH'b0
|
||||
combineNumbers :: [Token] -> [Token]
|
||||
combineNumbers (Token Lit_number size pos : Token Lit_number ('\'' : num) _ : tokens) =
|
||||
|
|
@ -33,6 +32,16 @@ combineNumbers (Token Lit_number size pos : Token Lit_number ('\'' : num) _ : to
|
|||
combineNumbers (token : tokens) = token : combineNumbers tokens
|
||||
combineNumbers [] = []
|
||||
|
||||
includeSearch :: FilePath -> FilePath -> (StateT PP IO) FilePath
|
||||
includeSearch base file = do
|
||||
includePaths <- gets ppIncludePaths
|
||||
let directories = dropFileName base : includePaths
|
||||
result <- lift $ findFile directories file
|
||||
case result of
|
||||
Just path -> return path
|
||||
Nothing ->
|
||||
error $ "Could not find file " ++ file ++ " included from " ++ base
|
||||
|
||||
data Cond
|
||||
= CurrentlyTrue
|
||||
| PreviouslyTrue
|
||||
|
|
@ -42,6 +51,7 @@ data Cond
|
|||
data PP = PP
|
||||
{ ppEnv :: Map.Map String [Token]
|
||||
, ppCondStack :: [Cond]
|
||||
, ppIncludePaths :: [FilePath]
|
||||
} deriving (Eq, Show)
|
||||
|
||||
pp :: [Token] -> (StateT PP IO) [Token]
|
||||
|
|
@ -81,10 +91,9 @@ pp (Token Spe_Directive str pos : tokens) = do
|
|||
"include" -> do
|
||||
let file = init $ tail $ tokenString $ head tokens
|
||||
let Position basePath _ _ = pos
|
||||
let filePath = replaceFileName basePath file
|
||||
includedTokens <- loadFile filePath
|
||||
remainingTokens <- pp $ tail tokens
|
||||
return $ includedTokens ++ remainingTokens
|
||||
filePath <- includeSearch basePath file
|
||||
includedTokens <- lift $ loadFile filePath
|
||||
pp $ includedTokens ++ tail tokens
|
||||
|
||||
"ifdef" -> do
|
||||
let name = tokenString $ head tokens
|
||||
|
|
@ -163,14 +172,19 @@ pp (token : tokens) = do
|
|||
then return tokens'
|
||||
else return $ token : tokens'
|
||||
|
||||
-- loads, lexes, and preprocesses the file at the given path
|
||||
loadFile :: FilePath -> (StateT PP IO) [Token]
|
||||
-- loads and lexes the file at the given path
|
||||
loadFile :: FilePath -> IO [Token]
|
||||
loadFile file = do
|
||||
content <- lift $ readFile file
|
||||
preprocess $
|
||||
map relocate $
|
||||
alexScanTokens $
|
||||
content
|
||||
content <- readFile file
|
||||
let tokens = alexScanTokens content
|
||||
return $ map relocate tokens
|
||||
where
|
||||
relocate :: Token -> Token
|
||||
relocate (Token t s (Position _ l c)) = Token t s $ Position file l c
|
||||
|
||||
preprocess :: [String] -> [(String, String)] -> [Token] -> IO [Token]
|
||||
preprocess includePaths env tokens = do
|
||||
let initialEnv = Map.map alexScanTokens $ Map.fromList env
|
||||
let initialState = PP initialEnv [] includePaths
|
||||
res <- evalStateT (pp tokens) initialState
|
||||
return $ combineNumbers res
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
import System.IO
|
||||
import System.Exit
|
||||
|
||||
import Job (readJob, file, exclude)
|
||||
import Job (readJob, files, exclude, incdir)
|
||||
import Convert (convert)
|
||||
import Language.SystemVerilog.Parser
|
||||
|
||||
|
|
@ -15,8 +15,9 @@ main :: IO ()
|
|||
main = do
|
||||
job <- readJob
|
||||
-- parse the input file
|
||||
let filePath = file job
|
||||
ast <- parseFile [] filePath
|
||||
let includePaths = incdir job
|
||||
asts <- mapM (parseFile includePaths []) (files job)
|
||||
let ast = concat asts
|
||||
-- convert the file
|
||||
let ast' = convert (exclude job) ast
|
||||
-- print the converted file out
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ executable sv2v
|
|||
base,
|
||||
cmdargs,
|
||||
containers,
|
||||
directory,
|
||||
filepath,
|
||||
mtl
|
||||
other-modules:
|
||||
|
|
|
|||
Loading…
Reference in New Issue