module Text.Loc
( HasLoc(..)
, LocLens(..)
, Span(..)
, SpannedLoc(..)
, locStart
, locEnd
, spanOf
, startOf
, endOf
, SpannedLens(..)
, lStart
, lEnd
, lSpanOf
, lEndOf
, lStartOf
, Located(..)
, LineCol(..)
, nextLine
, nextCol
, LineColLoc(..)
, locLine
, locCol
, lineColOf
, lineOf
, colOf
, LineColLens(..)
, lLine
, lCol
, lLineColOf
, lLineOf
, lColOf
, SrcLoc(..)
, srcOf
, SrcLens(..)
, lSrcOf
, InSrc(..)
, FromLoc(..)
, fromOf
, FromLens(..)
, lFromOf
, Nested(..)
) where
import GHC.Generics (Generic)
import Data.Typeable (Typeable)
import Data.Foldable (Foldable)
import Data.Traversable (Traversable)
import Data.Hashable (Hashable(..))
import Data.Word (Word)
class HasLoc α where
type LocOf α
locOf ∷ α → LocOf α
class HasLoc α ⇒ LocLens α where
lLocOf ∷ Functor f ⇒ (LocOf α → f (LocOf α)) → α → f α
data Span l = Span l l
deriving (Typeable, Generic, Show, Read, Eq, Ord,
Functor, Foldable, Traversable)
instance Hashable l ⇒ Hashable (Span l) where
hashWithSalt salt (Span s e) = hashWithSalt salt (s, e)
instance HasLoc (Span l) where
type LocOf (Span l) = Span l
locOf = id
instance LocLens (Span l) where
lLocOf = id
class SpannedLoc l where
type SpanLoc l
locSpan ∷ l → Span (SpanLoc l)
instance SpannedLoc (Span l) where
type SpanLoc (Span l) = l
locSpan = id
locStart ∷ SpannedLoc l ⇒ l → SpanLoc l
locStart l = let Span s _ = locSpan l in s
locEnd ∷ SpannedLoc l ⇒ l → SpanLoc l
locEnd l = let Span _ e = locSpan l in e
spanOf ∷ (HasLoc α, SpannedLoc (LocOf α)) ⇒ α → Span (SpanLoc (LocOf α))
spanOf = locSpan . locOf
startOf ∷ (HasLoc α, SpannedLoc (LocOf α)) ⇒ α → SpanLoc (LocOf α)
startOf = locStart . locOf
endOf ∷ (HasLoc α, SpannedLoc (LocOf α)) ⇒ α → SpanLoc (LocOf α)
endOf = locEnd . locOf
class SpannedLoc l ⇒ SpannedLens l where
lSpan ∷ Functor f ⇒ (Span (SpanLoc l) → f (Span (SpanLoc l))) → l → f l
instance SpannedLens (Span l) where
lSpan = id
lStart ∷ (Functor f, SpannedLens l) ⇒ (SpanLoc l → f (SpanLoc l)) → l → f l
lStart f = lSpan (\(Span s e) → fmap (flip Span e) (f s))
lEnd ∷ (Functor f, SpannedLens l) ⇒ (SpanLoc l → f (SpanLoc l)) → l → f l
lEnd f = lSpan (\(Span s e) → fmap (Span s) (f e))
lSpanOf ∷ (Functor f, LocLens α, SpannedLens (LocOf α))
⇒ (Span (SpanLoc (LocOf α)) → f (Span (SpanLoc (LocOf α)))) → α → f α
lSpanOf = lLocOf . lSpan
lStartOf ∷ (Functor f, LocLens α, SpannedLens (LocOf α))
⇒ (SpanLoc (LocOf α) → f (SpanLoc (LocOf α))) → α → f α
lStartOf = lLocOf . lStart
lEndOf ∷ (Functor f, LocLens α, SpannedLens (LocOf α))
⇒ (SpanLoc (LocOf α) → f (SpanLoc (LocOf α))) → α → f α
lEndOf = lLocOf . lEnd
data Located l α = Located { locAt ∷ l
, locVal ∷ α }
deriving (Typeable, Generic, Show, Read,
Functor, Foldable, Traversable)
instance (Hashable l, Hashable α) ⇒ Hashable (Located l α) where
hashWithSalt salt (Located l a) = hashWithSalt salt (l, a)
instance HasLoc (Located l α) where
type LocOf (Located l α) = l
locOf = locAt
instance LocLens (Located l α) where
lLocOf f (Located l a) = fmap (flip Located a) (f l)
data LineCol = LineCol !Word !Word
deriving (Typeable, Generic, Show, Read, Eq, Ord, Bounded)
instance Hashable LineCol where
hashWithSalt salt (LineCol l c) = hashWithSalt salt (l, c)
instance HasLoc LineCol where
type LocOf LineCol = LineCol
locOf = id
nextLine ∷ LineCol → LineCol
nextLine (LineCol l _) = LineCol (l + 1) 1
nextCol ∷ LineCol → LineCol
nextCol (LineCol l c) = LineCol l (c + 1)
class LineColLoc l where
locLineCol ∷ l → LineCol
instance LineColLoc LineCol where
locLineCol = id
locLine ∷ LineColLoc l ⇒ l → Word
locLine l = let LineCol ln _ = locLineCol l in ln
locCol ∷ LineColLoc l ⇒ l → Word
locCol l = let LineCol _ c = locLineCol l in c
lineColOf ∷ (HasLoc α, LineColLoc (LocOf α)) ⇒ α → LineCol
lineColOf = locLineCol . locOf
lineOf ∷ (HasLoc α, LineColLoc (LocOf α)) ⇒ α → Word
lineOf = locLine . lineColOf
colOf ∷ (HasLoc α, LineColLoc (LocOf α)) ⇒ α → Word
colOf = locCol . lineColOf
class LineColLens l where
lLineCol ∷ Functor f ⇒ (LineCol → f LineCol) → l → f l
instance LineColLens LineCol where
lLineCol = id
lLine ∷ (Functor f, LineColLens l) ⇒ (Word → f Word) → l → f l
lLine f = lLineCol (\(LineCol l c) → fmap (flip LineCol c) (f l))
lCol ∷ (Functor f, LineColLens l) ⇒ (Word → f Word) → l → f l
lCol f = lLineCol (\(LineCol l c) → fmap (LineCol l) (f c))
lLineColOf ∷ (Functor f, LocLens α, LineColLens (LocOf α))
⇒ (LineCol → f LineCol) → α → f α
lLineColOf = lLocOf . lLineCol
lLineOf ∷ (Functor f, LocLens α, LineColLens (LocOf α))
⇒ (Word → f Word) → α → f α
lLineOf = lLocOf . lLine
lColOf ∷ (Functor f, LocLens α, LineColLens (LocOf α))
⇒ (Word → f Word) → α → f α
lColOf = lLocOf . lCol
class SrcLoc l where
type LocSrc l
locSrc ∷ l → LocSrc l
srcOf ∷ (HasLoc α, SrcLoc (LocOf α)) ⇒ α → LocSrc (LocOf α)
srcOf = locSrc . locOf
class SrcLoc l ⇒ SrcLens l where
lSrc ∷ Functor f ⇒ (LocSrc l → f (LocSrc l)) → l → f l
lSrcOf ∷ (Functor f, LocLens α, SrcLens (LocOf α))
⇒ (LocSrc (LocOf α) → f (LocSrc (LocOf α))) → α → f α
lSrcOf = lLocOf . lSrc
data InSrc s l = InSrc { srcSrc ∷ s
, srcLoc ∷ l }
deriving (Typeable, Generic, Show, Read, Eq, Ord)
instance (Hashable s, Hashable l) ⇒ Hashable (InSrc s l) where
hashWithSalt salt (InSrc s l) = hashWithSalt salt (s, l)
instance HasLoc (InSrc s l) where
type LocOf (InSrc s l) = InSrc s l
locOf = id
instance LocLens (InSrc s l) where
lLocOf = id
instance SpannedLoc l ⇒ SpannedLoc (InSrc s l) where
type SpanLoc (InSrc s l) = InSrc s (SpanLoc l)
locSpan (InSrc s l) = fmap (InSrc s) (locSpan l)
instance SpannedLens l ⇒ SpannedLens (InSrc s l) where
lSpan f (InSrc s l) =
fmap (InSrc s) (lSpan (fmap (fmap srcLoc) . f . fmap (InSrc s)) l)
instance LineColLoc l ⇒ LineColLoc (InSrc s l) where
locLineCol = locLineCol . srcLoc
instance LineColLens l ⇒ LineColLens (InSrc s l) where
lLineCol f (InSrc s l) = fmap (InSrc s) (lLineCol f l)
instance SrcLoc (InSrc s l) where
type LocSrc (InSrc s l) = s
locSrc = srcSrc
instance SrcLens (InSrc s l) where
lSrc f (InSrc s l) = fmap (flip InSrc l) (f s)
class FromLoc l where
type LocFrom l
locFrom ∷ l → LocFrom l
instance FromLoc l ⇒ FromLoc (InSrc s l) where
type LocFrom (InSrc s l) = LocFrom l
locFrom = locFrom . srcLoc
instance FromLens l ⇒ FromLens (InSrc s l) where
lFrom f (InSrc s l) = fmap (InSrc s) (lFrom f l)
fromOf ∷ (HasLoc α, FromLoc (LocOf α)) ⇒ α → LocFrom (LocOf α)
fromOf = locFrom . locOf
class FromLoc l ⇒ FromLens l where
lFrom ∷ Functor f ⇒ (LocFrom l → f (LocFrom l)) → l → f l
lFromOf ∷ (Functor f, LocLens α, FromLens (LocOf α))
⇒ (LocFrom (LocOf α) → f (LocFrom (LocOf α))) → α → f α
lFromOf = lLocOf . lFrom
data Nested l p = Nested { nestedLoc ∷ l
, nestedFrom ∷ p }
deriving (Typeable, Generic, Show, Read)
instance (Hashable l, Hashable p) ⇒ Hashable (Nested l p) where
hashWithSalt salt (Nested l p) = hashWithSalt salt (l, p)
instance HasLoc (Nested l p) where
type LocOf (Nested l p) = Nested l p
locOf = id
instance LocLens (Nested l p) where
lLocOf = id
instance SpannedLoc l ⇒ SpannedLoc (Nested l p) where
type SpanLoc (Nested l p) = Nested (SpanLoc l) p
locSpan (Nested l p) = fmap (flip Nested p) (locSpan l)
instance SpannedLens l ⇒ SpannedLens (Nested l p) where
lSpan f (Nested l p) =
fmap (flip Nested p)
(lSpan (fmap (fmap nestedLoc) . f . fmap (flip Nested p)) l)
instance LineColLoc l ⇒ LineColLoc (Nested l p) where
locLineCol = locLineCol . nestedLoc
instance LineColLens l ⇒ LineColLens (Nested l p) where
lLineCol f (Nested l p) = fmap (flip Nested p) (lLineCol f l)
instance SrcLoc l ⇒ SrcLoc (Nested l p) where
type LocSrc (Nested l p) = LocSrc l
locSrc = locSrc . nestedLoc
instance SrcLens l ⇒ SrcLens (Nested l p) where
lSrc f (Nested l p) = fmap (flip Nested p) (lSrc f l)
instance FromLoc (Nested l p) where
type LocFrom (Nested l p) = p
locFrom = nestedFrom
instance FromLens (Nested l p) where
lFrom f (Nested l p) = fmap (Nested l) (f p)