Commit b7959c7a by Zachary Snow

support for statement labels and basic fork-join

parent d57c9670
...@@ -20,8 +20,8 @@ convert = ...@@ -20,8 +20,8 @@ convert =
$ traverseStmts $ convertStmt $ traverseStmts $ convertStmt
convertStmt :: Stmt -> Stmt convertStmt :: Stmt -> Stmt
convertStmt (Block name decls stmts) = convertStmt (Block Seq name decls stmts) =
Block name decls' stmts' Block Seq name decls' stmts'
where where
splitDecls = map splitDecl decls splitDecls = map splitDecl decls
decls' = map fst splitDecls decls' = map fst splitDecls
......
...@@ -11,8 +11,6 @@ ...@@ -11,8 +11,6 @@
module Convert.ForDecl (convert) where module Convert.ForDecl (convert) where
import Data.Either (isLeft, isRight, lefts, rights)
import Convert.Traverse import Convert.Traverse
import Language.SystemVerilog.AST import Language.SystemVerilog.AST
...@@ -24,14 +22,14 @@ convert = ...@@ -24,14 +22,14 @@ convert =
) )
convertGenItem :: GenItem -> GenItem convertGenItem :: GenItem -> GenItem
convertGenItem (GenFor (True, x, e) a b mbx c) = convertGenItem (GenFor (True, x, e) a b bx c) =
GenBlock Nothing genItems GenBlock "" genItems
where where
x' = (maybe "" (++ "_") mbx) ++ x x' = if null bx then x else bx ++ "_" ++ x
Generate genItems = Generate genItems =
traverseNestedModuleItems converter $ Generate $ traverseNestedModuleItems converter $ Generate $
[ GenModuleItem $ Genvar x' [ GenModuleItem $ Genvar x'
, GenFor (False, x, e) a b mbx c , GenFor (False, x, e) a b bx c
] ]
converter = converter =
(traverseExprs $ traverseNestedExprs convertExpr) . (traverseExprs $ traverseNestedExprs convertExpr) .
...@@ -45,33 +43,28 @@ convertGenItem (GenFor (True, x, e) a b mbx c) = ...@@ -45,33 +43,28 @@ convertGenItem (GenFor (True, x, e) a b mbx c) =
convertGenItem other = other convertGenItem other = other
convertStmt :: Stmt -> Stmt convertStmt :: Stmt -> Stmt
convertStmt (For [] cc asgns stmt) = convertStmt (For (Left []) cc asgns stmt) =
convertStmt $ For (Right []) cc asgns stmt
convertStmt (For (Right []) cc asgns stmt) =
convertStmt $ For inits cc asgns stmt convertStmt $ For inits cc asgns stmt
where inits = [Left $ dummyDecl (Just $ Number "0")] where inits = Left [dummyDecl (Just $ Number "0")]
convertStmt (orig @ (For [Right _] _ _ _)) = orig convertStmt (orig @ (For (Right [_]) _ _ _)) = orig
convertStmt (orig @ (For (inits @ (Left _: _)) cc asgns stmt)) = convertStmt (For (Left inits) cc asgns stmt) =
if not $ all isLeft inits Block Seq "" decls $
then error $ "for loop has mix of decls and asgns: " ++ show orig initAsgns ++
else Block [For (Right [(lhs, expr)]) cc asgns stmt]
Nothing
decls
(initAsgns ++ [For [Right (lhs, expr)] cc asgns stmt])
where where
splitDecls = map splitDecl $ lefts inits splitDecls = map splitDecl inits
decls = map fst splitDecls decls = map fst splitDecls
initAsgns = map asgnStmt $ init $ map snd splitDecls initAsgns = map asgnStmt $ init $ map snd splitDecls
(lhs, expr) = snd $ last splitDecls (lhs, expr) = snd $ last splitDecls
convertStmt (orig @ (For inits cc asgns stmt)) = convertStmt (For (Right origPairs) cc asgns stmt) =
if not $ all isRight inits Block Seq "" [] $
then error $ "for loop has mix of decls and asgns: " ++ show orig initAsgns ++
else Block [For (Right [(lhs, expr)]) cc asgns stmt]
Nothing
[]
(initAsgns ++ [For [Right (lhs, expr)] cc asgns stmt])
where where
origPairs = rights inits
(lhs, expr) = last origPairs (lhs, expr) = last origPairs
initAsgns = map asgnStmt $ init origPairs initAsgns = map asgnStmt $ init origPairs
......
...@@ -25,7 +25,7 @@ convertStmt (Foreach x idxs stmt) = ...@@ -25,7 +25,7 @@ convertStmt (Foreach x idxs stmt) =
toLoop :: (Int, Maybe Identifier) -> (Stmt -> Stmt) toLoop :: (Int, Maybe Identifier) -> (Stmt -> Stmt)
toLoop (_, Nothing) = id toLoop (_, Nothing) = id
toLoop (d, Just i) = toLoop (d, Just i) =
For [Left idxDecl] (Just cmp) [incr] For (Left [idxDecl]) cmp [incr]
where where
queryFn f = DimFn f (Right $ Ident x) (Number $ show d) queryFn f = DimFn f (Right $ Ident x) (Number $ show d)
idxDecl = Variable Local (IntegerAtom TInteger Unspecified) i [] idxDecl = Variable Local (IntegerAtom TInteger Unspecified) i []
......
...@@ -26,19 +26,19 @@ convert asts = ...@@ -26,19 +26,19 @@ convert asts =
where runner = mapM . traverseDescriptionsM . traverseModuleItemsM . traverseStmtsM where runner = mapM . traverseDescriptionsM . traverseModuleItemsM . traverseStmtsM
collectStmtM :: Stmt -> State Idents Stmt collectStmtM :: Stmt -> State Idents Stmt
collectStmtM (Block (Just x) decls stmts) = do collectStmtM (Block kw x decls stmts) = do
modify $ Set.insert x modify $ Set.insert x
return $ Block (Just x) decls stmts return $ Block kw x decls stmts
collectStmtM other = return other collectStmtM other = return other
traverseStmtM :: Stmt -> State Idents Stmt traverseStmtM :: Stmt -> State Idents Stmt
traverseStmtM (Block Nothing [] stmts) = traverseStmtM (Block kw "" [] stmts) =
return $ Block Nothing [] stmts return $ Block kw "" [] stmts
traverseStmtM (Block Nothing decls stmts) = do traverseStmtM (Block kw "" decls stmts) = do
names <- get names <- get
let x = uniqueBlockName names let x = uniqueBlockName names
modify $ Set.insert x modify $ Set.insert x
return $ Block (Just x) decls stmts return $ Block kw x decls stmts
traverseStmtM other = return other traverseStmtM other = return other
uniqueBlockName :: Idents -> Identifier uniqueBlockName :: Idents -> Identifier
......
...@@ -27,4 +27,4 @@ convertPackageItem other = other ...@@ -27,4 +27,4 @@ convertPackageItem other = other
stmtsToStmt :: [Stmt] -> Stmt stmtsToStmt :: [Stmt] -> Stmt
stmtsToStmt [stmt] = stmt stmtsToStmt [stmt] = stmt
stmtsToStmt stmts = Block Nothing [] stmts stmtsToStmt stmts = Block Seq "" [] stmts
...@@ -29,7 +29,7 @@ convertDescription other = other ...@@ -29,7 +29,7 @@ convertDescription other = other
streamerBlock :: Expr -> Expr -> (LHS -> Expr -> Stmt) -> LHS -> Expr -> Stmt streamerBlock :: Expr -> Expr -> (LHS -> Expr -> Stmt) -> LHS -> Expr -> Stmt
streamerBlock chunk size asgn output input = streamerBlock chunk size asgn output input =
Block Nothing Block Seq ""
[ Variable Local t inp [] $ Just input [ Variable Local t inp [] $ Just input
, Variable Local t out [] Nothing , Variable Local t out [] Nothing
, Variable Local (IntegerAtom TInteger Unspecified) idx [] Nothing , Variable Local (IntegerAtom TInteger Unspecified) idx [] Nothing
...@@ -50,14 +50,14 @@ streamerBlock chunk size asgn output input = ...@@ -50,14 +50,14 @@ streamerBlock chunk size asgn output input =
idx = name ++ "_idx" idx = name ++ "_idx"
bas = name ++ "_bas" bas = name ++ "_bas"
-- main chunk loop -- main chunk loop
inits = [Right (LHSIdent idx, lo)] inits = Right [(LHSIdent idx, lo)]
cmp = Just $ BinOp Le (Ident idx) (BinOp Sub hi chunk) cmp = BinOp Le (Ident idx) (BinOp Sub hi chunk)
incr = [(LHSIdent idx, AsgnOp Add, chunk)] incr = [(LHSIdent idx, AsgnOp Add, chunk)]
lhs = LHSRange (LHSIdent out) IndexedMinus (BinOp Sub hi (Ident idx), chunk) lhs = LHSRange (LHSIdent out) IndexedMinus (BinOp Sub hi (Ident idx), chunk)
expr = Range (Ident inp) IndexedPlus (Ident idx, chunk) expr = Range (Ident inp) IndexedPlus (Ident idx, chunk)
stmt = AsgnBlk AsgnOpEq lhs expr stmt = AsgnBlk AsgnOpEq lhs expr
-- final chunk loop -- final chunk loop
cmp2 = Just $ BinOp Lt (Ident idx) (BinOp Sub size (Ident bas)) cmp2 = BinOp Lt (Ident idx) (BinOp Sub size (Ident bas))
incr2 = [(LHSIdent idx, AsgnOp Add, Number "1")] incr2 = [(LHSIdent idx, AsgnOp Add, Number "1")]
lhs2 = LHSBit (LHSIdent out) (Ident idx) lhs2 = LHSBit (LHSIdent out) (Ident idx)
expr2 = Bit (Ident inp) (BinOp Add (Ident idx) (Ident bas)) expr2 = Bit (Ident inp) (BinOp Add (Ident idx) (Ident bas))
......
...@@ -126,7 +126,7 @@ traverseModuleItemsM mapper (Part attrs extern kw lifetime name ports items) = d ...@@ -126,7 +126,7 @@ traverseModuleItemsM mapper (Part attrs extern kw lifetime name ports items) = d
let items'' = concatMap breakGenerate items' let items'' = concatMap breakGenerate items'
return $ Part attrs extern kw lifetime name ports items'' return $ Part attrs extern kw lifetime name ports items''
where where
fullMapper (Generate [GenBlock Nothing genItems]) = fullMapper (Generate [GenBlock "" genItems]) =
mapM fullGenItemMapper genItems >>= mapper . Generate mapM fullGenItemMapper genItems >>= mapper . Generate
fullMapper (Generate genItems) = do fullMapper (Generate genItems) = do
let genItems' = filter (/= GenNull) genItems let genItems' = filter (/= GenNull) genItems
...@@ -138,7 +138,7 @@ traverseModuleItemsM mapper (Part attrs extern kw lifetime name ports items) = d ...@@ -138,7 +138,7 @@ traverseModuleItemsM mapper (Part attrs extern kw lifetime name ports items) = d
genItemMapper (GenModuleItem moduleItem) = do genItemMapper (GenModuleItem moduleItem) = do
moduleItem' <- fullMapper moduleItem moduleItem' <- fullMapper moduleItem
return $ case moduleItem' of return $ case moduleItem' of
Generate subItems -> GenBlock Nothing subItems Generate subItems -> GenBlock "" subItems
_ -> GenModuleItem moduleItem' _ -> GenModuleItem moduleItem'
genItemMapper (GenIf (Number "1") s _) = return s genItemMapper (GenIf (Number "1") s _) = return s
genItemMapper (GenIf (Number "0") _ s) = return s genItemMapper (GenIf (Number "0") _ s) = return s
...@@ -228,9 +228,9 @@ traverseSinglyNestedStmtsM :: Monad m => MapperM m Stmt -> MapperM m Stmt ...@@ -228,9 +228,9 @@ traverseSinglyNestedStmtsM :: Monad m => MapperM m Stmt -> MapperM m Stmt
traverseSinglyNestedStmtsM fullMapper = cs traverseSinglyNestedStmtsM fullMapper = cs
where where
cs (StmtAttr a stmt) = fullMapper stmt >>= return . StmtAttr a cs (StmtAttr a stmt) = fullMapper stmt >>= return . StmtAttr a
cs (Block Nothing [] []) = return Null cs (Block _ "" [] []) = return Null
cs (Block name decls stmts) = cs (Block kw name decls stmts) =
mapM fullMapper stmts >>= return . Block name decls mapM fullMapper stmts >>= return . Block kw name decls
cs (Case u kw expr cases def) = do cs (Case u kw expr cases def) = do
caseStmts <- mapM fullMapper $ map snd cases caseStmts <- mapM fullMapper $ map snd cases
let cases' = zip (map fst cases) caseStmts let cases' = zip (map fst cases) caseStmts
...@@ -373,16 +373,17 @@ traverseStmtLHSsM mapper = stmtMapper ...@@ -373,16 +373,17 @@ traverseStmtLHSsM mapper = stmtMapper
stmtMapper (AsgnBlk op lhs expr) = fullMapper lhs >>= \lhs' -> return $ AsgnBlk op lhs' expr stmtMapper (AsgnBlk op lhs expr) = fullMapper lhs >>= \lhs' -> return $ AsgnBlk op lhs' expr
stmtMapper (Asgn mt lhs expr) = fullMapper lhs >>= \lhs' -> return $ Asgn mt lhs' expr stmtMapper (Asgn mt lhs expr) = fullMapper lhs >>= \lhs' -> return $ Asgn mt lhs' expr
stmtMapper (For inits me incrs stmt) = do stmtMapper (For inits me incrs stmt) = do
inits' <- mapM mapInit inits inits' <- mapInits inits
let (lhss, asgnOps, exprs) = unzip3 incrs let (lhss, asgnOps, exprs) = unzip3 incrs
lhss' <- mapM fullMapper lhss lhss' <- mapM fullMapper lhss
let incrs' = zip3 lhss' asgnOps exprs let incrs' = zip3 lhss' asgnOps exprs
return $ For inits' me incrs' stmt return $ For inits' me incrs' stmt
where where
mapInit (Left decl) = return $ Left decl mapInits (Left decls) = return $ Left decls
mapInit (Right (lhs, expr)) = do mapInits (Right asgns) = do
lhs' <- fullMapper lhs let (lhss, exprs) = unzip asgns
return $ Right (lhs', expr) lhss' <- mapM fullMapper lhss
return $ Right $ zip lhss' exprs
stmtMapper (Assertion a) = stmtMapper (Assertion a) =
assertionMapper a >>= return . Assertion assertionMapper a >>= return . Assertion
stmtMapper other = return other stmtMapper other = return other
...@@ -664,9 +665,9 @@ traverseStmtExprsM exprMapper = flatStmtMapper ...@@ -664,9 +665,9 @@ traverseStmtExprsM exprMapper = flatStmtMapper
flatStmtMapper (StmtAttr attr stmt) = flatStmtMapper (StmtAttr attr stmt) =
-- note: we exclude expressions in attributes from conversion -- note: we exclude expressions in attributes from conversion
return $ StmtAttr attr stmt return $ StmtAttr attr stmt
flatStmtMapper (Block name decls stmts) = do flatStmtMapper (Block kw name decls stmts) = do
decls' <- mapM declMapper decls decls' <- mapM declMapper decls
return $ Block name decls' stmts return $ Block kw name decls' stmts
flatStmtMapper (Case u kw e cases def) = do flatStmtMapper (Case u kw e cases def) = do
e' <- exprMapper e e' <- exprMapper e
cases' <- mapM caseMapper cases cases' <- mapM caseMapper cases
...@@ -680,8 +681,8 @@ traverseStmtExprsM exprMapper = flatStmtMapper ...@@ -680,8 +681,8 @@ traverseStmtExprsM exprMapper = flatStmtMapper
expr' <- exprMapper expr expr' <- exprMapper expr
return $ Asgn mt lhs' expr' return $ Asgn mt lhs' expr'
flatStmtMapper (For inits cc asgns stmt) = do flatStmtMapper (For inits cc asgns stmt) = do
inits' <- mapM initMapper inits inits' <- initsMapper inits
cc' <- maybeExprMapper cc cc' <- exprMapper cc
asgns' <- mapM asgnMapper asgns asgns' <- mapM asgnMapper asgns
return $ For inits' cc' asgns' stmt return $ For inits' cc' asgns' stmt
flatStmtMapper (While e stmt) = flatStmtMapper (While e stmt) =
...@@ -709,8 +710,9 @@ traverseStmtExprsM exprMapper = flatStmtMapper ...@@ -709,8 +710,9 @@ traverseStmtExprsM exprMapper = flatStmtMapper
return $ Assertion a'' return $ Assertion a''
flatStmtMapper (Null) = return Null flatStmtMapper (Null) = return Null
initMapper (Left decl) = declMapper decl >>= return . Left initsMapper (Left decls) = mapM declMapper decls >>= return . Left
initMapper (Right (l, e)) = exprMapper e >>= \e' -> return $ Right (l, e') initsMapper (Right asgns) = mapM mapper asgns >>= return . Right
where mapper (l, e) = exprMapper e >>= return . (,) l
asgnMapper (l, op, e) = exprMapper e >>= \e' -> return $ (l, op, e') asgnMapper (l, op, e) = exprMapper e >>= \e' -> return $ (l, op, e')
...@@ -802,9 +804,9 @@ traverseDeclsM' strat mapper item = do ...@@ -802,9 +804,9 @@ traverseDeclsM' strat mapper item = do
else return decls else return decls
return $ MIPackageItem $ Task l x decls' stmts return $ MIPackageItem $ Task l x decls' stmts
miMapper other = return other miMapper other = return other
stmtMapper (Block name decls stmts) = do stmtMapper (Block kw name decls stmts) = do
decls' <- mapM mapper decls decls' <- mapM mapper decls
return $ Block name decls' stmts return $ Block kw name decls' stmts
stmtMapper other = return other stmtMapper other = return other
traverseDecls' :: TFStrategy -> Mapper Decl -> Mapper ModuleItem traverseDecls' :: TFStrategy -> Mapper Decl -> Mapper ModuleItem
...@@ -938,7 +940,7 @@ traverseSinglyNestedGenItemsM fullMapper = gim ...@@ -938,7 +940,7 @@ traverseSinglyNestedGenItemsM fullMapper = gim
return $ GenModuleItem moduleItem return $ GenModuleItem moduleItem
gim (GenNull) = return GenNull gim (GenNull) = return GenNull
flattenBlocks :: GenItem -> [GenItem] flattenBlocks :: GenItem -> [GenItem]
flattenBlocks (GenBlock Nothing items) = items flattenBlocks (GenBlock "" items) = items
flattenBlocks other = [other] flattenBlocks other = [other]
traverseAsgnsM' :: Monad m => TFStrategy -> MapperM m (LHS, Expr) -> MapperM m ModuleItem traverseAsgnsM' :: Monad m => TFStrategy -> MapperM m (LHS, Expr) -> MapperM m ModuleItem
...@@ -1032,10 +1034,10 @@ traverseScopesM declMapper moduleItemMapper stmtMapper = ...@@ -1032,10 +1034,10 @@ traverseScopesM declMapper moduleItemMapper stmtMapper =
nestedStmtMapper stmt = nestedStmtMapper stmt =
stmtMapper stmt >>= traverseSinglyNestedStmtsM fullStmtMapper stmtMapper stmt >>= traverseSinglyNestedStmtsM fullStmtMapper
fullStmtMapper (Block name decls stmts) = do fullStmtMapper (Block kw name decls stmts) = do
prevState <- get prevState <- get
decls' <- mapM declMapper decls decls' <- mapM declMapper decls
block <- nestedStmtMapper $ Block name decls' stmts block <- nestedStmtMapper $ Block kw name decls' stmts
put prevState put prevState
return block return block
fullStmtMapper other = nestedStmtMapper other fullStmtMapper other = nestedStmtMapper other
......
...@@ -20,9 +20,9 @@ import Language.SystemVerilog.AST.Type (Identifier) ...@@ -20,9 +20,9 @@ import Language.SystemVerilog.AST.Type (Identifier)
import {-# SOURCE #-} Language.SystemVerilog.AST.ModuleItem (ModuleItem) import {-# SOURCE #-} Language.SystemVerilog.AST.ModuleItem (ModuleItem)
data GenItem data GenItem
= GenBlock (Maybe Identifier) [GenItem] = GenBlock Identifier [GenItem]
| GenCase Expr [GenCase] (Maybe GenItem) | GenCase Expr [GenCase] (Maybe GenItem)
| GenFor (Bool, Identifier, Expr) Expr (Identifier, AsgnOp, Expr) (Maybe Identifier) [GenItem] | GenFor (Bool, Identifier, Expr) Expr (Identifier, AsgnOp, Expr) Identifier [GenItem]
| GenIf Expr GenItem GenItem | GenIf Expr GenItem GenItem
| GenNull | GenNull
| GenModuleItem ModuleItem | GenModuleItem ModuleItem
...@@ -30,9 +30,9 @@ data GenItem ...@@ -30,9 +30,9 @@ data GenItem
instance Show GenItem where instance Show GenItem where
showList i _ = unlines' $ map show i showList i _ = unlines' $ map show i
show (GenBlock mx i) = show (GenBlock x i) =
printf "begin%s\n%s\nend" printf "begin%s\n%s\nend"
(maybe "" (" : " ++) mx) (if null x then "" else " : " ++ x)
(indent $ unlines' $ map show i) (indent $ unlines' $ map show i)
show (GenCase e cs def) = show (GenCase e cs def) =
printf "case (%s)\n%s%s\nendcase" (show e) bodyStr defStr printf "case (%s)\n%s%s\nendcase" (show e) bodyStr defStr
...@@ -43,13 +43,13 @@ instance Show GenItem where ...@@ -43,13 +43,13 @@ instance Show GenItem where
Just c -> printf "\n\tdefault: %s" (show c) Just c -> printf "\n\tdefault: %s" (show c)
show (GenIf e a GenNull) = printf "if (%s) %s" (show e) (show a) show (GenIf e a GenNull) = printf "if (%s) %s" (show e) (show a)
show (GenIf e a b ) = printf "if (%s) %s\nelse %s" (show e) (show a) (show b) show (GenIf e a b ) = printf "if (%s) %s\nelse %s" (show e) (show a) (show b)
show (GenFor (new, x1, e1) c (x2, o2, e2) mx is) = show (GenFor (new, x1, e1) c (x2, o2, e2) x is) =
printf "for (%s%s = %s; %s; %s %s %s) %s" printf "for (%s%s = %s; %s; %s %s %s) %s"
(if new then "genvar " else "") (if new then "genvar " else "")
x1 (show e1) x1 (show e1)
(show c) (show c)
x2 (show o2) (show e2) x2 (show o2) (show e2)
(show $ GenBlock mx is) (show $ GenBlock x is)
show (GenNull) = ";" show (GenNull) = ";"
show (GenModuleItem item) = show item show (GenModuleItem item) = show item
......
...@@ -20,6 +20,7 @@ module Language.SystemVerilog.AST.Stmt ...@@ -20,6 +20,7 @@ module Language.SystemVerilog.AST.Stmt
, Assertion (..) , Assertion (..)
, PropertySpec (..) , PropertySpec (..)
, UniquePriority (..) , UniquePriority (..)
, BlockKW (..)
) where ) where
import Text.Printf (printf) import Text.Printf (printf)
...@@ -29,14 +30,14 @@ import Language.SystemVerilog.AST.Attr (Attr) ...@@ -29,14 +30,14 @@ import Language.SystemVerilog.AST.Attr (Attr)
import Language.SystemVerilog.AST.Decl (Decl) import Language.SystemVerilog.AST.Decl (Decl)
import Language.SystemVerilog.AST.Expr (Expr, Args) import Language.SystemVerilog.AST.Expr (Expr, Args)
import Language.SystemVerilog.AST.LHS (LHS) import Language.SystemVerilog.AST.LHS (LHS)
import Language.SystemVerilog.AST.Op (AsgnOp) import Language.SystemVerilog.AST.Op (AsgnOp(AsgnOpEq))
import Language.SystemVerilog.AST.Type (Identifier) import Language.SystemVerilog.AST.Type (Identifier)
data Stmt data Stmt
= StmtAttr Attr Stmt = StmtAttr Attr Stmt
| Block (Maybe Identifier) [Decl] [Stmt] | Block BlockKW Identifier [Decl] [Stmt]
| Case (Maybe UniquePriority) CaseKW Expr [Case] (Maybe Stmt) | Case (Maybe UniquePriority) CaseKW Expr [Case] (Maybe Stmt)
| For [Either Decl (LHS, Expr)] (Maybe Expr) [(LHS, AsgnOp, Expr)] Stmt | For (Either [Decl] [(LHS, Expr)]) 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
...@@ -55,10 +56,10 @@ data Stmt ...@@ -55,10 +56,10 @@ data Stmt
instance Show Stmt where instance Show Stmt where
show (StmtAttr attr stmt) = printf "%s\n%s" (show attr) (show stmt) show (StmtAttr attr stmt) = printf "%s\n%s" (show attr) (show stmt)
show (Block name decls stmts) = show (Block kw name decls stmts) =
printf "begin%s\n%s\nend" header body printf "%s%s\n%s\n%s" (show kw) header body (blockEndToken kw)
where where
header = maybe "" (" : " ++) name header = if null name then "" else " : " ++ name
bodyLines = (map show decls) ++ (map show stmts) bodyLines = (map show decls) ++ (map show stmts)
body = indent $ unlines' bodyLines body = indent $ unlines' bodyLines
show (Case u kw e cs def) = show (Case u kw e cs def) =
...@@ -68,16 +69,17 @@ instance Show Stmt where ...@@ -68,16 +69,17 @@ 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 inits mc assigns stmt) = show (For inits cond assigns stmt) =
printf "for (%s; %s; %s)\n%s" printf "for (%s; %s; %s)\n%s"
(commas $ map showInit inits) (showInits inits)
(maybe "" show mc) (show cond)
(commas $ map showAssign assigns) (commas $ map showAssign assigns)
(indent $ show stmt) (indent $ show stmt)
where where
showInit :: Either Decl (LHS, Expr) -> String showInits :: Either [Decl] [(LHS, Expr)] -> String
showInit (Left d) = init $ show d showInits (Left decls) = commas $ map (init . show) decls
showInit (Right (l, e)) = printf "%s = %s" (show l) (show e) showInits (Right asgns) = commas $ map showInit asgns
where showInit (l, e) = showAssign (l, AsgnOpEq, e)
showAssign :: (LHS, AsgnOp, Expr) -> String showAssign :: (LHS, AsgnOp, Expr) -> String
showAssign (l, op, e) = printf "%s %s %s" (show l) (show op) (show e) showAssign (l, op, e) = printf "%s %s %s" (show l) (show op) (show e)
show (Subroutine ps x a) = printf "%s%s(%s);" (maybe "" (++ "::") ps) x (show a) show (Subroutine ps x a) = printf "%s%s(%s);" (maybe "" (++ "::") ps) x (show a)
...@@ -221,3 +223,16 @@ instance Show UniquePriority where ...@@ -221,3 +223,16 @@ instance Show UniquePriority where
show Unique = "unique" show Unique = "unique"
show Unique0 = "unique0" show Unique0 = "unique0"
show Priority = "priority" show Priority = "priority"
data BlockKW
= Seq
| Par
deriving Eq
instance Show BlockKW where
show Seq = "begin"
show Par = "fork"
blockEndToken :: BlockKW -> Identifier
blockEndToken Seq = "end"
blockEndToken Par = "join"
...@@ -518,6 +518,10 @@ PackageDeclaration :: { Description } ...@@ -518,6 +518,10 @@ PackageDeclaration :: { Description }
Tag :: { Identifier } Tag :: { Identifier }
: ":" Identifier { $2 } : ":" Identifier { $2 }
StrTag :: { Identifier }
: {- empty -} { "" }
| ":" Identifier { $2 }
PackageImportDeclarations :: { [ModuleItem] } PackageImportDeclarations :: { [ModuleItem] }
: PackageImportDeclaration PackageImportDeclarations { $1 ++ $2 } : PackageImportDeclaration PackageImportDeclarations { $1 ++ $2 }
| {- empty -} { [] } | {- empty -} { [] }
...@@ -700,7 +704,7 @@ SeqMatchItems :: { [SeqMatchItem] } ...@@ -700,7 +704,7 @@ SeqMatchItems :: { [SeqMatchItem] }
| SeqMatchItems "," SeqMatchItem { $1 ++ [$3] } | SeqMatchItems "," SeqMatchItem { $1 ++ [$3] }
SeqMatchItem :: { SeqMatchItem } SeqMatchItem :: { SeqMatchItem }
: ForStepAssignment { Left $1 } : ForStepAssignment { Left $1 }
| Identifier "(" CallArgs ")" { Right ($1, $3) } | Identifier CallArgs { Right ($1, $2) }
ActionBlock :: { ActionBlock } ActionBlock :: { ActionBlock }
: Stmt %prec NoElse { ActionBlockIf $1 } : Stmt %prec NoElse { ActionBlockIf $1 }
...@@ -879,22 +883,31 @@ Stmts :: { [Stmt] } ...@@ -879,22 +883,31 @@ Stmts :: { [Stmt] }
| Stmts Stmt { $1 ++ [$2] } | Stmts Stmt { $1 ++ [$2] }
Stmt :: { Stmt } Stmt :: { Stmt }
: StmtNonAsgn { $1 } : StmtAsgn { $1 }
| LHS AsgnOp Expr ";" { AsgnBlk $2 $1 $3 } | StmtNonAsgn { $1 }
StmtAsgn :: { Stmt }
: LHS AsgnOp Expr ";" { AsgnBlk $2 $1 $3 }
| LHS IncOrDecOperator ";" { AsgnBlk (AsgnOp $2) $1 (Number "1") }
| LHS "<=" opt(DelayOrEventControl) Expr ";" { Asgn $3 $1 $4 }
| Identifier ";" { Subroutine (Nothing) $1 (Args [] []) } | Identifier ";" { Subroutine (Nothing) $1 (Args [] []) }
| Identifier "::" Identifier ";" { Subroutine (Just $1) $3 (Args [] []) } | Identifier "::" Identifier ";" { Subroutine (Just $1) $3 (Args [] []) }
| LHS "<=" opt(DelayOrEventControl) Expr ";" { Asgn $3 $1 $4 }
| LHS IncOrDecOperator ";" { AsgnBlk (AsgnOp $2) $1 (Number "1") }
StmtNonAsgn :: { Stmt } StmtNonAsgn :: { Stmt }
: StmtBlock(BlockKWSeq, "end" ) { $1 }
| StmtBlock(BlockKWPar, "join") { $1 }
| StmtNonBlock { $1 }
| Identifier ":" StmtNonBlock { Block Seq $1 [] [$3] }
StmtBlock(begin, end) :: { Stmt }
: begin StrTag DeclsAndStmts end StrTag { uncurry (Block $1 $ combineTags $2 $5) $3 }
| Identifier ":" begin DeclsAndStmts end StrTag { uncurry (Block $3 $ combineTags $1 $6) $4 }
StmtNonBlock :: { Stmt }
: ";" { Null } : ";" { Null }
| "begin" opt(Tag) DeclsAndStmts "end" opt(Tag) { Block (combineTags $2 $5) (fst $3) (snd $3) }
| Unique "if" "(" Expr ")" Stmt "else" Stmt { If $1 $4 $6 $8 } | Unique "if" "(" Expr ")" Stmt "else" Stmt { If $1 $4 $6 $8 }
| Unique "if" "(" Expr ")" Stmt %prec NoElse { If $1 $4 $6 Null } | Unique "if" "(" Expr ")" Stmt %prec NoElse { If $1 $4 $6 Null }
| "for" "(" ";" opt(Expr) ";" ForStep ")" Stmt { For [] $4 $6 $8 } | "for" "(" ForInit ForCond ForStep ")" Stmt { For $3 $4 $5 $7 }
| "for" "(" DeclTokens(";") opt(Expr) ";" ForStep ")" Stmt { For (parseDTsAsDeclsAndAsgns $3) $4 $6 $8 } | Unique CaseKW "(" Expr ")" Cases "endcase" { Case $1 $2 $4 (fst $6) (snd $6) }
| Unique CaseKW "(" Expr ")" CasesWithDefault "endcase" { Case $1 $2 $4 (fst $6) (snd $6) } | Identifier CallArgs ";" { Subroutine (Nothing) $1 $2 }
| Identifier "(" CallArgs ")" ";" { Subroutine (Nothing) $1 $3 } | Identifier "::" Identifier CallArgs ";" { Subroutine (Just $1) $3 $4 }
| Identifier "::" Identifier "(" CallArgs ")" ";" { Subroutine (Just $1) $3 $5 }
| TimingControl Stmt { Timing $1 $2 } | TimingControl Stmt { Timing $1 $2 }
| "return" Expr ";" { Return $2 } | "return" Expr ";" { Return $2 }
| "while" "(" Expr ")" Stmt { While $3 $5 } | "while" "(" Expr ")" Stmt { While $3 $5 }
...@@ -907,12 +920,25 @@ StmtNonAsgn :: { Stmt } ...@@ -907,12 +920,25 @@ StmtNonAsgn :: { Stmt }
| ProceduralAssertionStatement { Assertion $1 } | ProceduralAssertionStatement { Assertion $1 }
| IncOrDecOperator LHS ";" { AsgnBlk (AsgnOp $1) $2 (Number "1") } | IncOrDecOperator LHS ";" { AsgnBlk (AsgnOp $1) $2 (Number "1") }
BlockKWPar :: { BlockKW }
: "fork" { Par }
BlockKWSeq :: { BlockKW }
: "begin" { Seq }
Unique :: { Maybe UniquePriority } Unique :: { Maybe UniquePriority }
: {- empty -} { Nothing } : {- empty -} { Nothing }
| "unique" { Just Unique } | "unique" { Just Unique }
| "unique0" { Just Unique0 } | "unique0" { Just Unique0 }
| "priority" { Just Priority } | "priority" { Just Priority }
ForInit :: { Either [Decl] [(LHS, Expr)] }
: ";" { Right [] }
| DeclTokens(";") { parseDTsAsDeclsOrAsgns $1 }
ForCond :: { Expr }
: ";" { Number "1" }
| Expr ";" { $1 }
ForStep :: { [(LHS, AsgnOp, Expr)] } ForStep :: { [(LHS, AsgnOp, Expr)] }
: {- empty -} { [] } : {- empty -} { [] }
| ForStepNonEmpty { $1 } | ForStepNonEmpty { $1 }
...@@ -996,13 +1022,13 @@ CaseKW :: { CaseKW } ...@@ -996,13 +1022,13 @@ CaseKW :: { CaseKW }
| "casex" { CaseX } | "casex" { CaseX }
| "casez" { CaseZ } | "casez" { CaseZ }
CasesWithDefault :: { ([Case], Maybe Stmt) } Cases :: { ([Case], Maybe Stmt) }
: {- empty -} { ([], Nothing) } : {- empty -} { ([], Nothing) }
| Case CasesWithDefault { ($1 : fst $2, snd $2) } | Case Cases { ($1 : fst $2, snd $2) }
| CaseDefault Cases { ($2, Just $1) } | CaseDefault CasesNoDefault { ($2, Just $1) }
Cases :: { [Case] } CasesNoDefault :: { [Case] }
: {- empty -} { [] } : {- empty -} { [] }
| Cases Case { $1 ++ [$2] } | CasesNoDefault Case { $1 ++ [$2] }
Case :: { Case } Case :: { Case }
: Exprs ":" Stmt { ($1, $3) } : Exprs ":" Stmt { ($1, $3) }
...@@ -1020,6 +1046,8 @@ Time :: { String } ...@@ -1020,6 +1046,8 @@ Time :: { String }
: time { tokenString $1 } : time { tokenString $1 }
CallArgs :: { Args } CallArgs :: { Args }
: "(" CallArgsInside ")" { $2 }
CallArgsInside :: { Args }
: {- empty -} { Args [ ] [] } : {- empty -} { Args [ ] [] }
| NamedCallArgsFollow { Args [ ] $1 } | NamedCallArgsFollow { Args [ ] $1 }
| Expr NamedCallArgs { Args [Just $1 ] $2 } | Expr NamedCallArgs { Args [Just $1 ] $2 }
...@@ -1049,8 +1077,8 @@ Expr :: { Expr } ...@@ -1049,8 +1077,8 @@ Expr :: { Expr }
: "(" Expr ")" { $2 } : "(" Expr ")" { $2 }
| String { String $1 } | String { String $1 }
| Number { Number $1 } | Number { Number $1 }
| Identifier "(" CallArgs ")" { Call (Nothing) $1 $3 } | Identifier CallArgs { Call (Nothing) $1 $2 }
| Identifier "::" Identifier "(" CallArgs ")" { Call (Just $1) $3 $5 } | Identifier "::" Identifier CallArgs { Call (Just $1) $3 $4 }
| DimsFn "(" TypeOrExpr ")" { DimsFn $1 $3 } | DimsFn "(" TypeOrExpr ")" { DimsFn $1 $3 }
| DimFn "(" TypeOrExpr ")" { DimFn $1 $3 (Number "1") } | DimFn "(" TypeOrExpr ")" { DimFn $1 $3 (Number "1") }
| DimFn "(" TypeOrExpr "," Expr ")" { DimFn $1 $3 $5 } | DimFn "(" TypeOrExpr "," Expr ")" { DimFn $1 $3 $5 }
...@@ -1156,8 +1184,8 @@ ConditionalGenerateConstruct :: { GenItem } ...@@ -1156,8 +1184,8 @@ ConditionalGenerateConstruct :: { GenItem }
LoopGenerateConstruct :: { GenItem } LoopGenerateConstruct :: { GenItem }
: "for" "(" GenvarInitialization ";" Expr ";" GenvarIteration ")" GenBlock { (uncurry $ GenFor $3 $5 $7) $9 } : "for" "(" GenvarInitialization ";" Expr ";" GenvarIteration ")" GenBlock { (uncurry $ GenFor $3 $5 $7) $9 }
GenBlock :: { (Maybe Identifier, [GenItem]) } GenBlock :: { (Identifier, [GenItem]) }
: "begin" opt(Tag) GenItems "end" opt(Tag) { (combineTags $2 $5, $3) } : "begin" StrTag GenItems "end" StrTag { (combineTags $2 $5, $3) }
GenCasesWithDefault :: { ([GenCase], Maybe GenItem) } GenCasesWithDefault :: { ([GenCase], Maybe GenItem) }
: {- empty -} { ([], Nothing) } : {- empty -} { ([], Nothing) }
...@@ -1222,7 +1250,7 @@ parseError a = case a of ...@@ -1222,7 +1250,7 @@ parseError a = case a of
genItemsToGenItem :: [GenItem] -> GenItem genItemsToGenItem :: [GenItem] -> GenItem
genItemsToGenItem [x] = x genItemsToGenItem [x] = x
genItemsToGenItem xs = GenBlock Nothing xs genItemsToGenItem xs = GenBlock "" xs
combineDeclsAndStmts :: ([Decl], [Stmt]) -> ([Decl], [Stmt]) -> ([Decl], [Stmt]) combineDeclsAndStmts :: ([Decl], [Stmt]) -> ([Decl], [Stmt]) -> ([Decl], [Stmt])
combineDeclsAndStmts (a1, b1) (a2, b2) = (a1 ++ a2, b1 ++ b2) combineDeclsAndStmts (a1, b1) (a2, b2) = (a1 ++ a2, b1 ++ b2)
...@@ -1242,13 +1270,13 @@ defaultFuncInput (Variable dir (Implicit sg rs) x a me) = ...@@ -1242,13 +1270,13 @@ defaultFuncInput (Variable dir (Implicit sg rs) x a me) =
else Implicit sg rs else Implicit sg rs
defaultFuncInput other = other defaultFuncInput other = other
combineTags :: Maybe Identifier -> Maybe Identifier -> Maybe Identifier combineTags :: Identifier -> Identifier -> Identifier
combineTags (Just a) (Just b) = combineTags a "" = a
combineTags "" b = b
combineTags a b =
if a == b if a == b
then Just a then a
else error $ "tag mismatch: " ++ show (a, b) else error $ "tag mismatch: " ++ show (a, b)
combineTags Nothing other = other
combineTags other _ = other
toLHS :: Expr -> LHS toLHS :: Expr -> LHS
toLHS expr = toLHS expr =
......
...@@ -35,7 +35,7 @@ module Language.SystemVerilog.Parser.ParseDecl ...@@ -35,7 +35,7 @@ module Language.SystemVerilog.Parser.ParseDecl
, parseDTsAsDecls , parseDTsAsDecls
, parseDTsAsDecl , parseDTsAsDecl
, parseDTsAsDeclOrAsgn , parseDTsAsDeclOrAsgn
, parseDTsAsDeclsAndAsgns , parseDTsAsDeclsOrAsgns
) where ) where
import Data.List (elemIndex, findIndex, findIndices) import Data.List (elemIndex, findIndex, findIndices)
...@@ -219,28 +219,14 @@ parseDTsAsDeclOrAsgn tokens = ...@@ -219,28 +219,14 @@ parseDTsAsDeclOrAsgn tokens =
isAsgn (DTAsgn _ _) = True isAsgn (DTAsgn _ _) = True
isAsgn _ = False isAsgn _ = False
-- [PUBLIC]: parser for mixed comma-separated declaration and assignment lists; -- [PUBLIC]: parser for comma-separated declarations or assignment lists; this
-- the main use case is for `for` loop initialization lists -- is only used for `for` loop initialization lists
parseDTsAsDeclsAndAsgns :: [DeclToken] -> [Either Decl (LHS, Expr)] parseDTsAsDeclsOrAsgns :: [DeclToken] -> Either [Decl] [(LHS, Expr)]
parseDTsAsDeclsAndAsgns [] = [] parseDTsAsDeclsOrAsgns tokens =
parseDTsAsDeclsAndAsgns tokens = forbidNonEqAsgn tokens $
if hasLeadingAsgn || tripLookahead tokens if hasLeadingAsgn || tripLookahead tokens
then then Right $ parseDTsAsAsgns tokens
let (lhsToks, l0) = break isDTAsgn tokens else Left $ parseDTsAsDecls tokens
lhs = case takeLHS lhsToks of
Nothing ->
error $ "could not parse as LHS: " ++ show lhsToks
Just l -> l
DTAsgn AsgnOpEq expr : l1 = l0
asgn = Right (lhs, expr)
in case l1 of
DTComma : remaining -> asgn : parseDTsAsDeclsAndAsgns remaining
[] -> [asgn]
_ -> error $ "bad decls and asgns tokens: " ++ show tokens
else
let (component, remaining) = parseDTsAsComponent tokens
decls = finalize component
in (map Left decls) ++ parseDTsAsDeclsAndAsgns remaining
where where
hasLeadingAsgn = hasLeadingAsgn =
-- if there is an asgn token before the next comma -- if there is an asgn token before the next comma
...@@ -248,6 +234,22 @@ parseDTsAsDeclsAndAsgns tokens = ...@@ -248,6 +234,22 @@ parseDTsAsDeclsAndAsgns tokens =
(Just a, Just b) -> a > b (Just a, Just b) -> a > b
(Nothing, Just _) -> True (Nothing, Just _) -> True
_ -> False _ -> False
-- internal parser for basic assignment lists
parseDTsAsAsgns :: [DeclToken] -> [(LHS, Expr)]
parseDTsAsAsgns tokens =
case l1 of
[] -> [asgn]
DTComma : remaining -> asgn : parseDTsAsAsgns remaining
_ -> error $ "bad assignment tokens: " ++ show tokens
where
(lhsToks, l0) = break isDTAsgn tokens
lhs = case takeLHS lhsToks of
Nothing -> error $ "could not parse as LHS: " ++ show lhsToks
Just l -> l
DTAsgn AsgnOpEq expr : l1 = l0
asgn = (lhs, expr)
isDTAsgn :: DeclToken -> Bool isDTAsgn :: DeclToken -> Bool
isDTAsgn (DTAsgn _ _) = True isDTAsgn (DTAsgn _ _) = True
isDTAsgn _ = False isDTAsgn _ = False
......
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