sv2v/src/Convert/Typedef.hs

117 lines
4.9 KiB
Haskell
Raw Normal View History

2019-02-18 09:59:17 +01:00
{- sv2v
- Author: Zachary Snow <zach@zachjs.com>
-
- Conversion for `typedef`
-
2019-04-23 06:23:32 +02:00
- Aliased types can appear in all data declarations, including modules, blocks,
- and function parameters. They are also found in type cast expressions.
2019-02-18 09:59:17 +01:00
-}
module Convert.Typedef (convert) where
import Control.Monad.Writer
2019-02-18 09:59:17 +01:00
import qualified Data.Map as Map
import Convert.Traverse
2019-02-18 09:59:17 +01:00
import Language.SystemVerilog.AST
type Types = Map.Map Identifier Type
convert :: [AST] -> [AST]
2020-06-12 02:37:53 +02:00
convert = map $ traverseDescriptions convertDescription
2019-02-18 09:59:17 +01:00
2020-06-12 02:37:53 +02:00
convertDescription :: Description -> Description
convertDescription (description @ Part{}) =
traverseModuleItems (convertTypedef types) description'
where
description' =
traverseModuleItems (traverseGenItems convertGenItem) description
2020-06-12 02:37:53 +02:00
types = execWriter $ collectModuleItemsM collectTypedefM description'
convertDescription other = other
convertTypedef :: Types -> ModuleItem -> ModuleItem
convertTypedef types =
removeTypedef .
convertModuleItem .
(traverseExprs $ traverseNestedExprs $ convertExpr) .
(traverseTypes $ resolveType types)
where
removeTypedef :: ModuleItem -> ModuleItem
removeTypedef (MIPackageItem (Typedef _ x)) =
MIPackageItem $ Decl $ CommentDecl $ "removed typedef: " ++ x
removeTypedef other = other
2019-09-11 17:58:03 +02:00
convertTypeOrExpr :: TypeOrExpr -> TypeOrExpr
2020-01-12 02:35:51 +01:00
convertTypeOrExpr (Left (TypeOf (Ident x))) =
if Map.member x types
then Left $ resolveType types (Alias Nothing x [])
else Left $ TypeOf (Ident x)
2019-09-11 17:58:03 +02:00
convertTypeOrExpr (Right (Ident x)) =
if Map.member x types
2019-09-11 17:58:03 +02:00
then Left $ resolveType types (Alias Nothing x [])
else Right $ Ident x
convertTypeOrExpr other = other
convertExpr :: Expr -> Expr
convertExpr (Cast v e) = Cast (convertTypeOrExpr v) e
convertExpr (DimsFn f v) = DimsFn f (convertTypeOrExpr v)
convertExpr (DimFn f v e) = DimFn f (convertTypeOrExpr v) e
convertExpr other = other
2019-09-11 17:58:03 +02:00
convertModuleItem :: ModuleItem -> ModuleItem
2020-06-18 04:01:59 +02:00
convertModuleItem (Instance m params x rs p) =
Instance m (map mapParam params) x rs p
2019-09-11 17:58:03 +02:00
where mapParam (i, v) = (i, convertTypeOrExpr v)
convertModuleItem other = other
2019-02-18 09:59:17 +01:00
convertGenItem :: GenItem -> GenItem
convertGenItem (GenIf c a b) =
GenIf c a' b'
where
a' = convertGenItem' a
b' = convertGenItem' b
convertGenItem other = other
convertGenItem' :: GenItem -> GenItem
convertGenItem' item = do
GenBlock "" items
where
-- convert inner generate blocks first
item' = Generate [traverseNestedGenItems convertGenItem item]
types = execWriter $ collectNestedModuleItemsM collectTypedefM item'
Generate items = traverseNestedModuleItems (convertTypedef types) item'
collectTypedefM :: ModuleItem -> Writer Types ()
collectTypedefM (MIPackageItem (Typedef a b)) = tell $ Map.singleton b a
collectTypedefM _ = return ()
resolveItem :: Types -> (Type, Identifier) -> (Type, Identifier)
resolveItem types (t, x) = (resolveType types t, x)
2019-02-18 09:59:17 +01:00
resolveType :: Types -> Type -> Type
resolveType _ (Net kw sg rs) = Net kw sg rs
resolveType _ (Implicit sg rs) = Implicit sg rs
resolveType _ (IntegerVector kw sg rs) = IntegerVector kw sg rs
resolveType _ (IntegerAtom kw sg ) = IntegerAtom kw sg
resolveType _ (NonInteger kw ) = NonInteger kw
2019-04-23 06:23:32 +02:00
resolveType _ (InterfaceT x my rs) = InterfaceT x my rs
resolveType _ (Alias (Just ps) st rs) = Alias (Just ps) st rs
resolveType _ (TypeOf expr) = TypeOf expr
2020-01-12 02:35:51 +01:00
resolveType _ (UnpackedType t rs) = UnpackedType t rs
resolveType types (Enum t vals rs) = Enum (resolveType types t) vals rs
resolveType types (Struct p items rs) = Struct p (map (resolveItem types) items) rs
resolveType types (Union p items rs) = Union p (map (resolveItem types) items) rs
resolveType types (Alias Nothing st rs1) =
if Map.notMember st types
then Alias Nothing st rs1
else case resolveType types $ types Map.! st of
(Net kw sg rs2) -> Net kw sg $ rs1 ++ rs2
(Implicit sg rs2) -> Implicit sg $ rs1 ++ rs2
(IntegerVector kw sg rs2) -> IntegerVector kw sg $ rs1 ++ rs2
(Enum t v rs2) -> Enum t v $ rs1 ++ rs2
(Struct p l rs2) -> Struct p l $ rs1 ++ rs2
(Union p l rs2) -> Union p l $ rs1 ++ rs2
(InterfaceT x my rs2) -> InterfaceT x my $ rs1 ++ rs2
(Alias ps x rs2) -> Alias ps x $ rs1 ++ rs2
2020-01-12 02:35:51 +01:00
(UnpackedType t rs2) -> UnpackedType t $ rs1 ++ rs2
(IntegerAtom kw sg ) -> nullRange (IntegerAtom kw sg) rs1
(NonInteger kw ) -> nullRange (NonInteger kw ) rs1
(TypeOf expr) -> nullRange (TypeOf expr) rs1