{-# LANGUAGE OverloadedStrings #-}

module BNFC.Backend.Common.Makefile where

import BNFC.Prelude

import Data.String (fromString)

import Prettyprinter

-- | 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 :: String -> [String] -> String -> Doc ()
mkRule String
target [String]
dependencies String
recipe =
  if String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
recipe
  then String -> Doc ()
forall a. IsString a => String -> a
fromString String
target Doc () -> Doc () -> Doc ()
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc ()
forall ann. Doc ann
colon Doc () -> Doc () -> Doc ()
forall ann. Doc ann -> Doc ann -> Doc ann
<+> [Doc ()] -> Doc ()
forall ann. [Doc ann] -> Doc ann
hsep (String -> Doc ()
forall a. IsString a => String -> a
fromString (String -> Doc ()) -> [String] -> [Doc ()]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [String]
dependencies)
  else [Doc ()] -> Doc ()
forall ann. [Doc ann] -> Doc ann
vsep
    [ String -> Doc ()
forall a. IsString a => String -> a
fromString String
target Doc () -> Doc () -> Doc ()
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc ()
forall ann. Doc ann
colon Doc () -> Doc () -> Doc ()
forall ann. Doc ann -> Doc ann -> Doc ann
<+> [Doc ()] -> Doc ()
forall ann. [Doc ann] -> Doc ann
hsep (String -> Doc ()
forall a. IsString a => String -> a
fromString (String -> Doc ()) -> [String] -> [Doc ()]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [String]
dependencies)
    , Doc ()
"\t" Doc () -> Doc () -> Doc ()
forall a. Semigroup a => a -> a -> a
<> String -> Doc ()
forall a. IsString a => String -> a
fromString String
recipe
    ]

-- | Variable assignment.
--
-- >>> mkVar "FOO" "bar"
-- FOO=bar
--
mkVar :: String -> String -> Doc ()
mkVar :: String -> String -> Doc ()
mkVar String
n String
v = String -> Doc ()
forall a. IsString a => String -> a
fromString String
n Doc () -> Doc () -> Doc ()
forall a. Semigroup a => a -> a -> a
<> Doc ()
"=" Doc () -> Doc () -> Doc ()
forall a. Semigroup a => a -> a -> a
<> String -> Doc ()
forall a. IsString a => String -> a
fromString String
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 -> Doc ()
refVar :: String -> Doc ()
refVar String
m = Doc ()
"${" Doc () -> Doc () -> Doc ()
forall ann. Doc ann -> Doc ann -> Doc ann
<+> String -> Doc ()
forall a. IsString a => String -> a
fromString String
m Doc () -> Doc () -> Doc ()
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc ()
"}"