{-# LANGUAGE OverloadedStrings #-}

module BNFC.Backend.Common.Makefile where

import Prelude hiding ((<>))

import BNFC.Options (SharedOptions(..))
import BNFC.Backend.Base (mkfile, Backend)
import BNFC.PrettyPrint

-- | Creates a Makefile rule.
--
-- >>> mkRule "main" ["file1","file2"] ["do something"]
-- main : file1 file2
-- 	do something
-- <BLANKLINE>
--
-- >>> mkRule "main" ["program.exe"] []
-- main : program.exe
-- <BLANKLINE>
--
mkRule :: String   -- ^ The target name.
       -> [String] -- ^ Dependencies.
       -> [String] -- ^ Recipe.
       -> Doc
mkRule :: [Char] -> [[Char]] -> [[Char]] -> Doc
mkRule [Char]
target [[Char]]
deps [[Char]]
recipe = [Doc] -> Doc
vcat ([Doc] -> Doc) -> ([[Doc]] -> [Doc]) -> [[Doc]] -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[Doc]] -> [Doc]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Doc]] -> Doc) -> [[Doc]] -> Doc
forall a b. (a -> b) -> a -> b
$
    [ [ [Char] -> Doc
text [Char]
target Doc -> Doc -> Doc
<+> Doc
":" Doc -> Doc -> Doc
<+> [Doc] -> Doc
hsep (([Char] -> Doc) -> [[Char]] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map [Char] -> Doc
text [[Char]]
deps) ]
    , ([Char] -> Doc) -> [[Char]] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map ((Doc
"\t" Doc -> Doc -> Doc
<>) (Doc -> Doc) -> ([Char] -> Doc) -> [Char] -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> Doc
text) [[Char]]
recipe
    , [ Doc
"" ]
    ]

-- | Variable assignment.
--
-- >>> mkVar "FOO" "bar"
-- FOO=bar
--
mkVar :: String -> String -> Doc
mkVar :: [Char] -> [Char] -> Doc
mkVar [Char]
n [Char]
v = [Char] -> Doc
text [Char]
n Doc -> Doc -> Doc
<> Doc
"=" Doc -> Doc -> Doc
<> [Char] -> Doc
text [Char]
v

-- UNUSED:
-- -- | Variable referencing.
-- --
-- -- >>> mkRefVar "FOO"
-- -- ${FOO}
-- --
-- mkRefVar :: String -> Doc
-- mkRefVar m  = case m of
--     "" -> empty
--     _ -> text $ refVar m


-- | Variable referencing.
--
-- >>> refVar "FOO"
-- "${FOO}"
--
refVar :: String -> String
refVar :: [Char] -> [Char]
refVar [Char]
m = [Char]
"${" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
m [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"}"

-- | Create the Makefile file using the name specified in the option record.
--
mkMakefile :: SharedOptions -> (String -> Doc) -> Backend
mkMakefile :: SharedOptions -> ([Char] -> Doc) -> Backend
mkMakefile Options{make :: SharedOptions -> Maybe [Char]
make = Just [Char]
m } [Char] -> Doc
mkContent = [Char] -> ([Char] -> [Char]) -> Doc -> Backend
forall c.
FileContent c =>
[Char] -> ([Char] -> [Char]) -> c -> Backend
mkfile [Char]
m ([Char]
"## " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++) ([Char] -> Doc
mkContent [Char]
m)
mkMakefile Options{make :: SharedOptions -> Maybe [Char]
make = Maybe [Char]
Nothing} [Char] -> Doc
_         = () -> Backend
forall (m :: * -> *) a. Monad m => a -> m a
return ()