module Curry.Base.Span where
import System.FilePath
import Curry.Base.Position
import Curry.Base.Pretty
data Span
= Span
{ file :: FilePath
, start :: Position
, end :: Position
}
| NoSpan
deriving (Eq, Ord, Read, Show)
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)
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) n = Span fn (incr s n) (incr e n)
incrSpan sp _ = sp
span2Pos :: Span -> Position
span2Pos (Span _ p _) = p
span2Pos NoSpan = NoPos
tabSpan :: Span -> Span
tabSpan (Span fn s e) = Span fn (tab s) (tab e)
tabSpan sp = sp
nlSpan :: Span -> Span
nlSpan (Span fn s e) = Span fn (nl s) (nl e)
nlSpan sp = sp
type Distance = (Int, Int)
setDistance :: Span -> Distance -> Span
setDistance (Span fn p _) d = Span fn p (p `moveBy` d)
setDistance s _ = s
moveBy :: Position -> Distance -> Position
moveBy (Position fn l c) (ld, cd) = Position fn (l + ld) (c + cd)
moveBy p _ = p