Commit 713fb8a6 by Zachary Snow

support for more complex for loop components

parent 1c1740f1
{- sv2v {- sv2v
- Author: Zachary Snow <zach@zachjs.com> - Author: Zachary Snow <zach@zachjs.com>
- -
- Conversion for binary assignment operators, which appear in generate for - Conversion for binary assignment operators, which appear in standard and
- loops and as a special case of blocking assignment statements. We simply - generate for loops and as a special case of blocking assignment statements.
- elaborate them in the obvious manner. - We simply elaborate them in the obvious manner.
-} -}
module Convert.AsgnOp (convert) where module Convert.AsgnOp (convert) where
...@@ -24,6 +24,14 @@ convertGenItem (GenFor a b (ident, AsgnOp op, expr) c d) = ...@@ -24,6 +24,14 @@ convertGenItem (GenFor a b (ident, AsgnOp op, expr) c d) =
convertGenItem other = other convertGenItem other = other
convertStmt :: Stmt -> Stmt convertStmt :: Stmt -> Stmt
convertStmt (For inits cc asgns stmt) =
For inits cc asgns' stmt
where
asgns' = map convertAsgn asgns
convertAsgn :: (LHS, AsgnOp, Expr) -> (LHS, AsgnOp, Expr)
convertAsgn (lhs, AsgnOp op, expr) =
(lhs, AsgnOpEq, BinOp op (lhsToExpr lhs) expr)
convertAsgn other = other
convertStmt (AsgnBlk (AsgnOp op) lhs expr) = convertStmt (AsgnBlk (AsgnOp op) lhs expr) =
AsgnBlk AsgnOpEq lhs (BinOp op (lhsToExpr lhs) expr) AsgnBlk AsgnOpEq lhs (BinOp op (lhsToExpr lhs) expr)
convertStmt other = other convertStmt other = other
......
...@@ -268,8 +268,8 @@ rewriteModuleItem info = ...@@ -268,8 +268,8 @@ rewriteModuleItem info =
assign = constructor assign = constructor
(LHSBit (LHSIdent $ prefix ident) (Ident index)) (LHSBit (LHSIdent $ prefix ident) (Ident index))
(Concat exprs) (Concat exprs)
inir = (index, b) inir = [Right (LHSIdent index, b)]
chkr = BinOp Le (Ident index) a chkr = Just $ BinOp Le (Ident index) a
incr = (index, BinOp Add (Ident index) (Number "1")) incr = [(LHSIdent index, AsgnOp Add, Number "1")]
convertAssignment constructor lhs expr = convertAssignment constructor lhs expr =
constructor (rewriteLHS lhs) expr constructor (rewriteLHS lhs) expr
...@@ -282,11 +282,11 @@ traverseExprsM mapper = moduleItemMapper ...@@ -282,11 +282,11 @@ traverseExprsM mapper = moduleItemMapper
exprMapper expr >>= return . AsgnBlk op lhs exprMapper expr >>= return . AsgnBlk op lhs
flatStmtMapper (Asgn mt lhs expr) = flatStmtMapper (Asgn mt lhs expr) =
exprMapper expr >>= return . Asgn mt lhs exprMapper expr >>= return . Asgn mt lhs
flatStmtMapper (For (x1, e1) cc (x2, e2) stmt) = do flatStmtMapper (For inits cc asgns stmt) = do
e1' <- exprMapper e1 inits' <- mapM initMapper inits
e2' <- exprMapper e2 cc' <- maybeExprMapper cc
cc' <- exprMapper cc asgns' <- mapM asgnMapper asgns
return $ For (x1, e1') cc' (x2, e2') stmt return $ For inits' cc' asgns' stmt
flatStmtMapper (While e stmt) = flatStmtMapper (While e stmt) =
exprMapper e >>= \e' -> return $ While e' stmt exprMapper e >>= \e' -> return $ While e' stmt
flatStmtMapper (RepeatL e stmt) = flatStmtMapper (RepeatL e stmt) =
...@@ -304,6 +304,11 @@ traverseExprsM mapper = moduleItemMapper ...@@ -304,6 +304,11 @@ traverseExprsM mapper = moduleItemMapper
flatStmtMapper (Trigger x) = return $ Trigger x flatStmtMapper (Trigger x) = return $ Trigger x
flatStmtMapper (Null) = return Null flatStmtMapper (Null) = return Null
initMapper (Left decl) = declMapper decl >>= return . Left
initMapper (Right (l, e)) = exprMapper e >>= \e' -> return $ Right (l, e')
asgnMapper (l, op, e) = exprMapper e >>= \e' -> return $ (l, op, e')
portBindingMapper (p, me) = portBindingMapper (p, me) =
maybeExprMapper me >>= \me' -> return (p, me') maybeExprMapper me >>= \me' -> return (p, me')
......
...@@ -27,7 +27,7 @@ data Stmt ...@@ -27,7 +27,7 @@ data Stmt
= StmtAttr Attr Stmt = StmtAttr Attr Stmt
| Block (Maybe Identifier) [Decl] [Stmt] | Block (Maybe Identifier) [Decl] [Stmt]
| Case Bool CaseKW Expr [Case] (Maybe Stmt) | Case Bool CaseKW Expr [Case] (Maybe Stmt)
| For (Identifier, Expr) Expr (Identifier, Expr) Stmt | For [Either Decl (LHS, Expr)] (Maybe Expr) [(LHS, AsgnOp, Expr)] Stmt
| AsgnBlk AsgnOp LHS Expr | AsgnBlk AsgnOp LHS Expr
| Asgn (Maybe Timing) LHS Expr | Asgn (Maybe Timing) LHS Expr
| While Expr Stmt | While Expr Stmt
...@@ -58,8 +58,18 @@ instance Show Stmt where ...@@ -58,8 +58,18 @@ instance Show Stmt where
defStr = case def of defStr = case def of
Nothing -> "" Nothing -> ""
Just c -> printf "\n\tdefault: %s" (show c) Just c -> printf "\n\tdefault: %s" (show c)
show (For (a,b) c (d,e) f) = show (For inits mc assigns stmt) =
printf "for (%s = %s; %s; %s = %s)\n%s" a (show b) (show c) d (show e) (indent $ show f) printf "for (%s; %s; %s)\n%s"
(commas $ map showInit inits)
(maybe "" show mc)
(commas $ map showAssign assigns)
(indent $ show stmt)
where
showInit :: Either Decl (LHS, Expr) -> String
showInit (Left d) = init $ show d
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 (commas $ map (maybe "" show) a)
show (AsgnBlk o v e) = printf "%s %s %s;" (show v) (show o) (show e) 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 (Asgn t v e) = printf "%s <= %s%s;" (show v) (maybe "" showPad t) (show e)
......
...@@ -548,7 +548,7 @@ StmtNonAsgn :: { Stmt } ...@@ -548,7 +548,7 @@ StmtNonAsgn :: { Stmt }
| "begin" opt(Tag) DeclsAndStmts "end" opt(Tag) { Block (combineTags $2 $5) (fst $3) (snd $3) } | "begin" opt(Tag) DeclsAndStmts "end" opt(Tag) { Block (combineTags $2 $5) (fst $3) (snd $3) }
| "if" "(" Expr ")" Stmt "else" Stmt { If $3 $5 $7 } | "if" "(" Expr ")" Stmt "else" Stmt { If $3 $5 $7 }
| "if" "(" Expr ")" Stmt %prec NoElse { If $3 $5 Null } | "if" "(" Expr ")" Stmt %prec NoElse { If $3 $5 Null }
| "for" "(" Identifier "=" Expr ";" Expr ";" Identifier "=" Expr ")" Stmt { For ($3, $5) $7 ($9, $11) $13 } | "for" "(" DeclTokens(";") opt(Expr) ";" ForStep ")" Stmt { For (parseDTsAsDeclsAndAsgns $3) $4 $6 $8 }
| Unique CaseKW "(" Expr ")" Cases opt(CaseDefault) "endcase" { Case $1 $2 $4 $6 $7 } | Unique CaseKW "(" Expr ")" Cases opt(CaseDefault) "endcase" { Case $1 $2 $4 $6 $7 }
| TimingControl Stmt { Timing $1 $2 } | TimingControl Stmt { Timing $1 $2 }
| "return" Expr ";" { Return $2 } | "return" Expr ";" { Return $2 }
...@@ -560,6 +560,17 @@ StmtNonAsgn :: { Stmt } ...@@ -560,6 +560,17 @@ StmtNonAsgn :: { Stmt }
| "->" Identifier ";" { Trigger $2 } | "->" Identifier ";" { Trigger $2 }
| AttributeInstance Stmt { StmtAttr $1 $2 } | AttributeInstance Stmt { StmtAttr $1 $2 }
ForStep :: { [(LHS, AsgnOp, Expr)] }
: {- empty -} { [] }
| ForStepNonEmpty { $1 }
ForStepNonEmpty :: { [(LHS, AsgnOp, Expr)] }
: ForStepAssignment { [$1] }
| ForStepNonEmpty "," ForStepAssignment { $1 ++ [$3] }
ForStepAssignment :: { (LHS, AsgnOp, Expr) }
: LHS AsgnOp Expr { ($1, $2, $3) }
| IncOrDecOperator LHS { ($2, AsgnOp $1, Number "1") }
| LHS IncOrDecOperator { ($1, AsgnOp $2, Number "1") }
DeclsAndStmts :: { ([Decl], [Stmt]) } DeclsAndStmts :: { ([Decl], [Stmt]) }
: DeclOrStmt DeclsAndStmts { combineDeclsAndStmts $1 $2 } : DeclOrStmt DeclsAndStmts { combineDeclsAndStmts $1 $2 }
| StmtNonAsgn Stmts { ([], $1 : $2) } | StmtNonAsgn Stmts { ([], $1 : $2) }
......
...@@ -36,10 +36,11 @@ module Language.SystemVerilog.Parser.ParseDecl ...@@ -36,10 +36,11 @@ module Language.SystemVerilog.Parser.ParseDecl
, parseDTsAsDecls , parseDTsAsDecls
, parseDTsAsDecl , parseDTsAsDecl
, parseDTsAsDeclOrAsgn , parseDTsAsDeclOrAsgn
, parseDTsAsDeclsAndAsgns
) where ) where
import Data.List (findIndices) import Data.List (elemIndex, findIndex, findIndices)
import Data.Maybe (mapMaybe) import Data.Maybe (fromJust, mapMaybe)
import Language.SystemVerilog.AST import Language.SystemVerilog.AST
...@@ -187,13 +188,41 @@ parseDTsAsDeclOrAsgn tokens = ...@@ -187,13 +188,41 @@ parseDTsAsDeclOrAsgn tokens =
DTAsgn op e -> (AsgnBlk op, e) DTAsgn op e -> (AsgnBlk op, e)
DTAsgnNBlk mt e -> (Asgn mt, e) DTAsgnNBlk mt e -> (Asgn mt, e)
_ -> error $ "invalid block item decl or stmt: " ++ (show tokens) _ -> error $ "invalid block item decl or stmt: " ++ (show tokens)
Just lhs = foldl takeLHSStep Nothing $ init tokens lhs = takeLHS $ init tokens
isAsgnToken :: DeclToken -> Bool
isAsgnToken (DTBit _) = True -- [PUBLIC]: parser for mixed comma-separated declaration and assignment lists;
isAsgnToken (DTConcat _) = True -- the main use case is for `for` loop initialization lists
isAsgnToken (DTAsgnNBlk _ _) = True parseDTsAsDeclsAndAsgns :: [DeclToken] -> [Either Decl (LHS, Expr)]
isAsgnToken (DTAsgn (AsgnOp _) _) = True parseDTsAsDeclsAndAsgns [] = []
isAsgnToken _ = False parseDTsAsDeclsAndAsgns tokens =
if hasLeadingAsgn
then
let (lhsToks, l0) = break isAsgnToken tokens
lhs = takeLHS lhsToks
DTAsgnNBlk Nothing expr : l1 = l0
DTComma : remaining = l1
in Right (lhs, expr) : parseDTsAsDeclsAndAsgns remaining
else
let (component, remaining) = parseDTsAsComponent tokens
decls = finalize component
in (map Left decls) ++ parseDTsAsDeclsAndAsgns remaining
where
hasLeadingAsgn =
-- if there is an asgn token before the next comma
case (elemIndex DTComma tokens, findIndex isAsgnToken tokens) of
(Just a, Just b) -> a > b
(Nothing, Just _) -> True
_ -> False
isAsgnToken :: DeclToken -> Bool
isAsgnToken (DTBit _) = True
isAsgnToken (DTConcat _) = True
isAsgnToken (DTAsgnNBlk _ _) = True
isAsgnToken (DTAsgn (AsgnOp _) _) = True
isAsgnToken _ = False
takeLHS :: [DeclToken] -> LHS
takeLHS tokens = fromJust $ foldl takeLHSStep Nothing tokens
takeLHSStep :: Maybe LHS -> DeclToken -> Maybe LHS takeLHSStep :: Maybe LHS -> DeclToken -> Maybe LHS
takeLHSStep (Nothing ) (DTConcat lhss) = Just $ LHSConcat lhss takeLHSStep (Nothing ) (DTConcat lhss) = Just $ LHSConcat lhss
...@@ -216,8 +245,15 @@ finalize (dir, typ, trips) = ...@@ -216,8 +245,15 @@ finalize (dir, typ, trips) =
-- internal; entrypoint of the critical portion of our parser -- internal; entrypoint of the critical portion of our parser
parseDTsAsComponents :: [DeclToken] -> [Component] parseDTsAsComponents :: [DeclToken] -> [Component]
parseDTsAsComponents [] = [] parseDTsAsComponents [] = []
parseDTsAsComponents l0 = parseDTsAsComponents tokens =
component : parseDTsAsComponents l4 component : parseDTsAsComponents tokens'
where
(component, tokens') = parseDTsAsComponent tokens
parseDTsAsComponent :: [DeclToken] -> (Component, [DeclToken])
parseDTsAsComponent [] = error "parseDTsAsComponent unexpected end of tokens"
parseDTsAsComponent l0 =
(component, l4)
where where
(dir, l1) = takeDir l0 (dir, l1) = takeDir l0
(tf , l2) = takeType l1 (tf , l2) = takeType l1
......
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