From c5ef5ea9e2e995023e8594c5d29fce7d4f6ca30b Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Sun, 5 Apr 2020 23:12:54 -0400 Subject: [PATCH] additional expression simplification - constant folding supports hex numbers - simplify mod - simplify pow - elaborate !(a == b) into a != b --- src/Language/SystemVerilog/AST/Expr.hs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/Language/SystemVerilog/AST/Expr.hs b/src/Language/SystemVerilog/AST/Expr.hs index 38f0653..a57b19e 100644 --- a/src/Language/SystemVerilog/AST/Expr.hs +++ b/src/Language/SystemVerilog/AST/Expr.hs @@ -27,6 +27,7 @@ module Language.SystemVerilog.AST.Expr ) where import Data.List (intercalate) +import Numeric (readHex) import Text.Printf (printf) import Text.Read (readMaybe) @@ -168,13 +169,17 @@ clog2 :: Int -> Int clog2 n = if n < 2 then 0 else clog2Help 1 n readNumber :: String -> Maybe Int -readNumber n = - readMaybe n' :: Maybe Int - where - n' = case n of - '3' : '2' : '\'' : 'd' : rest -> rest - '\'' : 'd' : rest -> rest - _ -> n +readNumber ('3' : '2' : '\'' : 'd' : rest) = readMaybe rest +readNumber ( '\'' : 'd' : rest) = readMaybe rest +readNumber ('3' : '2' : '\'' : 'h' : rest) = + case readHex rest of + [(v, _)] -> Just v + _ -> Nothing +readNumber ('\'' : 'h' : rest) = + case readHex rest of + [(v, _)] -> Just v + _ -> Nothing +readNumber n = readMaybe n showUniOpPrec :: Expr -> String showUniOpPrec (e @ UniOp{}) = printf "(%s)" (show e) @@ -190,6 +195,7 @@ showBinOpPrec e = show e simplify :: Expr -> Expr simplify (UniOp LogNot (Number "1")) = Number "0" simplify (UniOp LogNot (Number "0")) = Number "1" +simplify (UniOp LogNot (BinOp Eq a b)) = BinOp Ne a b simplify (orig @ (UniOp UniSub (Number n))) = case readNumber n of Nothing -> orig @@ -251,6 +257,8 @@ simplify (BinOp op e1 e2) = (Mul, Just x, Just y) -> Number $ show (x * y) (Div, Just _, Just 0) -> Number "x" (Div, Just x, Just y) -> Number $ show (x `quot` y) + (Mod, Just x, Just y) -> Number $ show (x `rem` y) + (Pow, Just x, Just y) -> Number $ show (x ^ y) (Eq , Just x, Just y) -> bool $ x == y (Ne , Just x, Just y) -> bool $ x /= y (Gt , Just x, Just y) -> bool $ x > y