{-# 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
{ Span -> FilePath
file :: FilePath
, Span -> Position
start :: Position
, Span -> Position
end :: Position
}
| NoSpan
deriving (Span -> Span -> Bool
(Span -> Span -> Bool) -> (Span -> Span -> Bool) -> Eq Span
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Span -> Span -> Bool
$c/= :: Span -> Span -> Bool
== :: Span -> Span -> Bool
$c== :: Span -> Span -> Bool
Eq, Eq Span
Eq Span =>
(Span -> Span -> Ordering)
-> (Span -> Span -> Bool)
-> (Span -> Span -> Bool)
-> (Span -> Span -> Bool)
-> (Span -> Span -> Bool)
-> (Span -> Span -> Span)
-> (Span -> Span -> Span)
-> Ord Span
Span -> Span -> Bool
Span -> Span -> Ordering
Span -> Span -> Span
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Span -> Span -> Span
$cmin :: Span -> Span -> Span
max :: Span -> Span -> Span
$cmax :: Span -> Span -> Span
>= :: Span -> Span -> Bool
$c>= :: Span -> Span -> Bool
> :: Span -> Span -> Bool
$c> :: Span -> Span -> Bool
<= :: Span -> Span -> Bool
$c<= :: Span -> Span -> Bool
< :: Span -> Span -> Bool
$c< :: Span -> Span -> Bool
compare :: Span -> Span -> Ordering
$ccompare :: Span -> Span -> Ordering
$cp1Ord :: Eq Span
Ord, ReadPrec [Span]
ReadPrec Span
Int -> ReadS Span
ReadS [Span]
(Int -> ReadS Span)
-> ReadS [Span] -> ReadPrec Span -> ReadPrec [Span] -> Read Span
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Span]
$creadListPrec :: ReadPrec [Span]
readPrec :: ReadPrec Span
$creadPrec :: ReadPrec Span
readList :: ReadS [Span]
$creadList :: ReadS [Span]
readsPrec :: Int -> ReadS Span
$creadsPrec :: Int -> ReadS Span
Read, Int -> Span -> ShowS
[Span] -> ShowS
Span -> FilePath
(Int -> Span -> ShowS)
-> (Span -> FilePath) -> ([Span] -> ShowS) -> Show Span
forall a.
(Int -> a -> ShowS) -> (a -> FilePath) -> ([a] -> ShowS) -> Show a
showList :: [Span] -> ShowS
$cshowList :: [Span] -> ShowS
show :: Span -> FilePath
$cshow :: Span -> FilePath
showsPrec :: Int -> Span -> ShowS
$cshowsPrec :: Int -> Span -> ShowS
Show)
instance Pretty Span where
pPrint :: Span -> Doc
pPrint = Span -> Doc
ppSpan
instance HasPosition Span where
setPosition :: Position -> Span -> Span
setPosition p :: Position
p NoSpan = FilePath -> Position -> Position -> Span
Span "" Position
p Position
NoPos
setPosition p :: Position
p (Span f :: FilePath
f _ e :: Position
e) = FilePath -> Position -> Position -> Span
Span FilePath
f Position
p Position
e
getPosition :: Span -> Position
getPosition NoSpan = Position
NoPos
getPosition (Span _ p :: Position
p _) = Position
p
showSpan :: Span -> String
showSpan :: Span -> FilePath
showSpan = Doc -> FilePath
forall a. Show a => a -> FilePath
show (Doc -> FilePath) -> (Span -> Doc) -> Span -> FilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Span -> Doc
ppSpan
ppSpan :: Span -> Doc
ppSpan :: Span -> Doc
ppSpan s :: Span
s@(Span f :: FilePath
f _ _)
| FilePath -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null FilePath
f = Doc
startEnd
| Bool
otherwise = FilePath -> Doc
text (ShowS
normalise FilePath
f) Doc -> Doc -> Doc
<> Doc
comma Doc -> Doc -> Doc
<+> Doc
startEnd
where startEnd :: Doc
startEnd = Span -> Doc
ppPositions Span
s
ppSpan _ = Doc
empty
ppPositions :: Span -> Doc
ppPositions :: Span -> Doc
ppPositions (Span _ s :: Position
s e :: Position
e) = FilePath -> Doc
text "startPos:" Doc -> Doc -> Doc
<+> Position -> Doc
ppLine Position
s Doc -> Doc -> Doc
<> Doc
comma
Doc -> Doc -> Doc
<+> FilePath -> Doc
text "endPos:" Doc -> Doc -> Doc
<+> Position -> Doc
ppLine Position
e
ppPositions _ = Doc
empty
fstSpan :: FilePath -> Span
fstSpan :: FilePath -> Span
fstSpan fn :: FilePath
fn = FilePath -> Position -> Position -> Span
Span FilePath
fn (FilePath -> Position
first FilePath
fn) (FilePath -> Position
first FilePath
fn)
startCol :: Span -> Int
startCol :: Span -> Int
startCol (Span _ p :: Position
p _) = Position -> Int
column Position
p
startCol _ = 0
nextSpan :: Span -> Span
nextSpan :: Span -> Span
nextSpan sp :: Span
sp = Span -> Int -> Span
incrSpan Span
sp 1
incrSpan :: Span -> Int -> Span
incrSpan :: Span -> Int -> Span
incrSpan (Span fn :: FilePath
fn s :: Position
s e :: Position
e) n :: Int
n = FilePath -> Position -> Position -> Span
Span FilePath
fn (Position -> Int -> Position
incr Position
s Int
n) (Position -> Int -> Position
incr Position
e Int
n)
incrSpan sp :: Span
sp _ = Span
sp
span2Pos :: Span -> Position
span2Pos :: Span -> Position
span2Pos (Span _ p :: Position
p _) = Position
p
span2Pos NoSpan = Position
NoPos
combineSpans :: Span -> Span -> Span
combineSpans :: Span -> Span -> Span
combineSpans sp1 :: Span
sp1 sp2 :: Span
sp2 = FilePath -> Position -> Position -> Span
Span FilePath
f Position
s Position
e
where s :: Position
s = Span -> Position
start Span
sp1
e :: Position
e = Span -> Position
end Span
sp2
f :: FilePath
f = Span -> FilePath
file Span
sp1
tabSpan :: Span -> Span
tabSpan :: Span -> Span
tabSpan (Span fn :: FilePath
fn s :: Position
s e :: Position
e) = FilePath -> Position -> Position -> Span
Span FilePath
fn (Position -> Position
tab Position
s) (Position -> Position
tab Position
e)
tabSpan sp :: Span
sp = Span
sp
nlSpan :: Span -> Span
nlSpan :: Span -> Span
nlSpan (Span fn :: FilePath
fn s :: Position
s e :: Position
e) = FilePath -> Position -> Position -> Span
Span FilePath
fn (Position -> Position
nl Position
s) (Position -> Position
nl Position
e)
nlSpan sp :: Span
sp = Span
sp
addSpan :: Span -> (a, [Span]) -> (a, [Span])
addSpan :: Span -> (a, [Span]) -> (a, [Span])
addSpan sp :: Span
sp (a :: a
a, ss :: [Span]
ss) = (a
a, Span
spSpan -> [Span] -> [Span]
forall a. a -> [a] -> [a]
:[Span]
ss)
type Distance = (Int, Int)
setDistance :: Span -> Distance -> Span
setDistance :: Span -> Distance -> Span
setDistance (Span fn :: FilePath
fn p :: Position
p _) d :: Distance
d = FilePath -> Position -> Position -> Span
Span FilePath
fn Position
p (Position
p Position -> Distance -> Position
`moveBy` Distance
d)
setDistance s :: Span
s _ = Span
s
moveBy :: Position -> Distance -> Position
moveBy :: Position -> Distance -> Position
moveBy (Position fn :: FilePath
fn l :: Int
l c :: Int
c) (ld :: Int
ld, cd :: Int
cd) = FilePath -> Int -> Int -> Position
Position FilePath
fn (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
ld) (Int
c Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
cd)
moveBy p :: Position
p _ = Position
p