diff --git a/src/Language/SystemVerilog/AST/Decl.hs b/src/Language/SystemVerilog/AST/Decl.hs index acfd5d7..e980b87 100644 --- a/src/Language/SystemVerilog/AST/Decl.hs +++ b/src/Language/SystemVerilog/AST/Decl.hs @@ -10,12 +10,14 @@ module Language.SystemVerilog.AST.Decl ( Decl (..) , Direction (..) , ParamScope (..) + , showDecls ) where +import Data.List (intercalate) import Text.Printf (printf) import Language.SystemVerilog.AST.ShowHelp (showPad, unlines') -import Language.SystemVerilog.AST.Type (Type(UnpackedType), Identifier, pattern UnknownType) +import Language.SystemVerilog.AST.Type (Type(TypedefRef, UnpackedType), Identifier, pattern UnknownType) import Language.SystemVerilog.AST.Expr (Expr, Range, showRanges, showAssignment) data Decl @@ -28,6 +30,8 @@ data Decl instance Show Decl where showList l _ = unlines' $ map show l show (Param s t x e) = printf "%s %s%s%s;" (show s) (showPad t) x (showAssignment e) + show (ParamType Localparam x (TypedefRef e)) = + printf "typedef %s %s;" (show e) x show (ParamType Localparam x (UnpackedType t rs)) = printf "typedef %s %s%s;" (show t) x (showRanges rs) show (ParamType s x t) = printf "%s type %s%s;" (show s) x tStr @@ -38,6 +42,20 @@ instance Show Decl where then "// " ++ show c else "// " ++ c +showDecls :: Char -> String -> [Decl] -> String +showDecls delim whitespace = + dropDelim . intercalate whitespace . map showDecl + where + dropDelim :: String -> String + dropDelim [] = [] + dropDelim [x] = if x == delim then [] else [x] + dropDelim (x : xs) = x : dropDelim xs + showDecl (CommentDecl c) = + if whitespace == " " + then "/* " ++ c ++ " */" + else show $ CommentDecl c + showDecl decl = (init $ show decl) ++ [delim] + data Direction = Input | Output diff --git a/src/Language/SystemVerilog/AST/Description.hs b/src/Language/SystemVerilog/AST/Description.hs index 45ea28c..f1756d4 100644 --- a/src/Language/SystemVerilog/AST/Description.hs +++ b/src/Language/SystemVerilog/AST/Description.hs @@ -19,7 +19,7 @@ import Text.Printf (printf) import Language.SystemVerilog.AST.ShowHelp import Language.SystemVerilog.AST.Attr (Attr) -import Language.SystemVerilog.AST.Decl (Decl) +import Language.SystemVerilog.AST.Decl (Decl, showDecls) import Language.SystemVerilog.AST.Stmt (Stmt) import Language.SystemVerilog.AST.Type (Type, Identifier) import {-# SOURCE #-} Language.SystemVerilog.AST.ModuleItem (ModuleItem) @@ -53,13 +53,17 @@ instance Show Description where where bodyStr = indent $ unlines' $ map show items show (Class lifetime name decls items) = - printf "class %s%s;\n%s\nendclass" - (showPad lifetime) name bodyStr + printf "class %s%s%s;\n%s\nendclass" + (showPad lifetime) name (showParamDecls decls) bodyStr where - bodyStr = indent $ unlines' $ map showClassItem items' - items' = (map (\decl -> (QNone, Decl decl)) decls) ++ items + bodyStr = indent $ unlines' $ map showClassItem items show (PackageItem i) = show i +showParamDecls :: [Decl] -> String +showParamDecls [] = "" +showParamDecls decls = " #(\n\t" ++ str ++ "\n)" + where str = showDecls ',' "\n\t" decls + data PackageItem = Function Lifetime Type Identifier [Decl] [Stmt] | Task Lifetime Identifier [Decl] [Stmt] diff --git a/src/Language/SystemVerilog/AST/Stmt.hs b/src/Language/SystemVerilog/AST/Stmt.hs index 120aa2b..afcf8d9 100644 --- a/src/Language/SystemVerilog/AST/Stmt.hs +++ b/src/Language/SystemVerilog/AST/Stmt.hs @@ -27,7 +27,7 @@ import Text.Printf (printf) import Language.SystemVerilog.AST.ShowHelp (commas, indent, unlines', showPad, showBlock) import Language.SystemVerilog.AST.Attr (Attr) -import Language.SystemVerilog.AST.Decl (Decl) +import Language.SystemVerilog.AST.Decl (Decl, showDecls) import Language.SystemVerilog.AST.Expr (Expr(Nil), Args(..)) import Language.SystemVerilog.AST.LHS (LHS) import Language.SystemVerilog.AST.Op (AsgnOp(AsgnOpEq)) @@ -78,7 +78,7 @@ instance Show Stmt where (indent $ show stmt) where showInits :: Either [Decl] [(LHS, Expr)] -> String - showInits (Left decls) = commas $ map (init . show) decls + showInits (Left decls) = showDecls ',' " " decls showInits (Right asgns) = commas $ map showInit asgns where showInit (l, e) = showAssign (l, AsgnOpEq, e) showAssign :: (LHS, AsgnOp, Expr) -> String diff --git a/src/Language/SystemVerilog/Parser/Parse.y b/src/Language/SystemVerilog/Parser/Parse.y index f7c85d8..98edf7c 100644 --- a/src/Language/SystemVerilog/Parser/Parse.y +++ b/src/Language/SystemVerilog/Parser/Parse.y @@ -662,6 +662,10 @@ PortDeclTokens(delim) :: { [DeclToken] } | GenericInterfaceDecl PortDeclTokens(delim) { $1 ++ $2} | GenericInterfaceDecl delim { $1 } | AttributeInstance PortDeclTokens(delim) {% posInject \p -> DTAttr p $1 : $2 } +ModuleDeclTokens(delim) :: { [DeclToken] } + : DeclTokensBase(ModuleDeclTokens(delim), delim) { $1 } + | GenericInterfaceDecl ModuleDeclTokens(delim) { $1 ++ $2} + | GenericInterfaceDecl delim { $1 } GenericInterfaceDecl :: { [DeclToken] } : "interface" Identifier {% posInject \p -> [DTType p (\Unspecified -> InterfaceT "" ""), DTIdent p $2] } @@ -688,7 +692,7 @@ ModuleItem :: { [ModuleItem] } | "generate" GenItems endgenerate { [Generate $2] } NonGenerateModuleItem :: { [ModuleItem] } -- This item covers module instantiations and all declarations - : DeclTokens(";") { parseDTsAsModuleItems $1 } + : ModuleDeclTokens(";") { parseDTsAsModuleItems $1 } | ParameterDecl(";") { map (MIPackageItem . Decl) $1 } | "defparam" LHSAsgns ";" { map (uncurry Defparam) $2 } | "assign" AssignOption LHSAsgns ";" { map (uncurry $ Assign $2) $3 } diff --git a/test/lib/functions.sh b/test/lib/functions.sh index 7534ed7..78820b5 100644 --- a/test/lib/functions.sh +++ b/test/lib/functions.sh @@ -45,14 +45,26 @@ simulate() { assertConverts() { ac_file=$1 + ac_tmpa=$SHUNIT_TMPDIR/ac-conv-tmpa.v $SV2V $ac_file 2> /dev/null > $ac_tmpa assertTrue "1st conversion of $ac_file failed" $? + ac_tmpb=$SHUNIT_TMPDIR/ac-conv-tmpb.v $SV2V $ac_tmpa 2> /dev/null > $ac_tmpb assertTrue "2nd conversion of $ac_file failed" $? diff $ac_tmpa $ac_tmpb > /dev/null assertTrue "conversion of $ac_file not stable after the first iteration" $? + + ac_tmpc=$SHUNIT_TMPDIR/ac-conv-tmpc.v + $SV2V --pass-through $ac_file 2> /dev/null > $ac_tmpc + assertTrue "pass through of $ac_file failed" $? + ac_tmpd=$SHUNIT_TMPDIR/ac-conv-tmpd.v + $SV2V $ac_tmpc 2> /dev/null > $ac_tmpd + assertTrue "conversion of pass through of $ac_file failed" $? + diff $ac_tmpa $ac_tmpd > /dev/null + assertTrue "pass through then conversion differs for $ac_file" $? + # using sed to remove quoted strings filtered=`sed -E 's/"([^"]|\")+"//g' $ac_tmpa` # check for various things iverilog accepts which we don't want to output