Commit c4449fd9 by Zachary Snow

better support for macros with arguments

parent e49cb353
...@@ -25,7 +25,6 @@ import System.Directory (findFile) ...@@ -25,7 +25,6 @@ import System.Directory (findFile)
import System.IO.Unsafe (unsafePerformIO) import System.IO.Unsafe (unsafePerformIO)
import qualified Data.Map.Strict as Map import qualified Data.Map.Strict as Map
import Data.List (findIndex, isPrefixOf) import Data.List (findIndex, isPrefixOf)
import Data.List.Split (splitOn)
import Language.SystemVerilog.Parser.Tokens import Language.SystemVerilog.Parser.Tokens
} }
...@@ -511,18 +510,60 @@ takeMacroDefinition = do ...@@ -511,18 +510,60 @@ takeMacroDefinition = do
then lexicalError "macros cannot have 0 args" then lexicalError "macros cannot have 0 args"
else return (body, args) else return (body, args)
-- TODO FIXME XXX: This currently assumes that macro arguments contain no commas -- commas and right parens are forbidden outside matched pairs of: (), [], {},
-- or parentheses, which obviously isn't valid. See 22.5.1 of the spec for -- "", except to delimit arguments or end the list of arguments; see 22.5.1
-- details on how to deal with macros with arguments.
takeMacroArguments :: Alex [String] takeMacroArguments :: Alex [String]
takeMacroArguments = do takeMacroArguments = do
dropSpaces dropSpaces
str <- takeThrough ')' '(' <- takeChar
return $ splitOn "," str loop "" []
where
-- TODO FIXME XXX: This doens't handle escape sequences in macros. loop :: String -> [Char] -> Alex [String]
loop curr stack = do
ch <- takeChar
case (stack, ch) of
( s,'\\') -> do
ch2 <- takeChar
loop (curr ++ [ch, ch2]) s
([ ], ',') -> do
rest <- loop "" stack
return $ curr : rest
([ ], ')') -> return [curr]
('"' : s, '"') -> loop (curr ++ [ch]) s
( s, '"') -> loop (curr ++ [ch]) ('"' : s)
('[' : s, ']') -> loop (curr ++ [ch]) s
( s, '[') -> loop (curr ++ [ch]) ('[' : s)
('(' : s, ')') -> loop (curr ++ [ch]) s
( s, '(') -> loop (curr ++ [ch]) ('(' : s)
('{' : s, '}') -> loop (curr ++ [ch]) s
( s, '{') -> loop (curr ++ [ch]) ('{' : s)
( s,'\n') -> loop (curr ++ [' ']) s
( s, _ ) -> loop (curr ++ [ch ]) s
findUnescapedQuote :: String -> (String, String)
findUnescapedQuote [] = ([], [])
findUnescapedQuote ('`' : '\\' : '`' : '"' : rest) = ('\\' : '"' : start, end)
where (start, end) = findUnescapedQuote rest
findUnescapedQuote ('\\' : '"' : rest) = ('\\' : '"' : start, end)
where (start, end) = findUnescapedQuote rest
findUnescapedQuote ('"' : rest) = ("\"", rest)
findUnescapedQuote (ch : rest) = (ch : start, end)
where (start, end) = findUnescapedQuote rest
-- substitute in the arguments for a macro expension
substituteArgs :: String -> [String] -> [String] -> String substituteArgs :: String -> [String] -> [String] -> String
substituteArgs "" _ _ = "" substituteArgs "" _ _ = ""
substituteArgs ('`' : '`' : body) names args =
substituteArgs body names args
substituteArgs ('"' : body) names args =
'"' : start ++ substituteArgs rest names args
where (start, rest) = findUnescapedQuote body
substituteArgs ('`' : '"' : body) names args =
'"' : substituteArgs (init start) names args
++ '"' : substituteArgs rest names args
where (start, rest) = findUnescapedQuote body
substituteArgs body names args = substituteArgs body names args =
case findIndex isPresent names of case findIndex isPresent names of
Nothing -> head body : substituteArgs (tail body) names args Nothing -> head body : substituteArgs (tail body) names args
...@@ -628,7 +669,6 @@ handleDirective (posOrig, _, _, strOrig) len = do ...@@ -628,7 +669,6 @@ handleDirective (posOrig, _, _, strOrig) len = do
alexMonadScan alexMonadScan
"define" -> do "define" -> do
-- TODO: We don't yet support macros with arguments!
dropSpaces dropSpaces
name <- takeString name <- takeString
defn <- takeMacroDefinition defn <- takeMacroDefinition
......
...@@ -29,8 +29,7 @@ executable sv2v ...@@ -29,8 +29,7 @@ executable sv2v
containers, containers,
directory, directory,
filepath, filepath,
mtl, mtl
split
other-modules: other-modules:
-- SystemVerilog modules -- SystemVerilog modules
Language.SystemVerilog Language.SystemVerilog
......
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