{-# LANGUAGE TemplateHaskell #-}
import Data.Data
import Data.Either
import Data.Generics.Aliases
import Data.Generics.Schemes
import Language.Haskell.TH
import System.Exit
import Language.Haskell.ParseExp
fixNegLits :: Exp -> Exp
fixNegLits = everywhere (mkT trans)
where
trans (LitE (IntegerL l))
| l < 0 = AppE (VarE (mkName "negate")) (LitE (IntegerL (negate l)))
trans e = e
parse :: String -> Exp
parse str = case parseExp str of
Right exp -> fixNegLits exp
Left msg -> error msg
dequalify :: Exp -> Exp
dequalify = everywhere (mkT trans)
where
trans (VarE v) = VarE $ mkName $ nameBase v
trans e = e
addWhite :: Char -> String
addWhite c
| c `elem` cs = " " ++ [c] ++ " "
| otherwise = [c]
where
cs = ['(', ')', ',', '-', ' ']
test1 = ("\"sdf\"", [| "sdf" |])
test2 = ("sum [1,2,3]", [| sum [1,2,3] |])
test3 = ("min (max (negate (-34)) 888) (signum (-45))", [| min (max (negate (-34)) 888) (signum (-45)) |])
test4 = ("[(1,'a',\"a\"),(2,'b',\"b\"),(-3,'c',\"c\")]", [| [(1,'a',"a"),(2,'b',"b"),(-3,'c',"c")] |])
tests = [test1,test2,test3,test4]
main = do
es1 <- mapM (fmap dequalify . runQ . snd) tests
let es2 = map (parse . fst) tests
es3 = map (parse . concatMap addWhite . fst) tests
oks2 = map (uncurry (==)) $ zip es1 es2
oks3 = map (uncurry (==)) $ zip es1 es3
failedTests = [i | (i,(ok2,ok3)) <- zip [1..] (zip oks2 oks3), not (ok2&&ok3)]
if and oks2 && and oks3
then putStrLn "All tests passed"
else do
putStrLn $ "Tests " ++ show failedTests ++ " failed"
exitFailure