external-reality | 8f34d23 | 2014-02-22 21:35:47 -0500 | [diff] [blame] | 1 | module Lambda ( freeVariables |
| 2 | , lambdaArgs |
| 3 | , lambdaBody |
| 4 | ) where |
| 5 | |
| 6 | import Control.Monad |
| 7 | import Data.Generics.Aliases |
| 8 | import Data.Generics.Schemes |
| 9 | import Data.List |
external-reality | a56f115 | 2014-03-04 21:57:05 -0500 | [diff] [blame] | 10 | import Data.Char |
external-reality | 8f34d23 | 2014-02-22 21:35:47 -0500 | [diff] [blame] | 11 | import Language.Haskell.Exts |
| 12 | ------------------------------------------------------------------------------ |
| 13 | import HDevTools |
external-reality | 8f34d23 | 2014-02-22 21:35:47 -0500 | [diff] [blame] | 14 | |
| 15 | ------------------------------------------------------------------------------ |
external-reality | a56f115 | 2014-03-04 21:57:05 -0500 | [diff] [blame] | 16 | freeVariables :: FilePath -> FilePath -> FilePath -> String -> String -> IO String |
| 17 | freeVariables srcPath pkgConfigPath cabalFilePath buildTargetName code = case parseExp code of |
external-reality | 8f34d23 | 2014-02-22 21:35:47 -0500 | [diff] [blame] | 18 | 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 | ------------------------------------------------------------------------------ |
| 27 | lambdaBody :: String -> String |
| 28 | lambdaBody code = case parseExp code of |
| 29 | ParseOk ast -> show . extractLambdaBody $ ast |
| 30 | _ -> "[]" |
| 31 | |
| 32 | ------------------------------------------------------------------------------ |
| 33 | lambdaArgs :: String -> String |
| 34 | lambdaArgs code = case parseExp code of |
external-reality | a950a5f | 2014-03-04 22:15:27 -0500 | [diff] [blame^] | 35 | ParseOk ast -> prettyLambdaArgs ast |
external-reality | 8f34d23 | 2014-02-22 21:35:47 -0500 | [diff] [blame] | 36 | _ -> "[]" |
external-reality | a950a5f | 2014-03-04 22:15:27 -0500 | [diff] [blame^] | 37 | where |
| 38 | prettyLambdaArgs = trim |
| 39 | . takeWhile (/= '-') |
| 40 | . dropWhile (== '\\') |
| 41 | . prettyPrint |
external-reality | 8f34d23 | 2014-02-22 21:35:47 -0500 | [diff] [blame] | 42 | |
| 43 | ------------------------------------------------------------------------------ |
| 44 | extractLambdaArgs :: Exp -> String |
| 45 | extractLambdaArgs (Lambda _ ast _) = dropCommas . show $ allNames ast |
| 46 | extractLambdaArgs _ = "[]" |
| 47 | |
| 48 | ------------------------------------------------------------------------------ |
| 49 | allVariables :: GenericQ [Exp] |
| 50 | allVariables = listify isVar |
| 51 | |
| 52 | ------------------------------------------------------------------------------ |
| 53 | allBindings :: GenericQ [Pat] |
| 54 | allBindings = listify isBinding |
| 55 | |
| 56 | ------------------------------------------------------------------------------ |
| 57 | allNames :: GenericQ [String] |
| 58 | allNames = everything (++) ([] `mkQ` fmap (: []) getStringFromName) |
| 59 | |
| 60 | ------------------------------------------------------------------------------ |
| 61 | isVar :: Exp -> Bool |
| 62 | isVar (Var _) = True |
| 63 | isVar _ = False |
| 64 | |
| 65 | ------------------------------------------------------------------------------ |
| 66 | isBinding :: Pat -> Bool |
| 67 | isBinding (PVar _) = True |
| 68 | isBinding _ = False |
| 69 | |
| 70 | ------------------------------------------------------------------------------ |
| 71 | getStringFromName :: Name -> String |
| 72 | getStringFromName (Symbol str) = str |
| 73 | getStringFromName (Ident str) = str |
| 74 | |
| 75 | ------------------------------------------------------------------------------ |
| 76 | dropCommas :: String -> String |
| 77 | dropCommas = filter (/= ',') |
| 78 | |
| 79 | ------------------------------------------------------------------------------ |
| 80 | extractLambdaBody :: Exp -> String |
| 81 | extractLambdaBody (Lambda _ _ ast) = prettyPrint ast |
| 82 | extractLambdaBody _ = "[]" |
| 83 | |
| 84 | ------------------------------------------------------------------------------ |
| 85 | extractFreeVariables :: GenericQ [String] |
| 86 | extractFreeVariables ast = allNames (allVariables ast) \\ |
| 87 | allNames (allBindings ast) |
| 88 | |
| 89 | ------------------------------------------------------------------------------ |
| 90 | dropModuleVariableNames :: FilePath -> FilePath -> FilePath -> String -> [String] -> IO [String] |
| 91 | dropModuleVariableNames srcPath pkgConfigPath cabalFilePath buildTargetName = |
| 92 | filterM $ (liftM not) . isInModuleScope srcPath |
| 93 | pkgConfigPath |
| 94 | cabalFilePath |
| 95 | buildTargetName |
external-reality | a950a5f | 2014-03-04 22:15:27 -0500 | [diff] [blame^] | 96 | |
| 97 | |
| 98 | ------------------------------------------------------------------------------ |
| 99 | |
| 100 | trim :: [Char] -> [Char] |
| 101 | trim xs = dropSpaceTail "" $ dropWhile isSpace xs |
| 102 | |
| 103 | dropSpaceTail :: [Char] -> [Char] -> [Char] |
| 104 | dropSpaceTail _ "" = "" |
| 105 | dropSpaceTail maybeStuff (x:xs) |
| 106 | | isSpace x = dropSpaceTail (x:maybeStuff) xs |
| 107 | | null maybeStuff = x : dropSpaceTail "" xs |
| 108 | | otherwise = reverse maybeStuff ++ x : dropSpaceTail "" xs |
| 109 | |