2019-02-18 09:59:17 +01:00
|
|
|
{- sv2v
|
|
|
|
|
- Author: Zachary Snow <zach@zachjs.com>
|
|
|
|
|
-
|
|
|
|
|
- Conversion for `typedef`
|
2019-02-24 09:06:40 +01:00
|
|
|
-
|
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
|
|
|
|
|
|
2019-03-01 02:30:21 +01:00
|
|
|
import Control.Monad.Writer
|
2019-02-18 09:59:17 +01:00
|
|
|
import qualified Data.Map as Map
|
|
|
|
|
|
2019-03-01 02:30:21 +01:00
|
|
|
import Convert.Traverse
|
2019-02-18 09:59:17 +01:00
|
|
|
import Language.SystemVerilog.AST
|
|
|
|
|
|
|
|
|
|
type Types = Map.Map Identifier Type
|
|
|
|
|
|
2019-04-24 00:44:45 +02:00
|
|
|
convert :: [AST] -> [AST]
|
2019-04-30 21:44:52 +02:00
|
|
|
convert =
|
|
|
|
|
traverseFiles
|
|
|
|
|
(collectDescriptionsM getTypedef)
|
|
|
|
|
(\a -> traverseDescriptions $ removeTypedef . convertDescription a)
|
2019-02-18 09:59:17 +01:00
|
|
|
where
|
2019-03-01 02:30:21 +01:00
|
|
|
getTypedef :: Description -> Writer Types ()
|
2019-03-07 19:19:31 +01:00
|
|
|
getTypedef (PackageItem (Typedef a b)) = tell $ Map.singleton b a
|
2019-09-09 18:44:45 +02:00
|
|
|
getTypedef (Part _ Interface _ x _ _) =
|
|
|
|
|
tell $ Map.singleton x (InterfaceT x Nothing [])
|
2019-03-01 02:30:21 +01:00
|
|
|
getTypedef _ = return ()
|
2019-03-07 19:19:31 +01:00
|
|
|
removeTypedef :: Description -> Description
|
|
|
|
|
removeTypedef (PackageItem (Typedef _ x)) =
|
|
|
|
|
PackageItem $ Comment $ "removed typedef: " ++ x
|
|
|
|
|
removeTypedef other = other
|
2019-02-18 09:59:17 +01:00
|
|
|
|
|
|
|
|
convertDescription :: Types -> Description -> Description
|
2019-03-07 19:19:31 +01:00
|
|
|
convertDescription globalTypes description =
|
|
|
|
|
traverseModuleItems removeTypedef $
|
2019-09-11 17:58:03 +02:00
|
|
|
traverseModuleItems convertModuleItem $
|
2019-04-02 06:16:06 +02:00
|
|
|
traverseModuleItems (traverseExprs $ traverseNestedExprs $ convertExpr) $
|
2019-03-07 19:19:31 +01:00
|
|
|
traverseModuleItems (traverseTypes $ resolveType types) $
|
|
|
|
|
description
|
|
|
|
|
where
|
|
|
|
|
types = Map.union globalTypes $
|
|
|
|
|
execWriter $ collectModuleItemsM getTypedef description
|
|
|
|
|
getTypedef :: ModuleItem -> Writer Types ()
|
|
|
|
|
getTypedef (MIPackageItem (Typedef a b)) = tell $ Map.singleton b a
|
|
|
|
|
getTypedef _ = return ()
|
|
|
|
|
removeTypedef :: ModuleItem -> ModuleItem
|
|
|
|
|
removeTypedef (MIPackageItem (Typedef _ x)) =
|
|
|
|
|
MIPackageItem $ Comment $ "removed typedef: " ++ x
|
|
|
|
|
removeTypedef other = other
|
2019-09-11 17:58:03 +02:00
|
|
|
convertTypeOrExpr :: TypeOrExpr -> TypeOrExpr
|
|
|
|
|
convertTypeOrExpr (Right (Ident x)) =
|
2019-04-02 06:16:06 +02:00
|
|
|
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
|
2019-09-12 04:52:01 +02:00
|
|
|
convertExpr (Cast v e) = Cast (convertTypeOrExpr v) e
|
2019-09-14 18:31:44 +02:00
|
|
|
convertExpr (DimsFn f v) = DimsFn f (convertTypeOrExpr v)
|
|
|
|
|
convertExpr (DimFn f v e) = DimFn f (convertTypeOrExpr v) e
|
2019-04-02 06:16:06 +02:00
|
|
|
convertExpr other = other
|
2019-09-11 17:58:03 +02:00
|
|
|
convertModuleItem :: ModuleItem -> ModuleItem
|
|
|
|
|
convertModuleItem (Instance m params x r p) =
|
|
|
|
|
Instance m (map mapParam params) x r p
|
|
|
|
|
where mapParam (i, v) = (i, convertTypeOrExpr v)
|
|
|
|
|
convertModuleItem other = other
|
2019-02-18 09:59:17 +01:00
|
|
|
|
2019-08-09 05:12:06 +02:00
|
|
|
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
|
2019-03-22 21:57:13 +01:00
|
|
|
resolveType _ (Net kw rs) = Net kw 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 _ (Enum Nothing vals rs) = Enum Nothing vals rs
|
2019-04-24 09:37:47 +02:00
|
|
|
resolveType _ (Alias (Just ps) st rs) = Alias (Just ps) st rs
|
2019-02-24 03:24:13 +01:00
|
|
|
resolveType types (Enum (Just t) vals rs) = Enum (Just $ resolveType types t) vals rs
|
2019-08-09 05:12:06 +02:00
|
|
|
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
|
2019-04-24 09:37:47 +02:00
|
|
|
resolveType types (Alias Nothing st rs1) =
|
2019-03-04 08:58:00 +01:00
|
|
|
if Map.notMember st types
|
2019-09-09 18:44:45 +02:00
|
|
|
then Alias Nothing st rs1
|
2019-03-04 08:58:00 +01:00
|
|
|
else case resolveType types $ types Map.! st of
|
2019-04-09 03:28:33 +02:00
|
|
|
(Net kw rs2) -> Net kw $ 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
|
2019-08-09 05:12:06 +02:00
|
|
|
(Union p l rs2) -> Union p l $ rs1 ++ rs2
|
2019-04-09 03:28:33 +02:00
|
|
|
(InterfaceT x my rs2) -> InterfaceT x my $ rs1 ++ rs2
|
2019-03-22 21:57:13 +01:00
|
|
|
(IntegerAtom kw _ ) -> error $ "resolveType encountered packed `" ++ (show kw) ++ "` on " ++ st
|
|
|
|
|
(NonInteger kw ) -> error $ "resolveType encountered packed `" ++ (show kw) ++ "` on " ++ st
|
2019-04-24 09:37:47 +02:00
|
|
|
(Alias _ _ _) -> error $ "resolveType invariant failed on " ++ st
|