{-# LANGUAGE TemplateHaskell #-}

-- | The TH macro 'withLocTH' to manually annotate program points,
--   but you should always use the preprocessor if possible.

module Control.Monad.Loc.TH (withLocTH) where

import Prelude hiding (mod)
import Language.Haskell.TH.Syntax (qLocation, Loc(..), Q, Exp)
import Text.Printf
import Control.Monad.Loc

-- | 'withLocTH' is a convenient TH macro which expands to 'withLoc' @\<source location\>@
--    It should only be used when the MonadLoc preprocessor is not available.
--    Usage:
--
--    > f x = $withLocTH $ do
--    >          $withLocTH $ something
--    >          x < -$withLocTH $ something-else
--    >          ...
--
--   NOTE: unfortunately type signatures are necessary when using withLocTH

withLocTH :: Q Exp
withLocTH :: Q Exp
withLocTH = do
  Loc
loc <- Q Loc
forall (m :: * -> *). Quasi m => m Loc
qLocation
  let loc_msg :: String
loc_msg = Loc -> String
showLoc Loc
loc
  [| withLoc loc_msg |]

showLoc :: Loc -> String
showLoc :: Loc -> String
showLoc Loc{loc_module :: Loc -> String
loc_module=String
mod, loc_filename :: Loc -> String
loc_filename=String
filename, loc_start :: Loc -> CharPos
loc_start=CharPos
start} =
                     {- text package <> char '.' <> -}
                     String -> String -> String -> String -> String
forall r. PrintfType r => String -> r
printf String
"%s (%s). %s" String
mod String
filename (CharPos -> String
forall a. Show a => a -> String
show CharPos
start)