mirror of https://github.com/zachjs/sv2v.git
61 lines
1.9 KiB
Haskell
61 lines
1.9 KiB
Haskell
{- sv2v
|
|
- Author: Zachary Snow <zach@zachjs.com>
|
|
-
|
|
- Conversion for `casez` and `casex`
|
|
-
|
|
- Note that this conversion does not completely replicate the behavior of
|
|
- `casex` and `casez` in cases where that case expression itself (rather than
|
|
- just the case item patterns) contains wildcard values. This is apparently
|
|
- rarely ever intentially done.
|
|
-}
|
|
|
|
module Convert.CaseKW (convert) where
|
|
|
|
import Convert.Template.Stmt (stmtConverter)
|
|
|
|
import Language.SystemVerilog.AST
|
|
|
|
convert :: AST -> AST
|
|
convert = stmtConverter convertStmt
|
|
|
|
-- Conversions:
|
|
-- `casez` -> `case` with wildcards (?, z) expanded
|
|
-- `casex` -> `case` with wildcards (?, z, x) expanded
|
|
|
|
-- to be either 0 or 1
|
|
|
|
wildcards :: CaseKW -> [Char]
|
|
wildcards CaseN = [] -- CaseN == `case`
|
|
wildcards CaseZ = ['?', 'z', 'Z']
|
|
wildcards CaseX = ['?', 'z', 'Z', 'x', 'X']
|
|
|
|
possibilities :: [Char]
|
|
possibilities = ['0', '1']
|
|
|
|
explodeBy :: [Char] -> String -> [String]
|
|
explodeBy _ "" = [""]
|
|
explodeBy wilds (x : xs) =
|
|
if elem x wilds
|
|
then concat $ map (\c -> map (c :) prev) possibilities
|
|
else map (x :) prev
|
|
where prev = explodeBy wilds xs
|
|
|
|
expandExpr :: [Char] -> Expr -> [Expr]
|
|
expandExpr wilds (Number s) = map Number $ explodeBy wilds s
|
|
expandExpr [] other = [other]
|
|
-- TODO: Hopefully they only give us constant expressions...
|
|
expandExpr _ other = error $ "CaseKW conversione encountered case that was not a number, which is dubious..." ++ (show other)
|
|
|
|
-- Note that we don't have to convert the statements within the cases, as the
|
|
-- conversion template takes care of that for us.
|
|
convertStmt :: Stmt -> Stmt
|
|
convertStmt (Case kw expr cases def) =
|
|
Case CaseN expr cases' def
|
|
where
|
|
wilds = wildcards kw
|
|
cases' = map convertCase cases
|
|
convertCase :: Case -> Case
|
|
convertCase (exprs, stmt) = (exprs', stmt)
|
|
where exprs' = concat $ map (expandExpr wilds) exprs
|
|
convertStmt other = other
|