Commit 90bc30d4 by Zachary Snow

add --oneunit, which treats all input files as being part of one compilation unit

parent 376f0d3f
...@@ -20,6 +20,7 @@ data Job = Job ...@@ -20,6 +20,7 @@ data Job = Job
, files :: [FilePath] , files :: [FilePath]
, incdir :: [FilePath] , incdir :: [FilePath]
, define :: [String] , define :: [String]
, oneunit :: Bool
} deriving (Show, Typeable, Data) } deriving (Show, Typeable, Data)
defaultJob :: Job defaultJob :: Job
...@@ -29,6 +30,7 @@ defaultJob = Job ...@@ -29,6 +30,7 @@ defaultJob = Job
, files = def &= args &= typ "FILES" , files = def &= args &= typ "FILES"
, incdir = def &= typDir &= help "add directory to include search path" , incdir = def &= typDir &= help "add directory to include search path"
, define = def &= typ "NAME[=VALUE]" &= help "define a macro for preprocessing" , define = def &= typ "NAME[=VALUE]" &= help "define a macro for preprocessing"
, oneunit = False &= help "compile all files in one compilation unit"
} }
&= program "sv2v" &= program "sv2v"
&= summary "sv2v v0.0.1, (C) 2019 Zachary Snow, 2011-2015 Tom Hawkins" &= summary "sv2v v0.0.1, (C) 2019 Zachary Snow, 2011-2015 Tom Hawkins"
......
...@@ -2,15 +2,32 @@ ...@@ -2,15 +2,32 @@
- Author: Zachary Snow <zach@zachjs.com> - Author: Zachary Snow <zach@zachjs.com>
-} -}
module Language.SystemVerilog.Parser module Language.SystemVerilog.Parser
( parseFile ( parseFiles
) where ) where
import qualified Data.Map.Strict as Map
import Language.SystemVerilog.AST (AST) import Language.SystemVerilog.AST (AST)
import Language.SystemVerilog.Parser.Lex (lexFile) import Language.SystemVerilog.Parser.Lex (lexFile, Env)
import Language.SystemVerilog.Parser.Parse (parse) import Language.SystemVerilog.Parser.Parse (parse)
-- parses a compilation unit given include search paths and predefined macros
parseFiles :: [FilePath] -> [(String, String)] -> [FilePath] -> IO [AST]
parseFiles includePaths defines paths = do
let env = Map.map (\a -> (a, [])) $ Map.fromList defines
parseFiles' includePaths env paths
-- parses a compilation unit given include search paths and predefined macros
parseFiles' :: [FilePath] -> Env -> [FilePath] -> IO [AST]
parseFiles' _ _ [] = return []
parseFiles' includePaths env (path : paths) = do
(ast, env') <- parseFile' includePaths env path
asts <- parseFiles' includePaths env' paths
return $ ast : asts
-- parses a file given include search paths, a table of predefined macros, and -- parses a file given include search paths, a table of predefined macros, and
-- the file path -- the file path
parseFile :: [String] -> [(String, String)] -> FilePath -> IO AST parseFile' :: [String] -> Env -> FilePath -> IO (AST, Env)
parseFile includePaths defines path = parseFile' includePaths env path = do
lexFile includePaths defines path >>= return . parse (tokens, env') <- lexFile includePaths env path
let ast = parse tokens
return (ast, env')
...@@ -20,7 +20,10 @@ ...@@ -20,7 +20,10 @@
-- been fixed on their development branch, so this can be removed once they roll -- been fixed on their development branch, so this can be removed once they roll
-- a new release. (no new release as of 3/29/2018) -- a new release. (no new release as of 3/29/2018)
module Language.SystemVerilog.Parser.Lex (lexFile) where module Language.SystemVerilog.Parser.Lex
( lexFile
, Env
) where
import System.FilePath (dropFileName) import System.FilePath (dropFileName)
import System.Directory (findFile) import System.Directory (findFile)
...@@ -322,11 +325,14 @@ data Cond ...@@ -322,11 +325,14 @@ data Cond
| NeverTrue | NeverTrue
deriving (Eq, Show) deriving (Eq, Show)
-- map from macro to definition, plus arguments
type Env = Map.Map String (String, [(String, Maybe String)])
-- our custom lexer state -- our custom lexer state
data AlexUserState = LS data AlexUserState = LS
{ lsToks :: [Token] -- tokens read so far, *in reverse order* for efficiency { lsToks :: [Token] -- tokens read so far, *in reverse order* for efficiency
, lsCurrFile :: FilePath -- currently active filename , lsCurrFile :: FilePath -- currently active filename
, lsEnv :: Map.Map String (String, [(String, Maybe String)]) -- active macro definitions , lsEnv :: Env -- active macro definitions
, lsCondStack :: [Cond] -- if-else cascade state , lsCondStack :: [Cond] -- if-else cascade state
, lsIncludePaths :: [FilePath] -- folders to search for includes , lsIncludePaths :: [FilePath] -- folders to search for includes
} deriving (Eq, Show) } deriving (Eq, Show)
...@@ -338,7 +344,7 @@ alexInitUserState :: AlexUserState ...@@ -338,7 +344,7 @@ alexInitUserState :: AlexUserState
alexInitUserState = LS [] "" Map.empty [] [] alexInitUserState = LS [] "" Map.empty [] []
-- public-facing lexer entrypoint -- public-facing lexer entrypoint
lexFile :: [String] -> [(String, String)] -> FilePath -> IO [Token] lexFile :: [String] -> Env -> FilePath -> IO ([Token], Env)
lexFile includePaths env path = do lexFile includePaths env path = do
str <- readFile path str <- readFile path
let result = runAlex str $ setEnv >> alexMonadScan >> get let result = runAlex str $ setEnv >> alexMonadScan >> get
...@@ -346,16 +352,15 @@ lexFile includePaths env path = do ...@@ -346,16 +352,15 @@ lexFile includePaths env path = do
Left msg -> error $ "Lexical Error: " ++ msg Left msg -> error $ "Lexical Error: " ++ msg
Right finalState -> Right finalState ->
if null $ lsCondStack finalState if null $ lsCondStack finalState
then reverse $ lsToks finalState then (reverse $ lsToks finalState, lsEnv finalState)
else error $ "unfinished conditional directives: " ++ else error $ "unfinished conditional directives: " ++
(show $ length $ lsCondStack finalState) (show $ length $ lsCondStack finalState)
where where
initialEnv = Map.map (\a -> (a, [])) $ Map.fromList env
setEnv = do setEnv = do
-- standardize the file path format -- standardize the file path format
path' <- includeSearch path path' <- includeSearch path
modify $ \s -> s modify $ \s -> s
{ lsEnv = initialEnv { lsEnv = env
, lsIncludePaths = includePaths , lsIncludePaths = includePaths
, lsCurrFile = path' , lsCurrFile = path'
} }
......
...@@ -8,9 +8,9 @@ import System.IO ...@@ -8,9 +8,9 @@ import System.IO
import System.Exit import System.Exit
import Data.List (elemIndex) import Data.List (elemIndex)
import Job (readJob, files, exclude, incdir, define) import Job (readJob, files, exclude, incdir, define, oneunit)
import Convert (convert) import Convert (convert)
import Language.SystemVerilog.Parser import Language.SystemVerilog.Parser (parseFiles)
splitDefine :: String -> (String, String) splitDefine :: String -> (String, String)
splitDefine str = splitDefine str =
...@@ -21,12 +21,17 @@ splitDefine str = ...@@ -21,12 +21,17 @@ splitDefine str =
main :: IO () main :: IO ()
main = do main = do
job <- readJob job <- readJob
-- parse the input file -- parse the input files
let includePaths = incdir job let includePaths = incdir job
let defines = map splitDefine $ define job let defines = map splitDefine $ define job
asts <- mapM (parseFile includePaths defines) (files job) let singleton = \x -> [x]
-- convert the file let toFileLists = if oneunit job then singleton else map singleton
astLists <- mapM
(parseFiles includePaths defines)
(toFileLists $ files job)
let asts = concat astLists
-- convert the files
let asts' = convert (exclude job) asts let asts' = convert (exclude job) asts
-- print the converted file out -- print the converted files out
hPrint stdout $ concat asts' hPrint stdout $ concat asts'
exitSuccess exitSuccess
...@@ -5,5 +5,6 @@ module top ...@@ -5,5 +5,6 @@ module top
assign o = i + 1'b1; assign o = i + 1'b1;
initial begin initial begin
$display(width); $display(width);
$display(`FANCY_SEEING_YOU);
end end
endmodule endmodule
`define FANCY_SEEING_YOU 1337
package pkg; package pkg;
function automatic integer width_calc; function automatic integer width_calc;
input integer a; input integer a;
......
`define FANCY_SEEING_YOU 1337
module top; module top;
parameter width = 5; parameter width = 5;
input [width-1:0] i; input [width-1:0] i;
...@@ -5,5 +6,6 @@ module top; ...@@ -5,5 +6,6 @@ module top;
assign o = i + 1'b1; assign o = i + 1'b1;
initial begin initial begin
$display(width); $display(width);
$display(`FANCY_SEEING_YOU);
end end
endmodule endmodule
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
test_main() { test_main() {
cv="$SHUNIT_TMPDIR/conv.v" cv="$SHUNIT_TMPDIR/conv.v"
convert "$cv" package.svh module.sv convert "$cv" --oneunit package.svh module.sv
simulateAndCompare "reference.v" "$cv" "$SCRIPT_DIR/empty.v" simulateAndCompare "reference.v" "$cv" "$SCRIPT_DIR/empty.v"
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment