Typedef.hs 3.99 KB
Newer Older
1 2 3 4
{- sv2v
 - Author: Zachary Snow <zach@zachjs.com>
 -
 - Conversion for `typedef`
5
 -
6 7
 - Aliased types can appear in all data declarations, including modules, blocks,
 - and function parameters. They are also found in type cast expressions.
8 9 10 11
 -}

module Convert.Typedef (convert) where

12
import Control.Monad ((>=>))
13

14
import Convert.Scoper
15
import Convert.Traverse
16 17
import Language.SystemVerilog.AST

18
convert :: [AST] -> [AST]
19 20 21 22 23
convert = map $ traverseDescriptions $ partScoper
    traverseDeclM traverseModuleItemM traverseGenItemM traverseStmtM

traverseTypeOrExprM :: TypeOrExpr -> Scoper Type TypeOrExpr
traverseTypeOrExprM (Left (TypeOf (Ident x))) = do
24
    details <- lookupElemM x
25 26 27 28
    return $ case details of
        Nothing -> Left $ TypeOf $ Ident x
        Just (_, _, typ) -> Left typ
traverseTypeOrExprM (Right (Ident x)) = do
29
    details <- lookupElemM x
30 31 32 33
    return $ case details of
        Nothing -> Right $ Ident x
        Just (_, _, typ) -> Left typ
traverseTypeOrExprM other = return other
34

35 36 37 38 39 40 41 42 43 44 45
traverseExprM :: Expr -> Scoper Type Expr
traverseExprM (Cast v e) = do
    v' <- traverseTypeOrExprM v
    return $ Cast v' e
traverseExprM (DimsFn f v) = do
    v' <- traverseTypeOrExprM v
    return $ DimsFn f v'
traverseExprM (DimFn f v e) = do
    v' <- traverseTypeOrExprM v
    return $ DimFn f v' e
traverseExprM other = return other
46

47 48 49 50 51 52
traverseModuleItemM :: ModuleItem -> Scoper Type ModuleItem
traverseModuleItemM (Instance m params x rs p) = do
    let mapParam (i, v) = traverseTypeOrExprM v >>= \v' -> return (i, v')
    params' <- mapM mapParam params
    traverseModuleItemM' $ Instance m params' x rs p
traverseModuleItemM item = traverseModuleItemM' item
53

54 55
traverseModuleItemM' :: ModuleItem -> Scoper Type ModuleItem
traverseModuleItemM' =
56
    traverseTypesM (traverseNestedTypesM traverseTypeM) >=>
57
    traverseExprsM (traverseNestedExprsM traverseExprM)
58

59 60
traverseGenItemM :: GenItem -> Scoper Type GenItem
traverseGenItemM = traverseGenItemExprsM (traverseNestedExprsM traverseExprM)
61

62 63 64 65 66 67 68
traverseDeclM :: Decl -> Scoper Type Decl
traverseDeclM decl = do
    item <- traverseModuleItemM (MIPackageItem $ Decl decl)
    let MIPackageItem (Decl decl') = item
    case decl' of
        Variable{} -> return decl'
        Param{} -> return decl'
69
        ParamType Localparam x t -> do
70 71 72
            t' <- traverseNestedTypesM traverseTypeM t
            insertElem x t'
            return $ CommentDecl $ "removed localparam type " ++ x
73 74
        ParamType{} -> return decl'
        CommentDecl{} -> return decl'
75

76
traverseStmtM :: Stmt -> Scoper Type Stmt
77 78 79 80 81 82
traverseStmtM = traverseStmtExprsM $ traverseNestedExprsM traverseStmtExprM
    where
        traverseStmtExprM :: Expr -> Scoper Type Expr
        traverseStmtExprM =
            traverseExprTypesM (traverseNestedTypesM traverseTypeM) >=>
            traverseExprM
83

84
traverseTypeM :: Type -> Scoper Type Type
85
traverseTypeM (Alias st rs1) = do
86
    details <- lookupElemM st
87
    return $ case details of
88
        Nothing -> Alias st rs1
89 90 91 92 93 94 95 96
        Just (_, _, typ) -> case typ 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
97 98
            Alias            xx rs2 -> Alias            xx $ rs1 ++ rs2
            PSAlias    ps    xx rs2 -> PSAlias    ps    xx $ rs1 ++ rs2
99
            CSAlias    ps pm xx rs2 -> CSAlias    ps pm xx $ rs1 ++ rs2
100 101 102 103 104
            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
traverseTypeM other = return other