blob: 77e5861813bdc677be2b120b29940e08bd2edc3c [file] [log] [blame]
external-reality8f34d232014-02-22 21:35:47 -05001module Lambda ( freeVariables
2 , lambdaArgs
3 , lambdaBody
4 ) where
5
6import Control.Monad
7import Data.Generics.Aliases
8import Data.Generics.Schemes
9import Data.List
external-realitya56f1152014-03-04 21:57:05 -050010import Data.Char
external-reality8f34d232014-02-22 21:35:47 -050011import Language.Haskell.Exts
12------------------------------------------------------------------------------
13import HDevTools
external-reality8f34d232014-02-22 21:35:47 -050014
15------------------------------------------------------------------------------
external-realitya56f1152014-03-04 21:57:05 -050016freeVariables :: FilePath -> FilePath -> FilePath -> String -> String -> IO String
17freeVariables srcPath pkgConfigPath cabalFilePath buildTargetName code = case parseExp code of
external-reality8f34d232014-02-22 21:35:47 -050018 ParseOk ast -> do
19 names <- dropModuleVariableNames srcPath
20 pkgConfigPath
21 cabalFilePath
22 buildTargetName $ extractFreeVariables ast
23 return . dropCommas $ show names
24 _ -> return "Error parsing freeVars"
25
26------------------------------------------------------------------------------
27lambdaBody :: String -> String
28lambdaBody code = case parseExp code of
29 ParseOk ast -> show . extractLambdaBody $ ast
30 _ -> "[]"
31
32------------------------------------------------------------------------------
33lambdaArgs :: String -> String
34lambdaArgs code = case parseExp code of
external-realitya950a5f2014-03-04 22:15:27 -050035 ParseOk ast -> prettyLambdaArgs ast
external-reality8f34d232014-02-22 21:35:47 -050036 _ -> "[]"
external-realitya950a5f2014-03-04 22:15:27 -050037 where
38 prettyLambdaArgs = trim
39 . takeWhile (/= '-')
40 . dropWhile (== '\\')
41 . prettyPrint
external-reality8f34d232014-02-22 21:35:47 -050042
43------------------------------------------------------------------------------
44extractLambdaArgs :: Exp -> String
45extractLambdaArgs (Lambda _ ast _) = dropCommas . show $ allNames ast
46extractLambdaArgs _ = "[]"
47
48------------------------------------------------------------------------------
49allVariables :: GenericQ [Exp]
50allVariables = listify isVar
51
52------------------------------------------------------------------------------
53allBindings :: GenericQ [Pat]
54allBindings = listify isBinding
55
56------------------------------------------------------------------------------
57allNames :: GenericQ [String]
58allNames = everything (++) ([] `mkQ` fmap (: []) getStringFromName)
59
60------------------------------------------------------------------------------
61isVar :: Exp -> Bool
62isVar (Var _) = True
63isVar _ = False
64
65------------------------------------------------------------------------------
66isBinding :: Pat -> Bool
67isBinding (PVar _) = True
68isBinding _ = False
69
70------------------------------------------------------------------------------
71getStringFromName :: Name -> String
72getStringFromName (Symbol str) = str
73getStringFromName (Ident str) = str
74
75------------------------------------------------------------------------------
76dropCommas :: String -> String
77dropCommas = filter (/= ',')
78
79------------------------------------------------------------------------------
80extractLambdaBody :: Exp -> String
81extractLambdaBody (Lambda _ _ ast) = prettyPrint ast
82extractLambdaBody _ = "[]"
83
84------------------------------------------------------------------------------
85extractFreeVariables :: GenericQ [String]
86extractFreeVariables ast = allNames (allVariables ast) \\
87 allNames (allBindings ast)
88
89------------------------------------------------------------------------------
90dropModuleVariableNames :: FilePath -> FilePath -> FilePath -> String -> [String] -> IO [String]
91dropModuleVariableNames srcPath pkgConfigPath cabalFilePath buildTargetName =
92 filterM $ (liftM not) . isInModuleScope srcPath
93 pkgConfigPath
94 cabalFilePath
95 buildTargetName
external-realitya950a5f2014-03-04 22:15:27 -050096
97
98------------------------------------------------------------------------------
99
100trim :: [Char] -> [Char]
101trim xs = dropSpaceTail "" $ dropWhile isSpace xs
102
103dropSpaceTail :: [Char] -> [Char] -> [Char]
104dropSpaceTail _ "" = ""
105dropSpaceTail maybeStuff (x:xs)
106 | isSpace x = dropSpaceTail (x:maybeStuff) xs
107 | null maybeStuff = x : dropSpaceTail "" xs
108 | otherwise = reverse maybeStuff ++ x : dropSpaceTail "" xs
109