{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE DeriveGeneric #-}
module Language.Fortran.Util.Position where
import Data.Data
import Text.PrettyPrint.GenericPretty
import Text.PrettyPrint
import Data.Binary
import Language.Fortran.Util.SecondParameter
class Loc a where
getPos :: a -> Position
data Position = Position
{ posAbsoluteOffset :: Int
, posColumn :: Int
, posLine :: Int
, filePath :: String
, posPragmaOffset :: Maybe (Int, String)
} deriving (Eq, Ord, Data, Typeable, Generic)
instance Binary Position
instance Show Position where
show (Position _ c l _ _) = show l ++ ':' : show c
initPosition :: Position
initPosition = Position
{ posAbsoluteOffset = 0
, posColumn = 1
, posLine = 1
, filePath = ""
, posPragmaOffset = Nothing
}
lineCol :: Position -> (Int, Int)
lineCol p = (fromIntegral $ posLine p, fromIntegral $ posColumn p)
apparentLineCol :: Position -> (Int, Int)
apparentLineCol (Position _ c l _ (Just (o, _))) = (l + o, c)
apparentLineCol (Position _ c l _ _) = (l, c)
apparentFilePath :: Position -> String
apparentFilePath p | Just (_, f) <- posPragmaOffset p = f
| otherwise = filePath p
data SrcSpan = SrcSpan Position Position deriving (Eq, Ord, Typeable, Data, Generic)
instance Binary SrcSpan
instance Show SrcSpan where
show (SrcSpan s1 s2)= '(' : show s1 ++ ")-(" ++ show s2 ++ ")"
instance Out SrcSpan where
doc s = text $ show s
docPrec _ = doc
columnDistance :: SrcSpan -> Int
columnDistance (SrcSpan (Position _ c1 _ _ _) (Position _ c2 _ _ _)) = c2 - c1
lineDistance :: SrcSpan -> Int
lineDistance (SrcSpan (Position _ _ l1 _ _) (Position _ _ l2 _ _)) = l2 - l1
spannedLines :: SrcSpan -> [Int]
spannedLines (SrcSpan (Position _ _ l1 _ _) (Position _ _ l2 _ _)) = [l1..l2]
initSrcSpan :: SrcSpan
initSrcSpan = SrcSpan initPosition initPosition
instance Spanned SrcSpan where
getSpan s = s
setSpan _ _ = undefined
class Spanned a where
getSpan :: a -> SrcSpan
setSpan :: SrcSpan -> a -> a
default getSpan :: (SecondParameter a SrcSpan) => a -> SrcSpan
getSpan = getSecondParameter
default setSpan :: (SecondParameter a SrcSpan) => SrcSpan -> a -> a
setSpan = setSecondParameter