Commit c5ef5ea9 by Zachary Snow

additional expression simplification

- constant folding supports hex numbers
- simplify mod
- simplify pow
- elaborate !(a == b) into a != b
parent df7277a6
...@@ -27,6 +27,7 @@ module Language.SystemVerilog.AST.Expr ...@@ -27,6 +27,7 @@ module Language.SystemVerilog.AST.Expr
) where ) where
import Data.List (intercalate) import Data.List (intercalate)
import Numeric (readHex)
import Text.Printf (printf) import Text.Printf (printf)
import Text.Read (readMaybe) import Text.Read (readMaybe)
...@@ -168,13 +169,17 @@ clog2 :: Int -> Int ...@@ -168,13 +169,17 @@ clog2 :: Int -> Int
clog2 n = if n < 2 then 0 else clog2Help 1 n clog2 n = if n < 2 then 0 else clog2Help 1 n
readNumber :: String -> Maybe Int readNumber :: String -> Maybe Int
readNumber n = readNumber ('3' : '2' : '\'' : 'd' : rest) = readMaybe rest
readMaybe n' :: Maybe Int readNumber ( '\'' : 'd' : rest) = readMaybe rest
where readNumber ('3' : '2' : '\'' : 'h' : rest) =
n' = case n of case readHex rest of
'3' : '2' : '\'' : 'd' : rest -> rest [(v, _)] -> Just v
'\'' : 'd' : rest -> rest _ -> Nothing
_ -> n readNumber ('\'' : 'h' : rest) =
case readHex rest of
[(v, _)] -> Just v
_ -> Nothing
readNumber n = readMaybe n
showUniOpPrec :: Expr -> String showUniOpPrec :: Expr -> String
showUniOpPrec (e @ UniOp{}) = printf "(%s)" (show e) showUniOpPrec (e @ UniOp{}) = printf "(%s)" (show e)
...@@ -190,6 +195,7 @@ showBinOpPrec e = show e ...@@ -190,6 +195,7 @@ showBinOpPrec e = show e
simplify :: Expr -> Expr simplify :: Expr -> Expr
simplify (UniOp LogNot (Number "1")) = Number "0" simplify (UniOp LogNot (Number "1")) = Number "0"
simplify (UniOp LogNot (Number "0")) = Number "1" simplify (UniOp LogNot (Number "0")) = Number "1"
simplify (UniOp LogNot (BinOp Eq a b)) = BinOp Ne a b
simplify (orig @ (UniOp UniSub (Number n))) = simplify (orig @ (UniOp UniSub (Number n))) =
case readNumber n of case readNumber n of
Nothing -> orig Nothing -> orig
...@@ -251,6 +257,8 @@ simplify (BinOp op e1 e2) = ...@@ -251,6 +257,8 @@ simplify (BinOp op e1 e2) =
(Mul, Just x, Just y) -> Number $ show (x * y) (Mul, Just x, Just y) -> Number $ show (x * y)
(Div, Just _, Just 0) -> Number "x" (Div, Just _, Just 0) -> Number "x"
(Div, Just x, Just y) -> Number $ show (x `quot` y) (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 (Eq , Just x, Just y) -> bool $ x == y
(Ne , Just x, Just y) -> bool $ x /= y (Ne , Just x, Just y) -> bool $ x /= y
(Gt , Just x, Just y) -> bool $ x > y (Gt , Just x, Just y) -> bool $ x > y
......
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