2019-02-25 08:36:37 +01:00
|
|
|
{- sv2v
|
|
|
|
|
- Author: Zachary Snow <zach@zachjs.com>
|
|
|
|
|
-
|
|
|
|
|
- Utilities for traversing AST transformations.
|
|
|
|
|
-}
|
|
|
|
|
|
|
|
|
|
module Convert.Traverse
|
|
|
|
|
( MapperM
|
|
|
|
|
, Mapper
|
|
|
|
|
, unmonad
|
2019-02-25 22:19:55 +01:00
|
|
|
, collectify
|
2019-02-25 08:36:37 +01:00
|
|
|
, traverseDescriptionsM
|
|
|
|
|
, traverseDescriptions
|
2019-02-25 22:19:55 +01:00
|
|
|
, collectDescriptionsM
|
2019-02-25 08:36:37 +01:00
|
|
|
, traverseModuleItemsM
|
|
|
|
|
, traverseModuleItems
|
2019-02-25 22:19:55 +01:00
|
|
|
, collectModuleItemsM
|
2019-02-25 08:36:37 +01:00
|
|
|
, traverseStmtsM
|
|
|
|
|
, traverseStmts
|
2019-02-25 22:19:55 +01:00
|
|
|
, collectStmtsM
|
|
|
|
|
, traverseStmtLHSsM
|
|
|
|
|
, traverseStmtLHSs
|
|
|
|
|
, collectStmtLHSsM
|
2019-02-28 23:12:37 +01:00
|
|
|
, traverseExprsM
|
|
|
|
|
, traverseExprs
|
|
|
|
|
, collectExprsM
|
2019-03-01 01:48:58 +01:00
|
|
|
, traverseLHSsM
|
|
|
|
|
, traverseLHSs
|
|
|
|
|
, collectLHSsM
|
2019-03-01 02:30:21 +01:00
|
|
|
, traverseDeclsM
|
|
|
|
|
, traverseDecls
|
|
|
|
|
, collectDeclsM
|
2019-03-01 04:44:31 +01:00
|
|
|
, traverseTypesM
|
|
|
|
|
, traverseTypes
|
|
|
|
|
, collectTypesM
|
2019-03-05 01:58:54 +01:00
|
|
|
, traverseGenItemsM
|
|
|
|
|
, traverseGenItems
|
|
|
|
|
, collectGenItemsM
|
2019-03-06 06:51:09 +01:00
|
|
|
, traverseAsgnsM
|
|
|
|
|
, traverseAsgns
|
|
|
|
|
, collectAsgnsM
|
2019-03-07 02:30:47 +01:00
|
|
|
, traverseNestedModuleItemsM
|
|
|
|
|
, traverseNestedModuleItems
|
|
|
|
|
, collectNestedModuleItemsM
|
2019-03-06 06:51:09 +01:00
|
|
|
, traverseNestedStmts
|
2019-02-25 08:36:37 +01:00
|
|
|
) where
|
|
|
|
|
|
2019-02-28 23:12:37 +01:00
|
|
|
import Data.Maybe (fromJust)
|
2019-02-25 08:36:37 +01:00
|
|
|
import Control.Monad.State
|
|
|
|
|
import Language.SystemVerilog.AST
|
|
|
|
|
|
2019-02-25 22:19:55 +01:00
|
|
|
type MapperM m t = t -> m t
|
2019-02-25 08:36:37 +01:00
|
|
|
type Mapper t = t -> t
|
2019-02-25 22:19:55 +01:00
|
|
|
type CollectorM m t = t -> m ()
|
2019-02-25 08:36:37 +01:00
|
|
|
|
2019-02-25 22:19:55 +01:00
|
|
|
unmonad :: (MapperM (State ()) a -> MapperM (State ()) b) -> Mapper a -> Mapper b
|
2019-02-25 08:36:37 +01:00
|
|
|
unmonad traverser mapper thing =
|
|
|
|
|
evalState (traverser (return . mapper) thing) ()
|
|
|
|
|
|
2019-02-25 22:19:55 +01:00
|
|
|
collectify :: Monad m => (MapperM m a -> MapperM m b) -> CollectorM m a -> CollectorM m b
|
|
|
|
|
collectify traverser collector thing =
|
|
|
|
|
traverser mapper thing >>= \_ -> return ()
|
|
|
|
|
where mapper x = collector x >>= \() -> return x
|
|
|
|
|
|
|
|
|
|
traverseDescriptionsM :: Monad m => MapperM m Description -> MapperM m AST
|
2019-02-25 08:36:37 +01:00
|
|
|
traverseDescriptionsM mapper descriptions =
|
|
|
|
|
mapM mapper descriptions
|
|
|
|
|
|
|
|
|
|
traverseDescriptions :: Mapper Description -> Mapper AST
|
|
|
|
|
traverseDescriptions = unmonad traverseDescriptionsM
|
2019-02-25 22:19:55 +01:00
|
|
|
collectDescriptionsM :: Monad m => CollectorM m Description -> CollectorM m AST
|
|
|
|
|
collectDescriptionsM = collectify traverseDescriptionsM
|
2019-02-25 08:36:37 +01:00
|
|
|
|
2019-02-25 10:03:03 +01:00
|
|
|
maybeDo :: Monad m => (a -> m b) -> Maybe a -> m (Maybe b)
|
|
|
|
|
maybeDo _ Nothing = return Nothing
|
|
|
|
|
maybeDo fun (Just val) = fun val >>= return . Just
|
|
|
|
|
|
2019-02-25 22:19:55 +01:00
|
|
|
traverseModuleItemsM :: Monad m => MapperM m ModuleItem -> MapperM m Description
|
2019-03-04 08:58:00 +01:00
|
|
|
traverseModuleItemsM mapper (Part kw name ports items) =
|
|
|
|
|
mapM fullMapper items >>= return . Part kw name ports
|
2019-02-25 08:36:37 +01:00
|
|
|
where
|
|
|
|
|
fullMapper (Generate genItems) =
|
2019-03-05 01:58:54 +01:00
|
|
|
mapM fullGenItemMapper genItems >>= mapper . Generate
|
2019-02-25 08:36:37 +01:00
|
|
|
fullMapper other = mapper other
|
2019-03-05 01:58:54 +01:00
|
|
|
fullGenItemMapper = traverseNestedGenItemsM genItemMapper
|
2019-02-28 06:16:53 +01:00
|
|
|
genItemMapper (GenModuleItem moduleItem) = do
|
|
|
|
|
moduleItem' <- fullMapper moduleItem
|
|
|
|
|
return $ case moduleItem' of
|
|
|
|
|
Generate subItems -> GenBlock Nothing subItems
|
|
|
|
|
_ -> GenModuleItem moduleItem'
|
2019-03-05 01:58:54 +01:00
|
|
|
genItemMapper other = return other
|
2019-03-07 19:19:31 +01:00
|
|
|
traverseModuleItemsM mapper (PackageItem packageItem) = do
|
|
|
|
|
let item = MIPackageItem packageItem
|
|
|
|
|
Part Module "DNE" [] [item'] <-
|
|
|
|
|
traverseModuleItemsM mapper (Part Module "DNE" [] [item])
|
|
|
|
|
return $ case item' of
|
|
|
|
|
MIPackageItem packageItem' -> PackageItem packageItem'
|
|
|
|
|
other -> error $ "encountered bad package module item: " ++ show other
|
2019-02-25 08:36:37 +01:00
|
|
|
|
|
|
|
|
traverseModuleItems :: Mapper ModuleItem -> Mapper Description
|
|
|
|
|
traverseModuleItems = unmonad traverseModuleItemsM
|
2019-02-25 22:19:55 +01:00
|
|
|
collectModuleItemsM :: Monad m => CollectorM m ModuleItem -> CollectorM m Description
|
|
|
|
|
collectModuleItemsM = collectify traverseModuleItemsM
|
2019-02-25 08:36:37 +01:00
|
|
|
|
2019-02-25 22:19:55 +01:00
|
|
|
traverseStmtsM :: Monad m => MapperM m Stmt -> MapperM m ModuleItem
|
2019-02-25 08:36:37 +01:00
|
|
|
traverseStmtsM mapper = moduleItemMapper
|
|
|
|
|
where
|
|
|
|
|
moduleItemMapper (AlwaysC kw stmt) =
|
|
|
|
|
fullMapper stmt >>= return . AlwaysC kw
|
2019-03-07 19:19:31 +01:00
|
|
|
moduleItemMapper (MIPackageItem (Function lifetime ret name decls stmts)) = do
|
2019-03-04 20:25:38 +01:00
|
|
|
stmts' <- mapM fullMapper stmts
|
2019-03-07 19:19:31 +01:00
|
|
|
return $ MIPackageItem $ Function lifetime ret name decls stmts'
|
2019-03-07 19:58:20 +01:00
|
|
|
moduleItemMapper (MIPackageItem (Task lifetime name decls stmts)) = do
|
|
|
|
|
stmts' <- mapM fullMapper stmts
|
|
|
|
|
return $ MIPackageItem $ Task lifetime name decls stmts'
|
2019-03-05 02:58:09 +01:00
|
|
|
moduleItemMapper (Initial stmt) =
|
|
|
|
|
fullMapper stmt >>= return . Initial
|
2019-02-25 08:36:37 +01:00
|
|
|
moduleItemMapper other = return $ other
|
2019-02-25 22:19:55 +01:00
|
|
|
fullMapper = traverseNestedStmtsM mapper
|
|
|
|
|
|
|
|
|
|
traverseStmts :: Mapper Stmt -> Mapper ModuleItem
|
|
|
|
|
traverseStmts = unmonad traverseStmtsM
|
|
|
|
|
collectStmtsM :: Monad m => CollectorM m Stmt -> CollectorM m ModuleItem
|
|
|
|
|
collectStmtsM = collectify traverseStmtsM
|
|
|
|
|
|
|
|
|
|
-- private utility for turning a thing which maps over a single lever of
|
|
|
|
|
-- statements into one that maps over the nested statements first, then the
|
|
|
|
|
-- higher levels up
|
|
|
|
|
traverseNestedStmtsM :: Monad m => MapperM m Stmt -> MapperM m Stmt
|
|
|
|
|
traverseNestedStmtsM mapper = fullMapper
|
|
|
|
|
where
|
2019-02-25 08:36:37 +01:00
|
|
|
fullMapper stmt = mapper stmt >>= cs
|
|
|
|
|
cs (Block decls stmts) = mapM fullMapper stmts >>= return . Block decls
|
2019-03-05 00:25:14 +01:00
|
|
|
cs (Case u kw expr cases def) = do
|
2019-02-25 08:36:37 +01:00
|
|
|
caseStmts <- mapM fullMapper $ map snd cases
|
|
|
|
|
let cases' = zip (map fst cases) caseStmts
|
2019-02-25 10:03:03 +01:00
|
|
|
def' <- maybeDo fullMapper def
|
2019-03-05 00:25:14 +01:00
|
|
|
return $ Case u kw expr cases' def'
|
2019-02-25 08:36:37 +01:00
|
|
|
cs (AsgnBlk lhs expr) = return $ AsgnBlk lhs expr
|
|
|
|
|
cs (Asgn lhs expr) = return $ Asgn lhs expr
|
|
|
|
|
cs (For a b c stmt) = fullMapper stmt >>= return . For a b c
|
2019-03-05 03:32:30 +01:00
|
|
|
cs (While e stmt) = fullMapper stmt >>= return . While e
|
|
|
|
|
cs (RepeatL e stmt) = fullMapper stmt >>= return . RepeatL e
|
|
|
|
|
cs (DoWhile e stmt) = fullMapper stmt >>= return . DoWhile e
|
|
|
|
|
cs (Forever stmt) = fullMapper stmt >>= return . Forever
|
2019-02-25 08:36:37 +01:00
|
|
|
cs (If e s1 s2) = do
|
|
|
|
|
s1' <- fullMapper s1
|
|
|
|
|
s2' <- fullMapper s2
|
|
|
|
|
return $ If e s1' s2'
|
2019-03-05 02:58:09 +01:00
|
|
|
cs (Timing event stmt) = fullMapper stmt >>= return . Timing event
|
2019-03-04 20:25:38 +01:00
|
|
|
cs (Return expr) = return $ Return expr
|
2019-03-05 02:58:09 +01:00
|
|
|
cs (Subroutine f exprs) = return $ Subroutine f exprs
|
2019-02-25 08:36:37 +01:00
|
|
|
cs (Null) = return Null
|
|
|
|
|
|
2019-02-25 22:19:55 +01:00
|
|
|
traverseStmtLHSsM :: Monad m => MapperM m LHS -> MapperM m Stmt
|
|
|
|
|
traverseStmtLHSsM mapper = traverseNestedStmtsM stmtMapper
|
|
|
|
|
where
|
2019-03-04 21:16:53 +01:00
|
|
|
fullMapper = traverseNestedLHSsM mapper
|
2019-03-07 03:55:27 +01:00
|
|
|
stmtMapper (Timing (Event sense) stmt) = do
|
|
|
|
|
sense' <- senseMapper sense
|
|
|
|
|
return $ Timing (Event sense') stmt
|
2019-03-04 21:16:53 +01:00
|
|
|
stmtMapper (AsgnBlk lhs expr) = fullMapper lhs >>= \lhs' -> return $ AsgnBlk lhs' expr
|
|
|
|
|
stmtMapper (Asgn lhs expr) = fullMapper lhs >>= \lhs' -> return $ Asgn lhs' expr
|
2019-02-25 22:19:55 +01:00
|
|
|
stmtMapper other = return other
|
2019-03-07 03:55:27 +01:00
|
|
|
senseMapper (Sense lhs) = fullMapper lhs >>= return . Sense
|
|
|
|
|
senseMapper (SensePosedge lhs) = fullMapper lhs >>= return . SensePosedge
|
|
|
|
|
senseMapper (SenseNegedge lhs) = fullMapper lhs >>= return . SenseNegedge
|
|
|
|
|
senseMapper (SenseOr s1 s2) = do
|
|
|
|
|
s1' <- senseMapper s1
|
|
|
|
|
s2' <- senseMapper s2
|
|
|
|
|
return $ SenseOr s1' s2'
|
|
|
|
|
senseMapper (SenseStar ) = return SenseStar
|
2019-02-25 22:19:55 +01:00
|
|
|
|
|
|
|
|
traverseStmtLHSs :: Mapper LHS -> Mapper Stmt
|
|
|
|
|
traverseStmtLHSs = unmonad traverseStmtLHSsM
|
|
|
|
|
collectStmtLHSsM :: Monad m => CollectorM m LHS -> CollectorM m Stmt
|
|
|
|
|
collectStmtLHSsM = collectify traverseStmtLHSsM
|
2019-02-28 23:12:37 +01:00
|
|
|
|
|
|
|
|
traverseNestedExprsM :: Monad m => MapperM m Expr -> MapperM m Expr
|
|
|
|
|
traverseNestedExprsM mapper = exprMapper
|
|
|
|
|
where
|
|
|
|
|
exprMapper e = mapper e >>= em
|
|
|
|
|
em (String s) = return $ String s
|
|
|
|
|
em (Number s) = return $ Number s
|
|
|
|
|
em (ConstBool b) = return $ ConstBool b
|
|
|
|
|
em (Ident i) = return $ Ident i
|
2019-03-04 21:46:12 +01:00
|
|
|
em (Range e (e1, e2)) = do
|
|
|
|
|
e' <- exprMapper e
|
|
|
|
|
e1' <- exprMapper e1
|
|
|
|
|
e2' <- exprMapper e2
|
|
|
|
|
return $ Range e' (e1', e2')
|
|
|
|
|
em (Bit e1 e2) = do
|
2019-02-28 23:12:37 +01:00
|
|
|
e1' <- exprMapper e1
|
|
|
|
|
e2' <- exprMapper e2
|
2019-03-04 21:46:12 +01:00
|
|
|
return $ Bit e1' e2'
|
2019-02-28 23:12:37 +01:00
|
|
|
em (Repeat e l) = do
|
|
|
|
|
e' <- exprMapper e
|
|
|
|
|
l' <- mapM exprMapper l
|
|
|
|
|
return $ Repeat e' l'
|
|
|
|
|
em (Concat l) =
|
|
|
|
|
mapM exprMapper l >>= return . Concat
|
|
|
|
|
em (Call f l) =
|
|
|
|
|
mapM exprMapper l >>= return . Call f
|
|
|
|
|
em (UniOp o e) =
|
|
|
|
|
exprMapper e >>= return . UniOp o
|
|
|
|
|
em (BinOp o e1 e2) = do
|
|
|
|
|
e1' <- exprMapper e1
|
|
|
|
|
e2' <- exprMapper e2
|
|
|
|
|
return $ BinOp o e1' e2'
|
|
|
|
|
em (Mux e1 e2 e3) = do
|
|
|
|
|
e1' <- exprMapper e1
|
|
|
|
|
e2' <- exprMapper e2
|
|
|
|
|
e3' <- exprMapper e3
|
|
|
|
|
return $ Mux e1' e2' e3'
|
|
|
|
|
em (Cast t e) =
|
|
|
|
|
exprMapper e >>= return . Cast t
|
2019-03-04 21:46:12 +01:00
|
|
|
em (Access e x) =
|
|
|
|
|
exprMapper e >>= \e' -> return $ Access e' x
|
|
|
|
|
em (Pattern l) = do
|
2019-03-02 02:26:44 +01:00
|
|
|
let names = map fst l
|
|
|
|
|
exprs <- mapM exprMapper $ map snd l
|
2019-03-04 21:46:12 +01:00
|
|
|
return $ Pattern $ zip names exprs
|
2019-02-28 23:12:37 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
traverseExprsM :: Monad m => MapperM m Expr -> MapperM m ModuleItem
|
|
|
|
|
traverseExprsM mapper = moduleItemMapper
|
|
|
|
|
where
|
|
|
|
|
|
|
|
|
|
rangeMapper (a, b) = do
|
|
|
|
|
a' <- exprMapper a
|
|
|
|
|
b' <- exprMapper b
|
|
|
|
|
return (a', b')
|
|
|
|
|
|
|
|
|
|
maybeExprMapper Nothing = return Nothing
|
|
|
|
|
maybeExprMapper (Just e) =
|
|
|
|
|
exprMapper e >>= return . Just
|
|
|
|
|
|
|
|
|
|
declMapper (Parameter t x e) =
|
|
|
|
|
exprMapper e >>= return . Parameter t x
|
|
|
|
|
declMapper (Localparam t x e) =
|
|
|
|
|
exprMapper e >>= return . Localparam t x
|
|
|
|
|
declMapper (Variable d t x a me) = do
|
|
|
|
|
a' <- mapM rangeMapper a
|
|
|
|
|
me' <- maybeExprMapper me
|
|
|
|
|
return $ Variable d t x a' me'
|
|
|
|
|
|
|
|
|
|
exprMapper = traverseNestedExprsM mapper
|
|
|
|
|
|
|
|
|
|
caseMapper (exprs, stmt) = do
|
|
|
|
|
exprs' <- mapM exprMapper exprs
|
|
|
|
|
return (exprs', stmt)
|
|
|
|
|
stmtMapper = traverseNestedStmtsM flatStmtMapper
|
|
|
|
|
flatStmtMapper (Block header stmts) = do
|
|
|
|
|
if header == Nothing
|
|
|
|
|
then return $ Block Nothing stmts
|
|
|
|
|
else do
|
|
|
|
|
let Just (name, decls) = header
|
|
|
|
|
decls' <- mapM declMapper decls
|
|
|
|
|
return $ Block (Just (name, decls')) stmts
|
2019-03-05 00:25:14 +01:00
|
|
|
flatStmtMapper (Case u kw e cases def) = do
|
2019-02-28 23:12:37 +01:00
|
|
|
e' <- exprMapper e
|
|
|
|
|
cases' <- mapM caseMapper cases
|
2019-03-05 00:25:14 +01:00
|
|
|
return $ Case u kw e' cases' def
|
2019-02-28 23:12:37 +01:00
|
|
|
flatStmtMapper (AsgnBlk lhs expr) =
|
|
|
|
|
exprMapper expr >>= return . AsgnBlk lhs
|
|
|
|
|
flatStmtMapper (Asgn lhs expr) =
|
|
|
|
|
exprMapper expr >>= return . Asgn lhs
|
|
|
|
|
flatStmtMapper (For (x1, e1) cc (x2, e2) stmt) = do
|
|
|
|
|
e1' <- exprMapper e1
|
|
|
|
|
e2' <- exprMapper e2
|
|
|
|
|
cc' <- exprMapper cc
|
|
|
|
|
return $ For (x1, e1') cc' (x2, e2') stmt
|
2019-03-05 03:32:30 +01:00
|
|
|
flatStmtMapper (While e stmt) =
|
|
|
|
|
exprMapper e >>= \e' -> return $ While e' stmt
|
|
|
|
|
flatStmtMapper (RepeatL e stmt) =
|
|
|
|
|
exprMapper e >>= \e' -> return $ RepeatL e' stmt
|
|
|
|
|
flatStmtMapper (DoWhile e stmt) =
|
|
|
|
|
exprMapper e >>= \e' -> return $ DoWhile e' stmt
|
|
|
|
|
flatStmtMapper (Forever stmt) = return $ Forever stmt
|
2019-02-28 23:12:37 +01:00
|
|
|
flatStmtMapper (If cc s1 s2) =
|
|
|
|
|
exprMapper cc >>= \cc' -> return $ If cc' s1 s2
|
2019-03-05 02:58:09 +01:00
|
|
|
flatStmtMapper (Timing event stmt) = return $ Timing event stmt
|
|
|
|
|
flatStmtMapper (Subroutine f exprs) =
|
|
|
|
|
mapM exprMapper exprs >>= return . Subroutine f
|
2019-03-04 20:25:38 +01:00
|
|
|
flatStmtMapper (Return expr) =
|
|
|
|
|
exprMapper expr >>= return . Return
|
2019-02-28 23:12:37 +01:00
|
|
|
flatStmtMapper (Null) = return Null
|
|
|
|
|
|
|
|
|
|
portBindingMapper (p, me) =
|
|
|
|
|
maybeExprMapper me >>= \me' -> return (p, me')
|
|
|
|
|
|
|
|
|
|
moduleItemMapper (MIDecl decl) =
|
|
|
|
|
declMapper decl >>= return . MIDecl
|
|
|
|
|
moduleItemMapper (Assign lhs expr) =
|
|
|
|
|
exprMapper expr >>= return . Assign lhs
|
|
|
|
|
moduleItemMapper (AlwaysC kw stmt) =
|
|
|
|
|
stmtMapper stmt >>= return . AlwaysC kw
|
2019-03-05 02:58:09 +01:00
|
|
|
moduleItemMapper (Initial stmt) =
|
|
|
|
|
stmtMapper stmt >>= return . Initial
|
2019-03-07 19:19:31 +01:00
|
|
|
moduleItemMapper (MIPackageItem (Function lifetime ret f decls stmts)) = do
|
2019-02-28 23:12:37 +01:00
|
|
|
decls' <- mapM declMapper decls
|
2019-03-04 20:25:38 +01:00
|
|
|
stmts' <- mapM stmtMapper stmts
|
2019-03-07 19:19:31 +01:00
|
|
|
return $ MIPackageItem $ Function lifetime ret f decls' stmts'
|
2019-03-07 19:58:20 +01:00
|
|
|
moduleItemMapper (MIPackageItem (Task lifetime f decls stmts)) = do
|
|
|
|
|
decls' <- mapM declMapper decls
|
|
|
|
|
stmts' <- mapM stmtMapper stmts
|
|
|
|
|
return $ MIPackageItem $ Task lifetime f decls' stmts'
|
2019-02-28 23:12:37 +01:00
|
|
|
moduleItemMapper (Instance m params x ml) = do
|
|
|
|
|
if ml == Nothing
|
|
|
|
|
then return $ Instance m params x Nothing
|
|
|
|
|
else do
|
|
|
|
|
l <- mapM portBindingMapper (fromJust ml)
|
|
|
|
|
return $ Instance m params x (Just l)
|
2019-03-07 02:30:47 +01:00
|
|
|
moduleItemMapper (Modport x l) =
|
|
|
|
|
mapM modportDeclMapper l >>= return . Modport x
|
2019-02-28 23:12:37 +01:00
|
|
|
moduleItemMapper (Genvar x) = return $ Genvar x
|
|
|
|
|
moduleItemMapper (Generate x) = return $ Generate x
|
2019-03-07 19:19:31 +01:00
|
|
|
moduleItemMapper (MIPackageItem (Typedef t x)) =
|
|
|
|
|
return $ MIPackageItem $ Typedef t x
|
|
|
|
|
moduleItemMapper (MIPackageItem (Comment c)) =
|
|
|
|
|
return $ MIPackageItem $ Comment c
|
2019-03-07 02:30:47 +01:00
|
|
|
|
|
|
|
|
modportDeclMapper (dir, ident, Just e) = do
|
|
|
|
|
e' <- exprMapper e
|
|
|
|
|
return (dir, ident, Just e')
|
|
|
|
|
modportDeclMapper other = return other
|
2019-02-28 23:12:37 +01:00
|
|
|
|
|
|
|
|
traverseExprs :: Mapper Expr -> Mapper ModuleItem
|
|
|
|
|
traverseExprs = unmonad traverseExprsM
|
|
|
|
|
collectExprsM :: Monad m => CollectorM m Expr -> CollectorM m ModuleItem
|
|
|
|
|
collectExprsM = collectify traverseExprsM
|
2019-03-01 01:48:58 +01:00
|
|
|
|
|
|
|
|
traverseLHSsM :: Monad m => MapperM m LHS -> MapperM m ModuleItem
|
|
|
|
|
traverseLHSsM mapper item =
|
|
|
|
|
traverseStmtsM (traverseStmtLHSsM mapper) item >>= traverseModuleItemLHSsM
|
|
|
|
|
where
|
|
|
|
|
traverseModuleItemLHSsM (Assign lhs expr) = do
|
2019-03-04 21:16:53 +01:00
|
|
|
lhs' <- traverseNestedLHSsM mapper lhs
|
2019-03-01 01:48:58 +01:00
|
|
|
return $ Assign lhs' expr
|
|
|
|
|
traverseModuleItemLHSsM other = return other
|
|
|
|
|
|
|
|
|
|
traverseLHSs :: Mapper LHS -> Mapper ModuleItem
|
|
|
|
|
traverseLHSs = unmonad traverseLHSsM
|
|
|
|
|
collectLHSsM :: Monad m => CollectorM m LHS -> CollectorM m ModuleItem
|
|
|
|
|
collectLHSsM = collectify traverseLHSsM
|
2019-03-01 02:30:21 +01:00
|
|
|
|
2019-03-04 21:16:53 +01:00
|
|
|
traverseNestedLHSsM :: Monad m => MapperM m LHS -> MapperM m LHS
|
|
|
|
|
traverseNestedLHSsM mapper = fullMapper
|
|
|
|
|
where
|
|
|
|
|
fullMapper lhs = tl lhs >>= mapper
|
|
|
|
|
tl (LHSIdent x ) = return $ LHSIdent x
|
|
|
|
|
tl (LHSBit l e ) = fullMapper l >>= \l' -> return $ LHSBit l' e
|
|
|
|
|
tl (LHSRange l r ) = fullMapper l >>= \l' -> return $ LHSRange l' r
|
|
|
|
|
tl (LHSDot l x ) = fullMapper l >>= \l' -> return $ LHSDot l' x
|
|
|
|
|
tl (LHSConcat lhss) = mapM fullMapper lhss >>= return . LHSConcat
|
|
|
|
|
|
2019-03-01 02:30:21 +01:00
|
|
|
traverseDeclsM :: Monad m => MapperM m Decl -> MapperM m ModuleItem
|
|
|
|
|
traverseDeclsM mapper item = do
|
|
|
|
|
item' <- miMapperA item
|
|
|
|
|
traverseStmtsM miMapperB item'
|
|
|
|
|
where
|
|
|
|
|
miMapperA (MIDecl decl) =
|
|
|
|
|
mapper decl >>= return . MIDecl
|
2019-03-07 19:19:31 +01:00
|
|
|
miMapperA (MIPackageItem (Function l t x decls s)) = do
|
2019-03-01 02:30:21 +01:00
|
|
|
decls' <- mapM mapper decls
|
2019-03-07 19:19:31 +01:00
|
|
|
return $ MIPackageItem $ Function l t x decls' s
|
2019-03-07 19:58:20 +01:00
|
|
|
miMapperA (MIPackageItem (Task l x decls s)) = do
|
|
|
|
|
decls' <- mapM mapper decls
|
|
|
|
|
return $ MIPackageItem $ Task l x decls' s
|
2019-03-01 02:30:21 +01:00
|
|
|
miMapperA other = return other
|
|
|
|
|
miMapperB (Block (Just (name, decls)) stmts) = do
|
|
|
|
|
decls' <- mapM mapper decls
|
|
|
|
|
return $ Block (Just (name, decls')) stmts
|
|
|
|
|
miMapperB other = return other
|
|
|
|
|
|
|
|
|
|
traverseDecls :: Mapper Decl -> Mapper ModuleItem
|
|
|
|
|
traverseDecls = unmonad traverseDeclsM
|
|
|
|
|
collectDeclsM :: Monad m => CollectorM m Decl -> CollectorM m ModuleItem
|
|
|
|
|
collectDeclsM = collectify traverseDeclsM
|
2019-03-01 04:44:31 +01:00
|
|
|
|
|
|
|
|
traverseTypesM :: Monad m => MapperM m Type -> MapperM m ModuleItem
|
|
|
|
|
traverseTypesM mapper item =
|
2019-03-04 20:25:38 +01:00
|
|
|
miMapper item >>= traverseDeclsM declMapper >>= traverseExprsM exprMapper
|
2019-03-01 04:44:31 +01:00
|
|
|
where
|
2019-03-06 06:51:09 +01:00
|
|
|
fullMapper t = tm t >>= mapper
|
|
|
|
|
tm (Reg r) = return $ Reg r
|
|
|
|
|
tm (Wire r) = return $ Wire r
|
|
|
|
|
tm (Logic r) = return $ Logic r
|
|
|
|
|
tm (Alias x r) = return $ Alias x r
|
|
|
|
|
tm (Implicit r) = return $ Implicit r
|
|
|
|
|
tm (IntegerT ) = return $ IntegerT
|
|
|
|
|
tm (InterfaceT x my r) = return $ InterfaceT x my r
|
|
|
|
|
tm (Enum Nothing vals r) =
|
|
|
|
|
return $ Enum Nothing vals r
|
|
|
|
|
tm (Enum (Just t) vals r) = do
|
|
|
|
|
t' <- fullMapper t
|
|
|
|
|
return $ Enum (Just t') vals r
|
|
|
|
|
tm (Struct p fields r) = do
|
|
|
|
|
types <- mapM fullMapper $ map fst fields
|
|
|
|
|
let idents = map snd fields
|
|
|
|
|
return $ Struct p (zip types idents) r
|
2019-03-07 06:59:02 +01:00
|
|
|
exprMapper (Cast t e) =
|
|
|
|
|
fullMapper t >>= \t' -> return $ Cast t' e
|
2019-03-01 04:44:31 +01:00
|
|
|
exprMapper other = return other
|
|
|
|
|
declMapper (Parameter t x e) =
|
2019-03-06 06:51:09 +01:00
|
|
|
fullMapper t >>= \t' -> return $ Parameter t' x e
|
2019-03-01 04:44:31 +01:00
|
|
|
declMapper (Localparam t x e) =
|
2019-03-06 06:51:09 +01:00
|
|
|
fullMapper t >>= \t' -> return $ Localparam t' x e
|
2019-03-01 04:44:31 +01:00
|
|
|
declMapper (Variable d t x a me) =
|
2019-03-06 06:51:09 +01:00
|
|
|
fullMapper t >>= \t' -> return $ Variable d t' x a me
|
2019-03-07 19:19:31 +01:00
|
|
|
miMapper (MIPackageItem (Function l t x d s)) =
|
|
|
|
|
fullMapper t >>= \t' -> return $ MIPackageItem $ Function l t' x d s
|
2019-03-07 19:58:20 +01:00
|
|
|
miMapper (MIPackageItem (other @ (Task _ _ _ _))) =
|
|
|
|
|
return $ MIPackageItem other
|
2019-03-04 20:25:38 +01:00
|
|
|
miMapper other = return other
|
2019-03-01 04:44:31 +01:00
|
|
|
|
|
|
|
|
traverseTypes :: Mapper Type -> Mapper ModuleItem
|
|
|
|
|
traverseTypes = unmonad traverseTypesM
|
|
|
|
|
collectTypesM :: Monad m => CollectorM m Type -> CollectorM m ModuleItem
|
|
|
|
|
collectTypesM = collectify traverseTypesM
|
2019-03-05 01:58:54 +01:00
|
|
|
|
|
|
|
|
traverseGenItemsM :: Monad m => MapperM m GenItem -> MapperM m ModuleItem
|
|
|
|
|
traverseGenItemsM mapper = moduleItemMapper
|
|
|
|
|
where
|
|
|
|
|
fullMapper = traverseNestedGenItemsM mapper
|
|
|
|
|
moduleItemMapper (Generate genItems) =
|
|
|
|
|
mapM fullMapper genItems >>= return . Generate
|
|
|
|
|
moduleItemMapper other = return other
|
|
|
|
|
|
|
|
|
|
traverseGenItems :: Mapper GenItem -> Mapper ModuleItem
|
|
|
|
|
traverseGenItems = unmonad traverseGenItemsM
|
|
|
|
|
collectGenItemsM :: Monad m => CollectorM m GenItem -> CollectorM m ModuleItem
|
|
|
|
|
collectGenItemsM = collectify traverseGenItemsM
|
|
|
|
|
|
|
|
|
|
-- traverses all GenItems within a given GenItem, but doesn't inspect within
|
|
|
|
|
-- GenModuleItems
|
|
|
|
|
traverseNestedGenItemsM :: Monad m => MapperM m GenItem -> MapperM m GenItem
|
|
|
|
|
traverseNestedGenItemsM mapper = fullMapper
|
|
|
|
|
where
|
|
|
|
|
fullMapper genItem = gim genItem >>= mapper
|
|
|
|
|
gim (GenBlock x subItems) =
|
|
|
|
|
mapM fullMapper subItems >>= return . GenBlock x
|
|
|
|
|
gim (GenFor a b c d subItems) =
|
|
|
|
|
mapM fullMapper subItems >>= return . GenFor a b c d
|
|
|
|
|
gim (GenIf e i1 i2) = do
|
|
|
|
|
i1' <- fullMapper i1
|
|
|
|
|
i2' <- fullMapper i2
|
|
|
|
|
return $ GenIf e i1' i2'
|
|
|
|
|
gim (GenCase e cases def) = do
|
|
|
|
|
caseItems <- mapM (fullMapper . snd) cases
|
|
|
|
|
let cases' = zip (map fst cases) caseItems
|
|
|
|
|
def' <- maybeDo fullMapper def
|
|
|
|
|
return $ GenCase e cases' def'
|
|
|
|
|
gim (GenModuleItem moduleItem) =
|
|
|
|
|
return $ GenModuleItem moduleItem
|
|
|
|
|
gim (GenNull) = return GenNull
|
2019-03-06 06:51:09 +01:00
|
|
|
|
|
|
|
|
traverseAsgnsM :: Monad m => MapperM m (LHS, Expr) -> MapperM m ModuleItem
|
|
|
|
|
traverseAsgnsM mapper = moduleItemMapper
|
|
|
|
|
where
|
|
|
|
|
moduleItemMapper item = miMapperA item >>= miMapperB
|
|
|
|
|
|
|
|
|
|
miMapperA (Assign lhs expr) = do
|
|
|
|
|
(lhs', expr') <- mapper (lhs, expr)
|
|
|
|
|
return $ Assign lhs' expr'
|
|
|
|
|
miMapperA other = return other
|
|
|
|
|
|
|
|
|
|
miMapperB = traverseStmtsM stmtMapper
|
|
|
|
|
stmtMapper (AsgnBlk lhs expr) = do
|
|
|
|
|
(lhs', expr') <- mapper (lhs, expr)
|
|
|
|
|
return $ AsgnBlk lhs' expr'
|
|
|
|
|
stmtMapper (Asgn lhs expr) = do
|
|
|
|
|
(lhs', expr') <- mapper (lhs, expr)
|
|
|
|
|
return $ Asgn lhs' expr'
|
|
|
|
|
stmtMapper other = return other
|
|
|
|
|
|
|
|
|
|
traverseAsgns :: Mapper (LHS, Expr) -> Mapper ModuleItem
|
|
|
|
|
traverseAsgns = unmonad traverseAsgnsM
|
|
|
|
|
collectAsgnsM :: Monad m => CollectorM m (LHS, Expr) -> CollectorM m ModuleItem
|
|
|
|
|
collectAsgnsM = collectify traverseAsgnsM
|
|
|
|
|
|
2019-03-07 02:30:47 +01:00
|
|
|
traverseNestedModuleItemsM :: Monad m => MapperM m ModuleItem -> MapperM m ModuleItem
|
|
|
|
|
traverseNestedModuleItemsM mapper item = do
|
|
|
|
|
Part Module "DNE" [] [item'] <-
|
|
|
|
|
traverseModuleItemsM mapper (Part Module "DNE" [] [item])
|
|
|
|
|
return item'
|
|
|
|
|
|
|
|
|
|
traverseNestedModuleItems :: Mapper ModuleItem -> Mapper ModuleItem
|
|
|
|
|
traverseNestedModuleItems = unmonad traverseNestedModuleItemsM
|
|
|
|
|
collectNestedModuleItemsM :: Monad m => CollectorM m ModuleItem -> CollectorM m ModuleItem
|
|
|
|
|
collectNestedModuleItemsM = collectify traverseNestedModuleItemsM
|
|
|
|
|
|
2019-03-06 06:51:09 +01:00
|
|
|
traverseNestedStmts :: Mapper Stmt -> Mapper Stmt
|
|
|
|
|
traverseNestedStmts = unmonad traverseNestedStmtsM
|