\begin{code}
module Text.Printf.TH.Simplify (simplify, Simplify) where
import Language.Haskell.TH.Syntax
import Language.Haskell.TH
import Monad (liftM)
class Simplify a where
simplify :: a -> a
instance Simplify a => Simplify (Q a) where
simplify = liftM simplify
instance Simplify a => Simplify [a] where
simplify = map simplify
instance Simplify Exp where
simplify (AppE e1 e2) = AppE (simplify e1) (simplify e2)
simplify (InfixE me1 (VarE op) me2)
= let (me1', me2') = (fmap simplify me1, fmap simplify me2)
in f me1' op me2'
where
f (Just (LitE (IntegerL i1))) x (Just (LitE (IntegerL i2))) | x == '(>) =
if i1 > i2 then ConE 'True else ConE 'False
f (Just (LitE (IntegerL i1))) x (Just (LitE (IntegerL i2))) | x == '(>=) =
if i1 >= i2 then ConE 'True
else ConE 'False
f (Just (LitE (IntegerL i1))) x ( Just (LitE (IntegerL i2))) | x == '(<) =
if i1 < i2 then ConE 'True
else ConE 'False
f (Just (LitE (IntegerL i1))) x (Just (LitE (IntegerL i2))) | x == '(<=) =
if i1 <= i2 then ConE 'True
else ConE 'False
f (Just (LitE (IntegerL 0))) x (Just y) | x == '(+) = y
f (Just y) x (Just (LitE (IntegerL 0))) | x == '(+) = y
f (Just (LitE (IntegerL i1))) x (Just (LitE (IntegerL i2))) | x == '(+) =
LitE (IntegerL (i1 + i2))
f (Just (LitE (IntegerL 0))) x (Just y) | x == '() = AppE (VarE 'negate) y
f (Just y) x (Just (LitE (IntegerL 0))) | x == '() = y
f (Just (LitE (IntegerL i1))) x (Just (LitE (IntegerL i2))) | x == '() =
LitE (IntegerL (i1 i2))
f (Just (LitE (IntegerL 1))) x (Just y) | x == '(*) = y
f (Just y) x (Just (LitE (IntegerL 1))) | x == '(*) = y
f (Just (LitE (IntegerL i1))) x (Just (LitE (IntegerL i2))) | x == '(*) =
LitE (IntegerL (i1 * i2))
f me1' _ me2' = InfixE me1' (VarE op) me2'
simplify (CondE g t f) = let x = simplify g in
f' x where f' (ConE y) | y == 'True = simplify t
f' (ConE y) | y == 'False = simplify f
f' g' = CondE g' (simplify t) (simplify f)
simplify (LamE ps e) = LamE ps (simplify e)
simplify (TupE es) = TupE (map simplify es)
simplify (LetE ds e) = LetE (simplify ds) (simplify e)
simplify (CaseE e ms) = CaseE (simplify e) (map simplify ms)
simplify (DoE ss) = DoE (map simplify ss)
simplify (CompE ss) = CompE (map simplify ss)
simplify (ArithSeqE dd) = ArithSeqE (simplify dd)
simplify (ListE es) = ListE (map simplify es)
simplify (SigE e t) = SigE (simplify e) t
simplify e = e
instance Simplify Dec where
simplify (FunD f cs) = FunD f (map simplify cs)
simplify (ValD p rhs ds) = ValD p (simplify rhs) (simplify ds)
simplify (ClassD ctxt tycon [] tyvars ds)
= ClassD ctxt tycon [] tyvars (simplify ds)
simplify (InstanceD ctxt typ ds) = InstanceD ctxt typ (simplify ds)
simplify d = d
instance Simplify Body where
simplify (NormalB e) = NormalB (simplify e)
simplify (GuardedB ges)
= GuardedB (map (\(e1, e2) -> (simplify e1, simplify e2)) ges)
instance Simplify Guard where
simplify (NormalG e) = NormalG $ simplify e
simplify (PatG l) = PatG $ map simplify l
instance Simplify Range where
simplify (FromR e) = FromR (simplify e)
simplify (FromThenR e1 e2) = FromThenR (simplify e1) (simplify e2)
simplify (FromToR e1 e2) = FromToR (simplify e1) (simplify e2)
simplify (FromThenToR e1 e2 e3)
= FromThenToR (simplify e1) (simplify e2) (simplify e3)
instance Simplify Stmt where
simplify (BindS p e) = BindS p (simplify e)
simplify (LetS ds) = LetS (simplify ds)
simplify (NoBindS e) = NoBindS (simplify e)
simplify (ParS _) = error "simplify[Statement]: ParS"
instance Simplify Match where
simplify (Match p rhs ds) = Match p (simplify rhs) (simplify ds)
instance Simplify Clause where
simplify (Clause ps rhs ds) = Clause ps (simplify rhs) (simplify ds)
\end{code}