module Curry.Base.Span where
import Data.Generics (Data, Typeable)
import System.FilePath
import Curry.Base.Position hiding (astRef)
import Curry.Base.Pretty
data Span
= Span
{ file :: FilePath
, start :: Position
, end :: Position
, astRef :: SrcRef
}
| ASTSpan
{ astRef :: SrcRef
}
| NoSpan
deriving (Eq, Ord, Read, Show, Data, Typeable)
instance SrcRefOf Span where
srcRefOf NoSpan = noRef
srcRefOf x = astRef x
instance Pretty Span where
pPrint = ppSpan
showSpan :: Span -> String
showSpan = show . ppSpan
ppSpan :: Span -> Doc
ppSpan s@(Span f _ _ _)
| null f = startEnd
| otherwise = text (normalise f) <> comma <+> startEnd
where startEnd = ppPositions s
ppSpan _ = empty
ppPositions :: Span -> Doc
ppPositions (Span _ s e _) = text "startPos:" <+> ppLine s <> comma
<+> text "endPos:" <+> ppLine e
ppPositions _ = empty
fstSpan :: FilePath -> Span
fstSpan fn = Span fn (first fn) (first fn) noRef
startCol :: Span -> Int
startCol (Span _ p _ _) = column p
startCol _ = 0
nextSpan :: Span -> Span
nextSpan sp = incrSpan sp 1
incrSpan :: Span -> Int -> Span
incrSpan (Span fn s e ref) n = Span fn (incr s n) (incr e n) ref
incrSpan sp _ = sp
span2Pos :: Span -> Position
span2Pos (Span _ p _ _) = p
span2Pos (ASTSpan ref) = AST ref
span2Pos NoSpan = NoPos
tabSpan :: Span -> Span
tabSpan (Span fn s e ref) = Span fn (tab s) (tab e) ref
tabSpan sp = sp
nlSpan :: Span -> Span
nlSpan (Span fn s e ref) = Span fn (nl s) (nl e) ref
nlSpan sp = sp
type Distance = (Int, Int)
setDistance :: Span -> Distance -> Span
setDistance (Span fn p _ ref) d = Span fn p (p `moveBy` d) ref
setDistance s _ = s
moveBy :: Position -> Distance -> Position
moveBy (Position fn l c ref) (ld, cd) = Position fn (l + ld) (c + cd) ref
moveBy p _ = p