{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveFoldable #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveTraversable #-}
module What4.ProgramLoc
( Position(..)
, sourcePos
, startOfFile
, ppNoFileName
, Posd(..)
, ProgramLoc
, mkProgramLoc
, initializationLoc
, plFunction
, plSourceLoc
, HasProgramLoc(..)
) where
import Control.DeepSeq
import Control.Lens
import Data.Text (Text)
import qualified Data.Text as Text
import Data.Word
import Numeric (showHex)
import qualified Text.PrettyPrint.ANSI.Leijen as PP
import What4.FunctionName
data Position
= SourcePos !Text !Int !Int
| BinaryPos !Text !Word64
| OtherPos !Text
| InternalPos
deriving (Eq, Ord)
instance Show Position where
show p = show (PP.pretty p)
instance NFData Position where
rnf (SourcePos t l c) = rnf (t,l,c)
rnf (BinaryPos t a) = rnf (t,a)
rnf (OtherPos t) = rnf t
rnf InternalPos = ()
sourcePos :: FilePath -> Int -> Int -> Position
sourcePos p l c = SourcePos (Text.pack p) l c
startOfFile :: FilePath -> Position
startOfFile path = sourcePos path 1 0
instance PP.Pretty Position where
pretty (SourcePos path l c) =
PP.text (Text.unpack path)
PP.<> PP.colon PP.<> PP.int l
PP.<> PP.colon PP.<> PP.int c
pretty (BinaryPos path addr) =
PP.text (Text.unpack path) PP.<> PP.colon PP.<>
PP.text "0x" PP.<> PP.text (showHex addr "")
pretty (OtherPos txt) = PP.text (Text.unpack txt)
pretty InternalPos = PP.text "internal"
ppNoFileName :: Position -> PP.Doc
ppNoFileName (SourcePos _ l c) =
PP.int l PP.<> PP.colon PP.<> PP.int c
ppNoFileName (BinaryPos _ addr) =
PP.text (showHex addr "")
ppNoFileName (OtherPos msg) =
PP.text (Text.unpack msg)
ppNoFileName InternalPos = PP.text "internal"
data Posd v = Posd { pos :: !Position
, pos_val :: !v
}
deriving (Functor, Foldable, Traversable, Show, Eq)
instance NFData v => NFData (Posd v) where
rnf p = rnf (pos p, pos_val p)
data ProgramLoc
= ProgramLoc { plFunction :: {-# UNPACK #-} !FunctionName
, plSourceLoc :: !Position
}
deriving (Show, Eq, Ord)
initializationLoc :: ProgramLoc
initializationLoc = ProgramLoc startFunctionName (startOfFile "")
mkProgramLoc :: FunctionName
-> Position
-> ProgramLoc
mkProgramLoc = ProgramLoc
class HasProgramLoc v where
programLoc :: Lens' v ProgramLoc