{-# LANGUAGE CPP #-}
module Curry.Base.Span where
#if __GLASGOW_HASKELL__ >= 804
import Prelude hiding ((<>))
#endif
import System.FilePath
import Curry.Base.Position hiding (file)
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
instance HasPosition Span where
setPosition p NoSpan = Span "" p NoPos
setPosition p (Span f _ e) = Span f p e
getPosition NoSpan = NoPos
getPosition (Span _ p _) = p
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
combineSpans :: Span -> Span -> Span
combineSpans sp1 sp2 = Span f s e
where s = start sp1
e = end sp2
f = file sp1
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
addSpan :: Span -> (a, [Span]) -> (a, [Span])
addSpan sp (a, ss) = (a, sp:ss)
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