Commit 642803a7 by Zachary Snow

expression traversals no longer visit types by default

parent de27065d
...@@ -82,10 +82,13 @@ traverseDeclM decl = do ...@@ -82,10 +82,13 @@ traverseDeclM decl = do
scopeExpr :: Expr -> ST Expr scopeExpr :: Expr -> ST Expr
scopeExpr expr = do scopeExpr expr = do
expr' <- traverseSinglyNestedExprsM scopeExpr expr expr' <- traverseSinglyNestedExprsM scopeExpr expr
>>= traverseExprTypesM scopeType
details <- lookupElemM expr' details <- lookupElemM expr'
case details of case details of
Just (accesses, _, _) -> return $ accessesToExpr accesses Just (accesses, _, _) -> return $ accessesToExpr accesses
_ -> return expr' _ -> return expr'
scopeType :: Type -> ST Type
scopeType = traverseNestedTypesM $ traverseTypeExprsM scopeExpr
-- substitute hierarchical references to constants -- substitute hierarchical references to constants
traverseExprM :: Expr -> ST Expr traverseExprM :: Expr -> ST Expr
......
...@@ -171,8 +171,11 @@ replaceInType :: Replacements -> Type -> Type ...@@ -171,8 +171,11 @@ replaceInType :: Replacements -> Type -> Type
replaceInType replacements = replaceInType replacements =
if Map.null replacements if Map.null replacements
then id then id
else traverseNestedTypes $ traverseTypeExprs $ else replaceInType' replacements
replaceInExpr' replacements
replaceInType' :: Replacements -> Type -> Type
replaceInType' replacements =
traverseNestedTypes $ traverseTypeExprs $ replaceInExpr' replacements
replaceInExpr :: Replacements -> Expr -> Expr replaceInExpr :: Replacements -> Expr -> Expr
replaceInExpr replacements = replaceInExpr replacements =
...@@ -184,7 +187,8 @@ replaceInExpr' :: Replacements -> Expr -> Expr ...@@ -184,7 +187,8 @@ replaceInExpr' :: Replacements -> Expr -> Expr
replaceInExpr' replacements (Ident x) = replaceInExpr' replacements (Ident x) =
Map.findWithDefault (Ident x) x replacements Map.findWithDefault (Ident x) x replacements
replaceInExpr' replacements other = replaceInExpr' replacements other =
traverseSinglyNestedExprs (replaceInExpr replacements) other traverseExprTypes (replaceInType' replacements) $
traverseSinglyNestedExprs (replaceInExpr' replacements) other
class ScopePath k where class ScopePath k where
toTiers :: Scopes a -> k -> [Tier] toTiers :: Scopes a -> k -> [Tier]
......
...@@ -36,7 +36,7 @@ traverseDeclM decl = do ...@@ -36,7 +36,7 @@ traverseDeclM decl = do
case decl' of case decl' of
Param Localparam UnknownType x e -> Param Localparam UnknownType x e ->
insertExpr x e insertExpr x e
Param Localparam (Implicit Signed [(RawNum 31, RawNum 0)]) x e -> Param Localparam (Implicit _ [(RawNum 31, RawNum 0)]) x e ->
insertExpr x e insertExpr x e
Param Localparam (Implicit sg rs) x e -> Param Localparam (Implicit sg rs) x e ->
insertExpr x $ Cast (Left t) e insertExpr x $ Cast (Left t) e
...@@ -81,6 +81,11 @@ substituteExprM :: Expr -> Scoper Expr Expr ...@@ -81,6 +81,11 @@ substituteExprM :: Expr -> Scoper Expr Expr
substituteExprM = embedScopes substitute substituteExprM = embedScopes substitute
convertExpr :: Scopes Expr -> Expr -> Expr convertExpr :: Scopes Expr -> Expr -> Expr
convertExpr info (Cast (Left t) e) =
Cast (Left t') e'
where
t' = traverseNestedTypes (traverseTypeExprs $ substitute info) t
e' = convertExpr info e
convertExpr info (Cast (Right c) e) = convertExpr info (Cast (Right c) e) =
Cast (Right c') e' Cast (Right c') e'
where where
......
{-# LANGUAGE TupleSections #-}
{- sv2v {- sv2v
- Author: Zachary Snow <zach@zachjs.com> - Author: Zachary Snow <zach@zachjs.com>
- -
...@@ -150,33 +151,29 @@ traverseStmtM' = ...@@ -150,33 +151,29 @@ traverseStmtM' =
traverseStmtAsgnsM traverseAsgnM traverseStmtAsgnsM traverseAsgnM
traverseExprM :: Expr -> Scoper Type Expr traverseExprM :: Expr -> Scoper Type Expr
traverseExprM = traverseNestedExprsM $ traverseExprM = embedScopes convertSubExpr >=> return . snd
embedScopes convertSubExpr >=> return . snd
traverseLHSM :: LHS -> Scoper Type LHS traverseLHSM :: LHS -> Scoper Type LHS
traverseLHSM = traverseNestedLHSsM $ convertLHS >=> return . snd traverseLHSM = convertLHS >=> return . snd
-- removes the innermost range from the given type, if possible -- removes the innermost range from the given type, if possible
dropInnerTypeRange :: Type -> Type dropInnerTypeRange :: Type -> Type
dropInnerTypeRange t = dropInnerTypeRange t =
case typeRanges t of case typeRanges t of
(_, []) -> unknownType (_, []) -> UnknownType
(tf, rs) -> tf $ tail rs (tf, rs) -> tf $ tail rs
-- produces the type of the given part select, if possible -- produces the type of the given part select, if possible
replaceInnerTypeRange :: PartSelectMode -> Range -> Type -> Type replaceInnerTypeRange :: PartSelectMode -> Range -> Type -> Type
replaceInnerTypeRange NonIndexed r t = replaceInnerTypeRange NonIndexed r t =
case typeRanges t of case typeRanges t of
(_, []) -> unknownType (_, []) -> UnknownType
(tf, rs) -> tf $ r : tail rs (tf, rs) -> tf $ r : tail rs
replaceInnerTypeRange IndexedPlus r t = replaceInnerTypeRange IndexedPlus r t =
replaceInnerTypeRange NonIndexed (snd r, RawNum 1) t replaceInnerTypeRange NonIndexed (snd r, RawNum 1) t
replaceInnerTypeRange IndexedMinus r t = replaceInnerTypeRange IndexedMinus r t =
replaceInnerTypeRange NonIndexed (snd r, RawNum 1) t replaceInnerTypeRange NonIndexed (snd r, RawNum 1) t
unknownType :: Type
unknownType = Implicit Unspecified []
traverseAsgnM :: (LHS, Expr) -> Scoper Type (LHS, Expr) traverseAsgnM :: (LHS, Expr) -> Scoper Type (LHS, Expr)
traverseAsgnM (lhs, expr) = do traverseAsgnM (lhs, expr) = do
-- convert the LHS using the innermost type information -- convert the LHS using the innermost type information
...@@ -319,9 +316,11 @@ convertExpr _ other = other ...@@ -319,9 +316,11 @@ convertExpr _ other = other
fallbackType :: Scopes Type -> Expr -> (Type, Expr) fallbackType :: Scopes Type -> Expr -> (Type, Expr)
fallbackType scopes e = fallbackType scopes e =
case lookupElem scopes e of (t, e)
Nothing -> (unknownType, e) where
Just (_, _, t) -> (t, e) t = case lookupElem scopes e of
Nothing -> UnknownType
Just (_, _, typ) -> typ
-- converting LHSs by looking at the innermost types first -- converting LHSs by looking at the innermost types first
convertLHS :: LHS -> Scoper Type (Type, LHS) convertLHS :: LHS -> Scoper Type (Type, LHS)
...@@ -354,65 +353,78 @@ convertSubExpr scopes (Range (Dot e x) NonIndexed rOuter) = ...@@ -354,65 +353,78 @@ convertSubExpr scopes (Range (Dot e x) NonIndexed rOuter) =
if isntStruct subExprType then if isntStruct subExprType then
fallbackType scopes orig' fallbackType scopes orig'
else if structIsntReady subExprType then else if structIsntReady subExprType then
(replaceInnerTypeRange NonIndexed rOuter fieldType, orig') (replaceInnerTypeRange NonIndexed rOuter' fieldType, orig')
else else
(replaceInnerTypeRange NonIndexed rOuter fieldType, undotted) (replaceInnerTypeRange NonIndexed rOuter' fieldType, undotted)
where where
(roLeft, roRight) = rOuter
(subExprType, e') = convertSubExpr scopes e (subExprType, e') = convertSubExpr scopes e
orig' = Range (Dot e' x) NonIndexed rOuter (_, roLeft') = convertSubExpr scopes roLeft
(_, roRight') = convertSubExpr scopes roRight
rOuter' = (roLeft', roRight')
orig' = Range (Dot e' x) NonIndexed rOuter'
(fieldType, bounds, dims) = lookupFieldInfo subExprType x (fieldType, bounds, dims) = lookupFieldInfo subExprType x
[dim] = dims [dim] = dims
rangeLeft = ( BinOp Sub (fst bounds) $ BinOp Sub (fst dim) (fst rOuter) rangeLeft = ( BinOp Sub (fst bounds) $ BinOp Sub (fst dim) roLeft'
, BinOp Sub (fst bounds) $ BinOp Sub (fst dim) (snd rOuter) ) , BinOp Sub (fst bounds) $ BinOp Sub (fst dim) roRight' )
rangeRight =( BinOp Add (snd bounds) $ BinOp Sub (snd dim) (fst rOuter) rangeRight =( BinOp Add (snd bounds) $ BinOp Sub (snd dim) roLeft'
, BinOp Add (snd bounds) $ BinOp Sub (snd dim) (snd rOuter) ) , BinOp Add (snd bounds) $ BinOp Sub (snd dim) roRight' )
undotted = Range e' NonIndexed $ undotted = Range e' NonIndexed $
endianCondRange dim rangeLeft rangeRight endianCondRange dim rangeLeft rangeRight
convertSubExpr scopes (Range (Dot e x) mode (baseO, lenO)) = convertSubExpr scopes (Range (Dot e x) mode (baseO, lenO)) =
if isntStruct subExprType then if isntStruct subExprType then
fallbackType scopes orig' fallbackType scopes orig'
else if structIsntReady subExprType then else if structIsntReady subExprType then
(replaceInnerTypeRange mode (baseO, lenO) fieldType, orig') (replaceInnerTypeRange mode (baseO', lenO') fieldType, orig')
else else
(replaceInnerTypeRange mode (baseO, lenO) fieldType, undotted) (replaceInnerTypeRange mode (baseO', lenO') fieldType, undotted)
where where
(subExprType, e') = convertSubExpr scopes e (subExprType, e') = convertSubExpr scopes e
orig' = Range (Dot e' x) mode (baseO, lenO) (_, baseO') = convertSubExpr scopes baseO
(_, lenO') = convertSubExpr scopes lenO
orig' = Range (Dot e' x) mode (baseO', lenO')
(fieldType, bounds, dims) = lookupFieldInfo subExprType x (fieldType, bounds, dims) = lookupFieldInfo subExprType x
[dim] = dims [dim] = dims
baseLeft = BinOp Sub (fst bounds) $ BinOp Sub (fst dim) baseO baseLeft = BinOp Sub (fst bounds) $ BinOp Sub (fst dim) baseO'
baseRight = BinOp Add (snd bounds) $ BinOp Sub (snd dim) baseO baseRight = BinOp Add (snd bounds) $ BinOp Sub (snd dim) baseO'
baseDec = baseLeft baseDec = baseLeft
baseInc = case mode of baseInc = case mode of
IndexedPlus -> BinOp Add (BinOp Sub baseRight lenO) one IndexedPlus -> BinOp Add (BinOp Sub baseRight lenO') one
IndexedMinus -> BinOp Sub (BinOp Add baseRight lenO) one IndexedMinus -> BinOp Sub (BinOp Add baseRight lenO') one
NonIndexed -> error "invariant violated" NonIndexed -> error "invariant violated"
base = endianCondExpr dim baseDec baseInc base = endianCondExpr dim baseDec baseInc
undotted = Range e' mode (base, lenO) undotted = Range e' mode (base, lenO')
one = RawNum 1 one = RawNum 1
convertSubExpr scopes (Range e mode r) = convertSubExpr scopes (Range e mode (left, right)) =
(replaceInnerTypeRange mode r t, Range e' mode r) (replaceInnerTypeRange mode r' t, Range e' mode r')
where (t, e') = convertSubExpr scopes e where
(t, e') = convertSubExpr scopes e
(_, left') = convertSubExpr scopes left
(_, right') = convertSubExpr scopes right
r' = (left', right')
convertSubExpr scopes (Bit (Dot e x) i) = convertSubExpr scopes (Bit (Dot e x) i) =
if isntStruct subExprType then if isntStruct subExprType then
fallbackType scopes orig' fallbackType scopes orig'
else if structIsntReady subExprType then else if structIsntReady subExprType then
(dropInnerTypeRange fieldType, orig') (dropInnerTypeRange fieldType, orig')
else else
(dropInnerTypeRange fieldType, Bit e' i') (dropInnerTypeRange fieldType, Bit e' iFlat)
where where
(subExprType, e') = convertSubExpr scopes e (subExprType, e') = convertSubExpr scopes e
orig' = Bit (Dot e' x) i (_, i') = convertSubExpr scopes i
orig' = Bit (Dot e' x) i'
(fieldType, bounds, dims) = lookupFieldInfo subExprType x (fieldType, bounds, dims) = lookupFieldInfo subExprType x
[dim] = dims [dim] = dims
iLeft = BinOp Sub (fst bounds) $ BinOp Sub (fst dim) i left = BinOp Sub (fst bounds) $ BinOp Sub (fst dim) i'
iRight = BinOp Add (snd bounds) $ BinOp Sub (snd dim) i right = BinOp Add (snd bounds) $ BinOp Sub (snd dim) i'
i' = endianCondExpr dim iLeft iRight iFlat = endianCondExpr dim left right
convertSubExpr scopes (Bit e i) = convertSubExpr scopes (Bit e i) =
if t == unknownType if t == UnknownType
then fallbackType scopes $ Bit e' i then fallbackType scopes $ Bit e' i'
else (dropInnerTypeRange t, Bit e' i) else (dropInnerTypeRange t, Bit e' i')
where (t, e') = convertSubExpr scopes e where
(t, e') = convertSubExpr scopes e
(_, i') = convertSubExpr scopes i
convertSubExpr scopes (Call e args) = convertSubExpr scopes (Call e args) =
(retType, Call e args') (retType, Call e args')
where where
...@@ -423,8 +435,8 @@ convertSubExpr scopes (Cast (Left t) e) = ...@@ -423,8 +435,8 @@ convertSubExpr scopes (Cast (Left t) e) =
where (_, e') = convertSubExpr scopes e where (_, e') = convertSubExpr scopes e
convertSubExpr scopes (Pattern items) = convertSubExpr scopes (Pattern items) =
if all (== "") $ map fst items' if all (== "") $ map fst items'
then (unknownType, Concat $ map snd items') then (UnknownType, Concat $ map snd items')
else (unknownType, Pattern items') else (UnknownType, Pattern items')
where where
items' = map mapItem items items' = map mapItem items
mapItem (x, e) = (x, e') mapItem (x, e) = (x, e')
...@@ -435,8 +447,15 @@ convertSubExpr scopes (Mux a b c) = ...@@ -435,8 +447,15 @@ convertSubExpr scopes (Mux a b c) =
(_, a') = convertSubExpr scopes a (_, a') = convertSubExpr scopes a
(t, b') = convertSubExpr scopes b (t, b') = convertSubExpr scopes b
(_, c') = convertSubExpr scopes c (_, c') = convertSubExpr scopes c
convertSubExpr scopes other = convertSubExpr scopes (Ident x) =
fallbackType scopes other fallbackType scopes (Ident x)
convertSubExpr scopes e =
(UnknownType, ) $
traverseExprTypes typeMapper $
traverseSinglyNestedExprs exprMapper e
where
exprMapper = snd . convertSubExpr scopes
typeMapper = traverseNestedTypes $ traverseTypeExprs exprMapper
-- get the fields and type function of a struct or union -- get the fields and type function of a struct or union
getFields :: Type -> Maybe [Field] getFields :: Type -> Maybe [Field]
...@@ -478,6 +497,6 @@ convertCall scopes fn (Args pnArgs kwArgs) = ...@@ -478,6 +497,6 @@ convertCall scopes fn (Args pnArgs kwArgs) =
(x, e') (x, e')
where where
details = lookupElem scopes $ LHSDot lhs x details = lookupElem scopes $ LHSDot lhs x
typ = maybe unknownType thd3 details typ = maybe UnknownType thd3 details
thd3 (_, _, c) = c thd3 (_, _, c) = c
(_, e') = convertSubExpr scopes $ convertExpr typ e (_, e') = convertSubExpr scopes $ convertExpr typ e
...@@ -402,9 +402,7 @@ collectNestedExprsM = collectify traverseNestedExprsM ...@@ -402,9 +402,7 @@ collectNestedExprsM = collectify traverseNestedExprsM
traverseSinglyNestedExprsM :: Monad m => MapperM m Expr -> MapperM m Expr traverseSinglyNestedExprsM :: Monad m => MapperM m Expr -> MapperM m Expr
traverseSinglyNestedExprsM exprMapper = em traverseSinglyNestedExprsM exprMapper = em
where where
typeMapper = traverseNestedTypesM (traverseTypeExprsM exprMapper) typeOrExprMapper (Left t) = return $ Left t
typeOrExprMapper (Left t) =
typeMapper t >>= return . Left
typeOrExprMapper (Right e) = typeOrExprMapper (Right e) =
exprMapper e >>= return . Right exprMapper e >>= return . Right
exprOrRangeMapper (Left e) = exprOrRangeMapper (Left e) =
......
...@@ -71,7 +71,7 @@ traverseDeclM decl = do ...@@ -71,7 +71,7 @@ traverseDeclM decl = do
-- rewrite and store a non-genvar data declaration's type information -- rewrite and store a non-genvar data declaration's type information
insertType :: Identifier -> Type -> ST () insertType :: Identifier -> Type -> ST ()
insertType ident typ = do insertType ident typ = do
typ' <- traverseNestedTypesM (traverseTypeExprsM scopeExpr) typ typ' <- scopeType typ
insertElem ident (typ', False) insertElem ident (typ', False)
-- rewrite an expression so that any identifiers it contains unambiguously refer -- rewrite an expression so that any identifiers it contains unambiguously refer
...@@ -79,10 +79,13 @@ insertType ident typ = do ...@@ -79,10 +79,13 @@ insertType ident typ = do
scopeExpr :: Expr -> ST Expr scopeExpr :: Expr -> ST Expr
scopeExpr expr = do scopeExpr expr = do
expr' <- traverseSinglyNestedExprsM scopeExpr expr expr' <- traverseSinglyNestedExprsM scopeExpr expr
>>= traverseExprTypesM scopeType
details <- lookupElemM expr' details <- lookupElemM expr'
case details of case details of
Just (accesses, _, (_, False)) -> return $ accessesToExpr accesses Just (accesses, _, (_, False)) -> return $ accessesToExpr accesses
_ -> return expr' _ -> return expr'
scopeType :: Type -> ST Type
scopeType = traverseNestedTypesM $ traverseTypeExprsM scopeExpr
-- convert TypeOf in a ModuleItem -- convert TypeOf in a ModuleItem
traverseModuleItemM :: ModuleItem -> ST ModuleItem traverseModuleItemM :: ModuleItem -> ST ModuleItem
...@@ -135,8 +138,8 @@ traverseExprM (Cast (Right size) expr) = do ...@@ -135,8 +138,8 @@ traverseExprM (Cast (Right size) expr) = do
size' <- traverseExprM size size' <- traverseExprM size
elaborateSizeCast size' expr' elaborateSizeCast size' expr'
traverseExprM other = traverseExprM other =
traverseExprTypesM traverseTypeM other traverseSinglyNestedExprsM traverseExprM other
>>= traverseSinglyNestedExprsM traverseExprM >>= traverseExprTypesM traverseTypeM
-- carry forward the signedness of the expression when cast to the given size -- carry forward the signedness of the expression when cast to the given size
elaborateSizeCast :: Expr -> Expr -> ST Expr elaborateSizeCast :: Expr -> Expr -> ST Expr
...@@ -151,8 +154,8 @@ traverseTypeM :: Type -> ST Type ...@@ -151,8 +154,8 @@ traverseTypeM :: Type -> ST Type
traverseTypeM (TypeOf expr) = traverseTypeM (TypeOf expr) =
traverseExprM expr >>= typeof traverseExprM expr >>= typeof
traverseTypeM other = traverseTypeM other =
traverseTypeExprsM traverseExprM other traverseSinglyNestedTypesM traverseTypeM other
>>= traverseSinglyNestedTypesM traverseTypeM >>= traverseTypeExprsM traverseExprM
-- attempts to find the given (potentially hierarchical or generate-scoped) -- attempts to find the given (potentially hierarchical or generate-scoped)
-- expression in the available scope information -- expression in the available scope information
......
...@@ -124,7 +124,11 @@ substituteExpr mapping (Ident x) = ...@@ -124,7 +124,11 @@ substituteExpr mapping (Ident x) =
Nothing -> Ident x Nothing -> Ident x
Just expr -> substituteExpr mapping expr Just expr -> substituteExpr mapping expr
substituteExpr mapping expr = substituteExpr mapping expr =
traverseSinglyNestedExprs (substituteExpr mapping) expr traverseExprTypes typeMapper $
traverseSinglyNestedExprs exprMapper expr
where
exprMapper = substituteExpr mapping
typeMapper = traverseNestedTypes $ traverseTypeExprs exprMapper
tagExpr :: Expr -> Expr tagExpr :: Expr -> Expr
tagExpr (Ident x) = Ident (':' : x) tagExpr (Ident x) = Ident (':' : x)
...@@ -254,7 +258,7 @@ pattern UU ch = Number (UnbasedUnsized ch) ...@@ -254,7 +258,7 @@ pattern UU ch = Number (UnbasedUnsized ch)
convertType :: Type -> Type convertType :: Type -> Type
convertType (TypeOf e) = TypeOf $ convertExpr SelfDetermined e convertType (TypeOf e) = TypeOf $ convertExpr SelfDetermined e
convertType other = other convertType other = traverseTypeExprs (convertExpr SelfDetermined) other
isParentSizedBinOp :: BinOp -> Bool isParentSizedBinOp :: BinOp -> Bool
isParentSizedBinOp BitAnd = True isParentSizedBinOp BitAnd = True
......
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