module Development.Make.Type where
import Control.Monad
data Makefile = Makefile [Stmt] deriving Show
data Stmt
= Rule
{targets :: Expr
,prerequisites :: Expr
,commands :: [Command]
}
| Assign
{name :: String
,assign :: Assign
,expr :: Expr
}
deriving Show
data Assign = Equals | ColonEquals | PlusEquals | QuestionEquals deriving Show
data Expr = Apply String [Expr]
| Concat [Expr]
| Var String
| Lit String
deriving Show
data Command = Expr Expr | String := Expr deriving Show
descendExpr :: (Expr -> Expr) -> Expr -> Expr
descendExpr f (Apply a b) = Apply a $ map f b
descendExpr f (Concat xs) = Concat $ map f xs
descendExpr f x = x
descendExprM :: Monad m => (Expr -> m Expr) -> Expr -> m Expr
descendExprM f (Apply a b) = Apply a `liftM` mapM f b
descendExprM f (Concat xs) = Concat `liftM` mapM f xs
descendExprM f x = return x
transformExpr :: (Expr -> Expr) -> Expr -> Expr
transformExpr f = f . descendExpr (transformExpr f)
simplifyExpr :: Expr -> Expr
simplifyExpr = transformExpr f
where
f (Concat xs) = case g xs of
[] -> Lit ""
[x] -> x
xs -> Concat xs
f x = x
g (Concat x:xs) = g $ x ++ xs
g (Lit x:Lit y:xs) = g $ Lit (x ++ y) : xs
g (x:xs) = x : g xs
g [] = []