diff --git a/src/Convert/Traverse.hs b/src/Convert/Traverse.hs index 287af24..a754931 100644 --- a/src/Convert/Traverse.hs +++ b/src/Convert/Traverse.hs @@ -213,8 +213,11 @@ traverseNestedExprsM mapper = exprMapper return $ Repeat e' l' em (Concat l) = mapM exprMapper l >>= return . Concat - em (Call f l) = - mapM maybeExprMapper l >>= return . Call f + em (Call f (Args l p)) = do + l' <- mapM maybeExprMapper l + pes <- mapM maybeExprMapper $ map snd p + let p' = zip (map fst p) pes + return $ Call f (Args l' p') em (UniOp o e) = exprMapper e >>= return . UniOp o em (BinOp o e1 e2) = do @@ -297,8 +300,11 @@ traverseExprsM mapper = moduleItemMapper flatStmtMapper (If u cc s1 s2) = exprMapper cc >>= \cc' -> return $ If u cc' s1 s2 flatStmtMapper (Timing event stmt) = return $ Timing event stmt - flatStmtMapper (Subroutine f exprs) = - mapM maybeExprMapper exprs >>= return . Subroutine f + flatStmtMapper (Subroutine f (Args l p)) = do + l' <- mapM maybeExprMapper l + pes <- mapM maybeExprMapper $ map snd p + let p' = zip (map fst p) pes + return $ Subroutine f (Args l' p') flatStmtMapper (Return expr) = exprMapper expr >>= return . Return flatStmtMapper (Trigger x) = return $ Trigger x diff --git a/src/Language/SystemVerilog/AST/Expr.hs b/src/Language/SystemVerilog/AST/Expr.hs index 33dcf39..69995bd 100644 --- a/src/Language/SystemVerilog/AST/Expr.hs +++ b/src/Language/SystemVerilog/AST/Expr.hs @@ -10,6 +10,7 @@ module Language.SystemVerilog.AST.Expr , Range , showAssignment , showRanges + , Args (..) ) where import Data.List (intercalate) @@ -29,7 +30,7 @@ data Expr | Bit Expr Expr | Repeat Expr [Expr] | Concat [Expr] - | Call Identifier [Maybe Expr] + | Call Identifier Args | UniOp UniOp Expr | BinOp BinOp Expr Expr | Mux Expr Expr Expr @@ -50,7 +51,7 @@ instance Show Expr where show (BinOp o a b) = printf "(%s %s %s)" (show a) (show o) (show b) show (Dot e n ) = printf "%s.%s" (show e) n show (Mux c a b) = printf "(%s ? %s : %s)" (show c) (show a) (show b) - show (Call f l ) = printf "%s(%s)" f (commas $ map (maybe "" show) l) + show (Call f l ) = printf "%s(%s)" f (show l) show (Cast tore e ) = printf "%s'(%s)" tStr (show e) where tStr = case tore of @@ -63,6 +64,17 @@ instance Show Expr where showPatternItem (Nothing, e) = show e showPatternItem (Just n , e) = printf "%s: %s" n (show e) +data Args + = Args [Maybe Expr] [(Identifier, Maybe Expr)] + deriving (Eq, Ord) + +instance Show Args where + show (Args pnArgs kwArgs) = commas strs + where + strs = (map showPnArg pnArgs) ++ (map showKwArg kwArgs) + showPnArg = maybe "" show + showKwArg (x, me) = printf ".%s(%s)" (show x) (showPnArg me) + showAssignment :: Maybe Expr -> String showAssignment Nothing = "" showAssignment (Just val) = " = " ++ show val diff --git a/src/Language/SystemVerilog/AST/Stmt.hs b/src/Language/SystemVerilog/AST/Stmt.hs index c2ec2ad..90b0dec 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, showCase) import Language.SystemVerilog.AST.Attr (Attr) import Language.SystemVerilog.AST.Decl (Decl) -import Language.SystemVerilog.AST.Expr (Expr) +import Language.SystemVerilog.AST.Expr (Expr, Args) import Language.SystemVerilog.AST.LHS (LHS) import Language.SystemVerilog.AST.Op (AsgnOp) import Language.SystemVerilog.AST.Type (Identifier) @@ -46,7 +46,7 @@ data Stmt | If (Maybe UniquePriority) Expr Stmt Stmt | Timing Timing Stmt | Return Expr - | Subroutine Identifier [Maybe Expr] + | Subroutine Identifier Args | Trigger Identifier -- TODO: Should we support coversion of assertions? -- | Assertion Assertion @@ -80,7 +80,7 @@ instance Show Stmt where showInit (Right (l, e)) = printf "%s = %s" (show l) (show e) showAssign :: (LHS, AsgnOp, Expr) -> String showAssign (l, op, e) = printf "%s %s %s" (show l) (show op) (show e) - show (Subroutine x a) = printf "%s(%s);" x (commas $ map (maybe "" show) a) + show (Subroutine x a) = printf "%s(%s);" x (show a) show (AsgnBlk o v e) = printf "%s %s %s;" (show v) (show o) (show e) show (Asgn t v e) = printf "%s <= %s%s;" (show v) (maybe "" showPad t) (show e) show (While e s) = printf "while (%s) %s" (show e) (show s) @@ -162,7 +162,7 @@ instance Show PESPBinOp where show ImpliesNO = "|=>" show FollowedByO = "#-#" show FollowedByNO = "#=#" -type SeqMatchItem = Either (LHS, AsgnOp, Expr) (Identifier, [Maybe Expr]) +type SeqMatchItem = Either (LHS, AsgnOp, Expr) (Identifier, Args) data SeqExpr = SeqExpr Expr | SeqExprAnd SeqExpr SeqExpr @@ -181,7 +181,7 @@ instance Show SeqExpr where show (SeqExprThroughout a b) = printf "(%s %s %s)" (show a) "throughout" (show b) show (SeqExprWithin a b) = printf "(%s %s %s)" (show a) "within" (show b) show (SeqExprDelay me e s) = printf "%s##%s %s" (maybe "" showPad me) (show e) (show s) - show (SeqExprFirstMatch e l) = printf "first_match(%s, %s)" (show e) (commas $ map show l) + show (SeqExprFirstMatch e a) = printf "first_match(%s, %s)" (show e) (show a) type AssertionItem = (Maybe Identifier, Assertion) data Assertion diff --git a/src/Language/SystemVerilog/Parser/Parse.y b/src/Language/SystemVerilog/Parser/Parse.y index 881b0ea..45ca396 100644 --- a/src/Language/SystemVerilog/Parser/Parse.y +++ b/src/Language/SystemVerilog/Parser/Parse.y @@ -625,7 +625,7 @@ Stmts :: { [Stmt] } Stmt :: { Stmt } : StmtNonAsgn { $1 } | LHS AsgnOp Expr ";" { AsgnBlk $2 $1 $3 } - | Identifier ";" { Subroutine $1 [] } + | Identifier ";" { Subroutine $1 (Args [] []) } | LHS "<=" opt(DelayOrEventControl) Expr ";" { Asgn $3 $1 $4 } | LHS IncOrDecOperator ";" { AsgnBlk (AsgnOp $2) $1 (Number "1") } | IncOrDecOperator LHS ";" { AsgnBlk (AsgnOp $1) $2 (Number "1") } @@ -737,14 +737,23 @@ Number :: { String } String :: { String } : string { tail $ init $ tokenString $1 } -CallArgs :: { [Maybe Expr] } - : {- empty -} { [] } - | Expr { [Just $1] } - | CallArgsFollow { (Nothing) : $1 } - | Expr CallArgsFollow { (Just $1) : $2 } -CallArgsFollow :: { [Maybe Expr] } +CallArgs :: { Args } + : {- empty -} { Args [ ] [] } + | NamedCallArgsFollow { Args [ ] $1 } + | Expr NamedCallArgs { Args [Just $1 ] $2 } + | UnnamedCallArgs NamedCallArgs { Args (Nothing : $1) $2 } + | Expr UnnamedCallArgs NamedCallArgs { Args (Just $1 : $2) $3 } +UnnamedCallArgs :: { [Maybe Expr] } : "," opt(Expr) { [$2] } - | "," opt(Expr) CallArgsFollow { $2 : $3 } + | UnnamedCallArgs "," opt(Expr) { $1 ++ [$3] } +NamedCallArgs :: { [(Identifier, Maybe Expr)] } + : {- empty -} { [] } + | "," NamedCallArgsFollow { $2 } +NamedCallArgsFollow :: { [(Identifier, Maybe Expr)] } + : NamedCallArg { [$1] } + | NamedCallArgsFollow "," NamedCallArg { $1 ++ [$3] } +NamedCallArg :: { (Identifier, Maybe Expr) } + : "." Identifier "(" opt(Expr) ")" { ($2, $4) } Exprs :: { [Expr] } : Expr { [$1] } diff --git a/src/Language/SystemVerilog/Parser/ParseDecl.hs b/src/Language/SystemVerilog/Parser/ParseDecl.hs index 078212d..cbff205 100644 --- a/src/Language/SystemVerilog/Parser/ParseDecl.hs +++ b/src/Language/SystemVerilog/Parser/ParseDecl.hs @@ -178,7 +178,7 @@ parseDTsAsDecl tokens = -- [PUBLIC]: parser for single block item declarations or assign or arg-less -- subroutine call statetments parseDTsAsDeclOrAsgn :: [DeclToken] -> ([Decl], [Stmt]) -parseDTsAsDeclOrAsgn [DTIdent f] = ([], [Subroutine f []]) +parseDTsAsDeclOrAsgn [DTIdent f] = ([], [Subroutine f (Args [] [])]) parseDTsAsDeclOrAsgn tokens = if any isAsgnToken tokens || tripLookahead tokens then ([], [constructor lhs expr])