{-# LANGUAGE DeriveDataTypeable, DeriveGeneric #-}
module Language.Haskell.Exts.SrcLoc where
import Data.Data
import GHC.Generics (Generic)
showInt :: Int -> String
showInt i | i < 0 = "(" ++ show i ++ ")"
showInt i = show i
data SrcLoc = SrcLoc
{ srcFilename :: String
, srcLine :: Int
, srcColumn :: Int
}
deriving (Eq,Ord,Typeable,Data,Generic)
instance Show SrcLoc where
showsPrec n (SrcLoc fn sl sc) =
showParen (n >= 11) $
showString $ "SrcLoc " ++ show fn ++ " " ++ unwords (map showInt [sl,sc])
noLoc :: SrcLoc
noLoc = SrcLoc "" (-1) (-1)
data SrcSpan = SrcSpan
{ srcSpanFilename :: String
, srcSpanStartLine :: Int
, srcSpanStartColumn :: Int
, srcSpanEndLine :: Int
, srcSpanEndColumn :: Int
}
deriving (Eq,Ord,Typeable,Data,Generic)
instance Show SrcSpan where
showsPrec n (SrcSpan fn sl sc el ec) =
showParen (n >= 11) $
showString $ "SrcSpan " ++ show fn ++ " " ++ unwords (map showInt [sl,sc,el,ec])
srcSpanStart :: SrcSpan -> (Int,Int)
srcSpanStart x = (srcSpanStartLine x, srcSpanStartColumn x)
srcSpanEnd :: SrcSpan -> (Int,Int)
srcSpanEnd x = (srcSpanEndLine x, srcSpanEndColumn x)
mkSrcSpan :: SrcLoc -> SrcLoc -> SrcSpan
mkSrcSpan (SrcLoc fn sl sc) (SrcLoc _ el ec) = SrcSpan fn sl sc el ec
mergeSrcSpan :: SrcSpan -> SrcSpan -> SrcSpan
mergeSrcSpan (SrcSpan fn sl1 sc1 el1 ec1) (SrcSpan _ sl2 sc2 el2 ec2) =
let (sl,sc) = min (sl1,sc1) (sl2,sc2)
(el,ec) = max (el1,ec1) (el2,ec2)
in SrcSpan fn sl sc el ec
isNullSpan :: SrcSpan -> Bool
isNullSpan ss = spanSize ss == (0,0)
spanSize :: SrcSpan -> (Int, Int)
spanSize ss = (srcSpanEndLine ss - srcSpanStartLine ss, max 0 (srcSpanEndColumn ss - srcSpanStartColumn ss))
data Loc a = Loc
{ loc :: SrcSpan
, unLoc :: a
}
deriving (Eq,Ord,Show,Generic)
data SrcSpanInfo = SrcSpanInfo
{ srcInfoSpan :: SrcSpan
, srcInfoPoints :: [SrcSpan]
}
deriving (Eq,Ord,Typeable,Data,Generic)
instance Show SrcSpanInfo where
showsPrec n (SrcSpanInfo s pts) = showParen (n >= 11) . showString $
"SrcSpanInfo {srcInfoSpan = " ++ show s ++ ", srcInfoPoints = " ++ show pts ++ "}"
noInfoSpan :: SrcSpan -> SrcSpanInfo
noInfoSpan ss = SrcSpanInfo ss []
noSrcSpan :: SrcSpanInfo
noSrcSpan = noInfoSpan (mkSrcSpan noLoc noLoc)
infoSpan :: SrcSpan -> [SrcSpan] -> SrcSpanInfo
infoSpan = SrcSpanInfo
combSpanInfo :: SrcSpanInfo -> SrcSpanInfo -> SrcSpanInfo
combSpanInfo s1 s2 = SrcSpanInfo
(mergeSrcSpan (srcInfoSpan s1) (srcInfoSpan s2))
[]
combSpanMaybe :: SrcSpanInfo -> Maybe SrcSpanInfo -> SrcSpanInfo
combSpanMaybe s1 Nothing = s1
combSpanMaybe s1 (Just s2) = SrcSpanInfo
(mergeSrcSpan (srcInfoSpan s1) (srcInfoSpan s2))
(srcInfoPoints s1 ++ srcInfoPoints s2)
(<++>) :: SrcSpanInfo -> SrcSpanInfo -> SrcSpanInfo
(<++>) = combSpanInfo
(<+?>) :: SrcSpanInfo -> Maybe SrcSpanInfo -> SrcSpanInfo
a <+?> b = case b of {Nothing -> a; Just b' -> a <++> b'}
(<?+>) :: Maybe SrcSpanInfo -> SrcSpanInfo -> SrcSpanInfo
a <?+> b = case a of {Nothing -> b; Just a' -> a' <++> b}
(<**) :: SrcSpanInfo -> [SrcSpan] -> SrcSpanInfo
ss@(SrcSpanInfo {srcInfoPoints = ps}) <** xs = ss {srcInfoPoints = ps ++ xs}
(<^^>) :: SrcSpan -> SrcSpan -> SrcSpanInfo
a <^^> b = noInfoSpan (mergeSrcSpan a b)
infixl 6 <^^>
infixl 5 <++>
infixl 4 <**, <+?>, <?+>
class SrcInfo si where
toSrcInfo :: SrcLoc -> [SrcSpan] -> SrcLoc -> si
fromSrcInfo :: SrcSpanInfo -> si
getPointLoc :: si -> SrcLoc
fileName :: si -> String
startLine :: si -> Int
startColumn :: si -> Int
getPointLoc si = SrcLoc (fileName si) (startLine si) (startColumn si)
instance SrcInfo SrcLoc where
toSrcInfo s _ _ = s
fromSrcInfo si = SrcLoc (fileName si) (startLine si) (startColumn si)
fileName = srcFilename
startLine = srcLine
startColumn = srcColumn
instance SrcInfo SrcSpan where
toSrcInfo st _ end = mkSrcSpan st end
fromSrcInfo = srcInfoSpan
fileName = srcSpanFilename
startLine = srcSpanStartLine
startColumn = srcSpanStartColumn
instance SrcInfo SrcSpanInfo where
toSrcInfo st pts end = SrcSpanInfo (mkSrcSpan st end) pts
fromSrcInfo = id
fileName = fileName . srcInfoSpan
startLine = startLine . srcInfoSpan
startColumn = startColumn . srcInfoSpan