{- sv2v - Author: Zachary Snow - - 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