-- | This reworks 'Text.Megaparsec.Stream' to split interfaces.
-- See <https://hackage.haskell.org/package/megaparsec-9.0.1/docs/Text-Megaparsec-Stream.html Text.Megaparsec.Stream>.
module SimpleParser.Stream
  ( Stream (..)
  , TextualStream
  , PosStream (..)
  , Offset (..)
  , OffsetStream (..)
  , newOffsetStream
  , Line (..)
  , Col (..)
  , LinePos (..)
  , LinePosStream (..)
  , newLinePosStream
  , Span (..)
  , HasLinePos (..)
  ) where

import Data.Bifunctor (first, second)
import Data.ByteString (ByteString)
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as BSL
import Data.Kind (Type)
import Data.List (foldl')
import Data.Sequence (Seq (..))
import qualified Data.Sequence as Seq
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Text.Lazy as TL
import Data.Word (Word8)
import SimpleParser.Chunked (Chunked (..), TextualChunked (..))

-- | 'Stream' lets us peel off tokens and chunks for parsing with explicit state passing.
class Chunked (Chunk s) (Token s) => Stream s where
  type Chunk s :: Type
  type Token s :: Type

  streamTake1 :: s -> Maybe (Token s, s)

  streamTakeN :: Int -> s -> Maybe (Chunk s, s)
  streamTakeN = forall {t} {t} {a}.
(Ord t, Num t, Stream t, Chunked a (Token t)) =>
[Token t] -> t -> t -> Maybe (a, t)
go forall a. Monoid a => a
mempty where
    ret :: [token] -> b -> Maybe (a, b)
ret [token]
acc b
s = forall a. a -> Maybe a
Just (forall chunk token. Chunked chunk token => [token] -> chunk
revTokensToChunk [token]
acc, b
s)
    go :: [Token t] -> t -> t -> Maybe (a, t)
go ![Token t]
acc !t
n !t
s
      | t
n forall a. Ord a => a -> a -> Bool
<= t
0 = forall {a} {token} {b}.
Chunked a token =>
[token] -> b -> Maybe (a, b)
ret [Token t]
acc t
s
      | Bool
otherwise =
          case forall s. Stream s => s -> Maybe (Token s, s)
streamTake1 t
s of
            Maybe (Token t, t)
Nothing -> if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Token t]
acc then forall a. Maybe a
Nothing else forall {a} {token} {b}.
Chunked a token =>
[token] -> b -> Maybe (a, b)
ret [Token t]
acc t
s
            Just (Token t
t, t
s') -> [Token t] -> t -> t -> Maybe (a, t)
go (Token t
tforall a. a -> [a] -> [a]
:[Token t]
acc) (t
n forall a. Num a => a -> a -> a
- t
1) t
s'

  streamTakeWhile :: (Token s -> Bool) -> s -> (Chunk s, s)
  streamTakeWhile Token s -> Bool
p = [Token s] -> s -> (Chunk s, s)
go forall a. Monoid a => a
mempty where
    go :: [Token s] -> s -> (Chunk s, s)
go ![Token s]
acc !s
s =
      case forall s. Stream s => s -> Maybe (Token s, s)
streamTake1 s
s of
        Just (Token s
t, s
s') | Token s -> Bool
p Token s
t -> [Token s] -> s -> (Chunk s, s)
go (Token s
tforall a. a -> [a] -> [a]
:[Token s]
acc) s
s'
        Maybe (Token s, s)
_ -> (forall chunk token. Chunked chunk token => [token] -> chunk
revTokensToChunk [Token s]
acc, s
s)

  streamDropN :: Int -> s -> Maybe (Int, s)
  streamDropN Int
n = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first forall chunk token. Chunked chunk token => chunk -> Int
chunkLength) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s. Stream s => Int -> s -> Maybe (Chunk s, s)
streamTakeN Int
n

  streamDropWhile :: (Token s -> Bool) -> s -> (Int, s)
  streamDropWhile Token s -> Bool
pcate = forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first forall chunk token. Chunked chunk token => chunk -> Int
chunkLength forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s. Stream s => (Token s -> Bool) -> s -> (Chunk s, s)
streamTakeWhile Token s -> Bool
pcate

type TextualStream s = (Stream s, Token s ~ Char, TextualChunked (Chunk s))

instance Stream [a] where
  type Chunk [a] = [a]
  type Token [a] = a

  streamTake1 :: [a] -> Maybe (Token [a], [a])
streamTake1 = forall chunk token.
Chunked chunk token =>
chunk -> Maybe (token, chunk)
unconsChunk
  streamTakeN :: Int -> [a] -> Maybe (Chunk [a], [a])
streamTakeN Int
n [a]
s
    | Int
n forall a. Ord a => a -> a -> Bool
<= Int
0 = forall a. a -> Maybe a
Just ([], [a]
s)
    | forall (t :: * -> *) a. Foldable t => t a -> Bool
null [a]
s = forall a. Maybe a
Nothing
    | Bool
otherwise = forall a. a -> Maybe a
Just (forall a. Int -> [a] -> ([a], [a])
splitAt Int
n [a]
s)
  streamTakeWhile :: (Token [a] -> Bool) -> [a] -> (Chunk [a], [a])
streamTakeWhile = forall a. (a -> Bool) -> [a] -> ([a], [a])
span

instance Stream (Seq a) where
  type Chunk (Seq a) = Seq a
  type Token (Seq a) = a

  streamTake1 :: Seq a -> Maybe (Token (Seq a), Seq a)
streamTake1 = forall chunk token.
Chunked chunk token =>
chunk -> Maybe (token, chunk)
unconsChunk
  streamTakeN :: Int -> Seq a -> Maybe (Chunk (Seq a), Seq a)
streamTakeN Int
n Seq a
s
    | Int
n forall a. Ord a => a -> a -> Bool
<= Int
0 = forall a. a -> Maybe a
Just (forall a. Seq a
Seq.empty, Seq a
s)
    | forall a. Seq a -> Bool
Seq.null Seq a
s = forall a. Maybe a
Nothing
    | Bool
otherwise = forall a. a -> Maybe a
Just (forall a. Int -> Seq a -> (Seq a, Seq a)
Seq.splitAt Int
n Seq a
s)
  streamTakeWhile :: (Token (Seq a) -> Bool) -> Seq a -> (Chunk (Seq a), Seq a)
streamTakeWhile = forall a. (a -> Bool) -> Seq a -> (Seq a, Seq a)
Seq.spanl

  -- TODO(ejconlon) Specialize drops

instance Stream Text where
  type Chunk Text = Text
  type Token Text = Char

  streamTake1 :: Text -> Maybe (Token Text, Text)
streamTake1 = Text -> Maybe (Char, Text)
T.uncons
  streamTakeN :: Int -> Text -> Maybe (Chunk Text, Text)
streamTakeN Int
n Text
s
    | Int
n forall a. Ord a => a -> a -> Bool
<= Int
0 = forall a. a -> Maybe a
Just (Text
T.empty, Text
s)
    | Text -> Bool
T.null Text
s = forall a. Maybe a
Nothing
    | Bool
otherwise = forall a. a -> Maybe a
Just (Int -> Text -> (Text, Text)
T.splitAt Int
n Text
s)
  streamTakeWhile :: (Token Text -> Bool) -> Text -> (Chunk Text, Text)
streamTakeWhile = (Char -> Bool) -> Text -> (Text, Text)
T.span

  -- TODO(ejconlon) Specialize drops

instance Stream TL.Text where
  type Chunk TL.Text = TL.Text
  type Token TL.Text = Char

  streamTake1 :: Text -> Maybe (Token Text, Text)
streamTake1 = Text -> Maybe (Char, Text)
TL.uncons
  streamTakeN :: Int -> Text -> Maybe (Chunk Text, Text)
streamTakeN Int
n Text
s
    | Int
n forall a. Ord a => a -> a -> Bool
<= Int
0 = forall a. a -> Maybe a
Just (Text
TL.empty, Text
s)
    | Text -> Bool
TL.null Text
s = forall a. Maybe a
Nothing
    | Bool
otherwise = forall a. a -> Maybe a
Just (Int64 -> Text -> (Text, Text)
TL.splitAt (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n) Text
s)
  streamTakeWhile :: (Token Text -> Bool) -> Text -> (Chunk Text, Text)
streamTakeWhile = (Char -> Bool) -> Text -> (Text, Text)
TL.span

  -- TODO(ejconlon) Specialize drops

instance Stream ByteString where
  type Chunk ByteString = ByteString
  type Token ByteString = Word8

  streamTake1 :: ByteString -> Maybe (Token ByteString, ByteString)
streamTake1 = ByteString -> Maybe (Word8, ByteString)
BS.uncons
  streamTakeN :: Int -> ByteString -> Maybe (Chunk ByteString, ByteString)
streamTakeN Int
n ByteString
s
    | Int
n forall a. Ord a => a -> a -> Bool
<= Int
0 = forall a. a -> Maybe a
Just (ByteString
BS.empty, ByteString
s)
    | ByteString -> Bool
BS.null ByteString
s = forall a. Maybe a
Nothing
    | Bool
otherwise = forall a. a -> Maybe a
Just (Int -> ByteString -> (ByteString, ByteString)
BS.splitAt Int
n ByteString
s)
  streamTakeWhile :: (Token ByteString -> Bool)
-> ByteString -> (Chunk ByteString, ByteString)
streamTakeWhile = (Word8 -> Bool) -> ByteString -> (ByteString, ByteString)
BS.span

  -- TODO(ejconlon) Specialize drops

instance Stream BSL.ByteString where
  type Chunk BSL.ByteString = BSL.ByteString
  type Token BSL.ByteString = Word8

  streamTake1 :: ByteString -> Maybe (Token ByteString, ByteString)
streamTake1 = ByteString -> Maybe (Word8, ByteString)
BSL.uncons
  streamTakeN :: Int -> ByteString -> Maybe (Chunk ByteString, ByteString)
streamTakeN Int
n ByteString
s
    | Int
n forall a. Ord a => a -> a -> Bool
<= Int
0 = forall a. a -> Maybe a
Just (ByteString
BSL.empty, ByteString
s)
    | ByteString -> Bool
BSL.null ByteString
s = forall a. Maybe a
Nothing
    | Bool
otherwise = forall a. a -> Maybe a
Just (Int64 -> ByteString -> (ByteString, ByteString)
BSL.splitAt (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n) ByteString
s)
  streamTakeWhile :: (Token ByteString -> Bool)
-> ByteString -> (Chunk ByteString, ByteString)
streamTakeWhile = (Word8 -> Bool) -> ByteString -> (ByteString, ByteString)
BSL.span

  -- TODO(ejconlon) Specialize drops

-- | 'PosStream' adds position tracking to a 'Stream'.
class Stream s => PosStream s where
  type Pos s :: Type

  streamViewPos :: s -> Pos s

newtype Offset = Offset { Offset -> Int
unOffset :: Int }
  deriving newtype (Offset -> Offset -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Offset -> Offset -> Bool
$c/= :: Offset -> Offset -> Bool
== :: Offset -> Offset -> Bool
$c== :: Offset -> Offset -> Bool
Eq, Int -> Offset -> ShowS
[Offset] -> ShowS
Offset -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Offset] -> ShowS
$cshowList :: [Offset] -> ShowS
show :: Offset -> String
$cshow :: Offset -> String
showsPrec :: Int -> Offset -> ShowS
$cshowsPrec :: Int -> Offset -> ShowS
Show, Eq Offset
Offset -> Offset -> Bool
Offset -> Offset -> Ordering
Offset -> Offset -> Offset
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 :: Offset -> Offset -> Offset
$cmin :: Offset -> Offset -> Offset
max :: Offset -> Offset -> Offset
$cmax :: Offset -> Offset -> Offset
>= :: Offset -> Offset -> Bool
$c>= :: Offset -> Offset -> Bool
> :: Offset -> Offset -> Bool
$c> :: Offset -> Offset -> Bool
<= :: Offset -> Offset -> Bool
$c<= :: Offset -> Offset -> Bool
< :: Offset -> Offset -> Bool
$c< :: Offset -> Offset -> Bool
compare :: Offset -> Offset -> Ordering
$ccompare :: Offset -> Offset -> Ordering
Ord, Int -> Offset
Offset -> Int
Offset -> [Offset]
Offset -> Offset
Offset -> Offset -> [Offset]
Offset -> Offset -> Offset -> [Offset]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: Offset -> Offset -> Offset -> [Offset]
$cenumFromThenTo :: Offset -> Offset -> Offset -> [Offset]
enumFromTo :: Offset -> Offset -> [Offset]
$cenumFromTo :: Offset -> Offset -> [Offset]
enumFromThen :: Offset -> Offset -> [Offset]
$cenumFromThen :: Offset -> Offset -> [Offset]
enumFrom :: Offset -> [Offset]
$cenumFrom :: Offset -> [Offset]
fromEnum :: Offset -> Int
$cfromEnum :: Offset -> Int
toEnum :: Int -> Offset
$ctoEnum :: Int -> Offset
pred :: Offset -> Offset
$cpred :: Offset -> Offset
succ :: Offset -> Offset
$csucc :: Offset -> Offset
Enum, Integer -> Offset
Offset -> Offset
Offset -> Offset -> Offset
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> Offset
$cfromInteger :: Integer -> Offset
signum :: Offset -> Offset
$csignum :: Offset -> Offset
abs :: Offset -> Offset
$cabs :: Offset -> Offset
negate :: Offset -> Offset
$cnegate :: Offset -> Offset
* :: Offset -> Offset -> Offset
$c* :: Offset -> Offset -> Offset
- :: Offset -> Offset -> Offset
$c- :: Offset -> Offset -> Offset
+ :: Offset -> Offset -> Offset
$c+ :: Offset -> Offset -> Offset
Num, Num Offset
Ord Offset
Offset -> Rational
forall a. Num a -> Ord a -> (a -> Rational) -> Real a
toRational :: Offset -> Rational
$ctoRational :: Offset -> Rational
Real, Enum Offset
Real Offset
Offset -> Integer
Offset -> Offset -> (Offset, Offset)
Offset -> Offset -> Offset
forall a.
Real a
-> Enum a
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
toInteger :: Offset -> Integer
$ctoInteger :: Offset -> Integer
divMod :: Offset -> Offset -> (Offset, Offset)
$cdivMod :: Offset -> Offset -> (Offset, Offset)
quotRem :: Offset -> Offset -> (Offset, Offset)
$cquotRem :: Offset -> Offset -> (Offset, Offset)
mod :: Offset -> Offset -> Offset
$cmod :: Offset -> Offset -> Offset
div :: Offset -> Offset -> Offset
$cdiv :: Offset -> Offset -> Offset
rem :: Offset -> Offset -> Offset
$crem :: Offset -> Offset -> Offset
quot :: Offset -> Offset -> Offset
$cquot :: Offset -> Offset -> Offset
Integral)

-- | Stream wrapper that maintains an offset position.
data OffsetStream s = OffsetStream
  { forall s. OffsetStream s -> Offset
osOffset :: !Offset
  , forall s. OffsetStream s -> s
osState :: !s
  } deriving (OffsetStream s -> OffsetStream s -> Bool
forall s. Eq s => OffsetStream s -> OffsetStream s -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: OffsetStream s -> OffsetStream s -> Bool
$c/= :: forall s. Eq s => OffsetStream s -> OffsetStream s -> Bool
== :: OffsetStream s -> OffsetStream s -> Bool
$c== :: forall s. Eq s => OffsetStream s -> OffsetStream s -> Bool
Eq, Int -> OffsetStream s -> ShowS
forall s. Show s => Int -> OffsetStream s -> ShowS
forall s. Show s => [OffsetStream s] -> ShowS
forall s. Show s => OffsetStream s -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [OffsetStream s] -> ShowS
$cshowList :: forall s. Show s => [OffsetStream s] -> ShowS
show :: OffsetStream s -> String
$cshow :: forall s. Show s => OffsetStream s -> String
showsPrec :: Int -> OffsetStream s -> ShowS
$cshowsPrec :: forall s. Show s => Int -> OffsetStream s -> ShowS
Show, forall a b. a -> OffsetStream b -> OffsetStream a
forall a b. (a -> b) -> OffsetStream a -> OffsetStream b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> OffsetStream b -> OffsetStream a
$c<$ :: forall a b. a -> OffsetStream b -> OffsetStream a
fmap :: forall a b. (a -> b) -> OffsetStream a -> OffsetStream b
$cfmap :: forall a b. (a -> b) -> OffsetStream a -> OffsetStream b
Functor, forall a. Eq a => a -> OffsetStream a -> Bool
forall a. Num a => OffsetStream a -> a
forall a. Ord a => OffsetStream a -> a
forall m. Monoid m => OffsetStream m -> m
forall a. OffsetStream a -> Bool
forall a. OffsetStream a -> Int
forall a. OffsetStream a -> [a]
forall a. (a -> a -> a) -> OffsetStream a -> a
forall m a. Monoid m => (a -> m) -> OffsetStream a -> m
forall b a. (b -> a -> b) -> b -> OffsetStream a -> b
forall a b. (a -> b -> b) -> b -> OffsetStream a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: forall a. Num a => OffsetStream a -> a
$cproduct :: forall a. Num a => OffsetStream a -> a
sum :: forall a. Num a => OffsetStream a -> a
$csum :: forall a. Num a => OffsetStream a -> a
minimum :: forall a. Ord a => OffsetStream a -> a
$cminimum :: forall a. Ord a => OffsetStream a -> a
maximum :: forall a. Ord a => OffsetStream a -> a
$cmaximum :: forall a. Ord a => OffsetStream a -> a
elem :: forall a. Eq a => a -> OffsetStream a -> Bool
$celem :: forall a. Eq a => a -> OffsetStream a -> Bool
length :: forall a. OffsetStream a -> Int
$clength :: forall a. OffsetStream a -> Int
null :: forall a. OffsetStream a -> Bool
$cnull :: forall a. OffsetStream a -> Bool
toList :: forall a. OffsetStream a -> [a]
$ctoList :: forall a. OffsetStream a -> [a]
foldl1 :: forall a. (a -> a -> a) -> OffsetStream a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> OffsetStream a -> a
foldr1 :: forall a. (a -> a -> a) -> OffsetStream a -> a
$cfoldr1 :: forall a. (a -> a -> a) -> OffsetStream a -> a
foldl' :: forall b a. (b -> a -> b) -> b -> OffsetStream a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> OffsetStream a -> b
foldl :: forall b a. (b -> a -> b) -> b -> OffsetStream a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> OffsetStream a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> OffsetStream a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> OffsetStream a -> b
foldr :: forall a b. (a -> b -> b) -> b -> OffsetStream a -> b
$cfoldr :: forall a b. (a -> b -> b) -> b -> OffsetStream a -> b
foldMap' :: forall m a. Monoid m => (a -> m) -> OffsetStream a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> OffsetStream a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> OffsetStream a -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> OffsetStream a -> m
fold :: forall m. Monoid m => OffsetStream m -> m
$cfold :: forall m. Monoid m => OffsetStream m -> m
Foldable, Functor OffsetStream
Foldable OffsetStream
forall (t :: * -> *).
Functor t
-> Foldable t
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a.
Monad m =>
OffsetStream (m a) -> m (OffsetStream a)
forall (f :: * -> *) a.
Applicative f =>
OffsetStream (f a) -> f (OffsetStream a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> OffsetStream a -> m (OffsetStream b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> OffsetStream a -> f (OffsetStream b)
sequence :: forall (m :: * -> *) a.
Monad m =>
OffsetStream (m a) -> m (OffsetStream a)
$csequence :: forall (m :: * -> *) a.
Monad m =>
OffsetStream (m a) -> m (OffsetStream a)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> OffsetStream a -> m (OffsetStream b)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> OffsetStream a -> m (OffsetStream b)
sequenceA :: forall (f :: * -> *) a.
Applicative f =>
OffsetStream (f a) -> f (OffsetStream a)
$csequenceA :: forall (f :: * -> *) a.
Applicative f =>
OffsetStream (f a) -> f (OffsetStream a)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> OffsetStream a -> f (OffsetStream b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> OffsetStream a -> f (OffsetStream b)
Traversable)

instance Stream s => Stream (OffsetStream s) where
  type Chunk (OffsetStream s) = Chunk s
  type Token (OffsetStream s) = Token s

  streamTake1 :: OffsetStream s -> Maybe (Token (OffsetStream s), OffsetStream s)
streamTake1 (OffsetStream Offset
o s
s) = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second (forall s. Offset -> s -> OffsetStream s
OffsetStream (forall a. Enum a => a -> a
succ Offset
o))) (forall s. Stream s => s -> Maybe (Token s, s)
streamTake1 s
s)
  streamTakeN :: Int
-> OffsetStream s -> Maybe (Chunk (OffsetStream s), OffsetStream s)
streamTakeN Int
n (OffsetStream (Offset Int
x) s
s) = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Chunk s, s) -> (Chunk s, OffsetStream s)
go (forall s. Stream s => Int -> s -> Maybe (Chunk s, s)
streamTakeN Int
n s
s) where
    go :: (Chunk s, s) -> (Chunk s, OffsetStream s)
go (Chunk s
a, s
b) = (Chunk s
a, forall s. Offset -> s -> OffsetStream s
OffsetStream (Int -> Offset
Offset (Int
x forall a. Num a => a -> a -> a
+ forall chunk token. Chunked chunk token => chunk -> Int
chunkLength Chunk s
a)) s
b)
  streamTakeWhile :: (Token (OffsetStream s) -> Bool)
-> OffsetStream s -> (Chunk (OffsetStream s), OffsetStream s)
streamTakeWhile Token (OffsetStream s) -> Bool
pcate (OffsetStream (Offset Int
x) s
s) =
    let (Chunk s
a, s
b) = forall s. Stream s => (Token s -> Bool) -> s -> (Chunk s, s)
streamTakeWhile Token (OffsetStream s) -> Bool
pcate s
s
    in (Chunk s
a, forall s. Offset -> s -> OffsetStream s
OffsetStream (Int -> Offset
Offset (Int
x forall a. Num a => a -> a -> a
+ forall chunk token. Chunked chunk token => chunk -> Int
chunkLength Chunk s
a)) s
b)
  streamDropN :: Int -> OffsetStream s -> Maybe (Int, OffsetStream s)
streamDropN Int
n (OffsetStream (Offset Int
x) s
s) = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int, s) -> (Int, OffsetStream s)
go (forall s. Stream s => Int -> s -> Maybe (Int, s)
streamDropN Int
n s
s) where
    go :: (Int, s) -> (Int, OffsetStream s)
go (Int
m, s
b) = (Int
m, forall s. Offset -> s -> OffsetStream s
OffsetStream (Int -> Offset
Offset (Int
x forall a. Num a => a -> a -> a
+ Int
m)) s
b)
  streamDropWhile :: (Token (OffsetStream s) -> Bool)
-> OffsetStream s -> (Int, OffsetStream s)
streamDropWhile Token (OffsetStream s) -> Bool
pcate (OffsetStream (Offset Int
x) s
s) =
    let (Int
m, s
b) = forall s. Stream s => (Token s -> Bool) -> s -> (Int, s)
streamDropWhile Token (OffsetStream s) -> Bool
pcate s
s
    in (Int
m, forall s. Offset -> s -> OffsetStream s
OffsetStream (Int -> Offset
Offset (Int
x forall a. Num a => a -> a -> a
+ Int
m)) s
b)

instance Stream s => PosStream (OffsetStream s) where
  type Pos (OffsetStream s) = Offset

  streamViewPos :: OffsetStream s -> Pos (OffsetStream s)
streamViewPos (OffsetStream Offset
o s
_) = Offset
o

newOffsetStream :: s -> OffsetStream s
newOffsetStream :: forall s. s -> OffsetStream s
newOffsetStream = forall s. Offset -> s -> OffsetStream s
OffsetStream Offset
0

newtype Line = Line { Line -> Int
unLine :: Int }
  deriving newtype (Line -> Line -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Line -> Line -> Bool
$c/= :: Line -> Line -> Bool
== :: Line -> Line -> Bool
$c== :: Line -> Line -> Bool
Eq, Int -> Line -> ShowS
[Line] -> ShowS
Line -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Line] -> ShowS
$cshowList :: [Line] -> ShowS
show :: Line -> String
$cshow :: Line -> String
showsPrec :: Int -> Line -> ShowS
$cshowsPrec :: Int -> Line -> ShowS
Show, Eq Line
Line -> Line -> Bool
Line -> Line -> Ordering
Line -> Line -> Line
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 :: Line -> Line -> Line
$cmin :: Line -> Line -> Line
max :: Line -> Line -> Line
$cmax :: Line -> Line -> Line
>= :: Line -> Line -> Bool
$c>= :: Line -> Line -> Bool
> :: Line -> Line -> Bool
$c> :: Line -> Line -> Bool
<= :: Line -> Line -> Bool
$c<= :: Line -> Line -> Bool
< :: Line -> Line -> Bool
$c< :: Line -> Line -> Bool
compare :: Line -> Line -> Ordering
$ccompare :: Line -> Line -> Ordering
Ord, Int -> Line
Line -> Int
Line -> [Line]
Line -> Line
Line -> Line -> [Line]
Line -> Line -> Line -> [Line]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: Line -> Line -> Line -> [Line]
$cenumFromThenTo :: Line -> Line -> Line -> [Line]
enumFromTo :: Line -> Line -> [Line]
$cenumFromTo :: Line -> Line -> [Line]
enumFromThen :: Line -> Line -> [Line]
$cenumFromThen :: Line -> Line -> [Line]
enumFrom :: Line -> [Line]
$cenumFrom :: Line -> [Line]
fromEnum :: Line -> Int
$cfromEnum :: Line -> Int
toEnum :: Int -> Line
$ctoEnum :: Int -> Line
pred :: Line -> Line
$cpred :: Line -> Line
succ :: Line -> Line
$csucc :: Line -> Line
Enum, Integer -> Line
Line -> Line
Line -> Line -> Line
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> Line
$cfromInteger :: Integer -> Line
signum :: Line -> Line
$csignum :: Line -> Line
abs :: Line -> Line
$cabs :: Line -> Line
negate :: Line -> Line
$cnegate :: Line -> Line
* :: Line -> Line -> Line
$c* :: Line -> Line -> Line
- :: Line -> Line -> Line
$c- :: Line -> Line -> Line
+ :: Line -> Line -> Line
$c+ :: Line -> Line -> Line
Num, Num Line
Ord Line
Line -> Rational
forall a. Num a -> Ord a -> (a -> Rational) -> Real a
toRational :: Line -> Rational
$ctoRational :: Line -> Rational
Real, Enum Line
Real Line
Line -> Integer
Line -> Line -> (Line, Line)
Line -> Line -> Line
forall a.
Real a
-> Enum a
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
toInteger :: Line -> Integer
$ctoInteger :: Line -> Integer
divMod :: Line -> Line -> (Line, Line)
$cdivMod :: Line -> Line -> (Line, Line)
quotRem :: Line -> Line -> (Line, Line)
$cquotRem :: Line -> Line -> (Line, Line)
mod :: Line -> Line -> Line
$cmod :: Line -> Line -> Line
div :: Line -> Line -> Line
$cdiv :: Line -> Line -> Line
rem :: Line -> Line -> Line
$crem :: Line -> Line -> Line
quot :: Line -> Line -> Line
$cquot :: Line -> Line -> Line
Integral)

newtype Col = Col { Col -> Int
unCol :: Int }
  deriving newtype (Col -> Col -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Col -> Col -> Bool
$c/= :: Col -> Col -> Bool
== :: Col -> Col -> Bool
$c== :: Col -> Col -> Bool
Eq, Int -> Col -> ShowS
[Col] -> ShowS
Col -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Col] -> ShowS
$cshowList :: [Col] -> ShowS
show :: Col -> String
$cshow :: Col -> String
showsPrec :: Int -> Col -> ShowS
$cshowsPrec :: Int -> Col -> ShowS
Show, Eq Col
Col -> Col -> Bool
Col -> Col -> Ordering
Col -> Col -> Col
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 :: Col -> Col -> Col
$cmin :: Col -> Col -> Col
max :: Col -> Col -> Col
$cmax :: Col -> Col -> Col
>= :: Col -> Col -> Bool
$c>= :: Col -> Col -> Bool
> :: Col -> Col -> Bool
$c> :: Col -> Col -> Bool
<= :: Col -> Col -> Bool
$c<= :: Col -> Col -> Bool
< :: Col -> Col -> Bool
$c< :: Col -> Col -> Bool
compare :: Col -> Col -> Ordering
$ccompare :: Col -> Col -> Ordering
Ord, Int -> Col
Col -> Int
Col -> [Col]
Col -> Col
Col -> Col -> [Col]
Col -> Col -> Col -> [Col]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: Col -> Col -> Col -> [Col]
$cenumFromThenTo :: Col -> Col -> Col -> [Col]
enumFromTo :: Col -> Col -> [Col]
$cenumFromTo :: Col -> Col -> [Col]
enumFromThen :: Col -> Col -> [Col]
$cenumFromThen :: Col -> Col -> [Col]
enumFrom :: Col -> [Col]
$cenumFrom :: Col -> [Col]
fromEnum :: Col -> Int
$cfromEnum :: Col -> Int
toEnum :: Int -> Col
$ctoEnum :: Int -> Col
pred :: Col -> Col
$cpred :: Col -> Col
succ :: Col -> Col
$csucc :: Col -> Col
Enum, Integer -> Col
Col -> Col
Col -> Col -> Col
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> Col
$cfromInteger :: Integer -> Col
signum :: Col -> Col
$csignum :: Col -> Col
abs :: Col -> Col
$cabs :: Col -> Col
negate :: Col -> Col
$cnegate :: Col -> Col
* :: Col -> Col -> Col
$c* :: Col -> Col -> Col
- :: Col -> Col -> Col
$c- :: Col -> Col -> Col
+ :: Col -> Col -> Col
$c+ :: Col -> Col -> Col
Num, Num Col
Ord Col
Col -> Rational
forall a. Num a -> Ord a -> (a -> Rational) -> Real a
toRational :: Col -> Rational
$ctoRational :: Col -> Rational
Real, Enum Col
Real Col
Col -> Integer
Col -> Col -> (Col, Col)
Col -> Col -> Col
forall a.
Real a
-> Enum a
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
toInteger :: Col -> Integer
$ctoInteger :: Col -> Integer
divMod :: Col -> Col -> (Col, Col)
$cdivMod :: Col -> Col -> (Col, Col)
quotRem :: Col -> Col -> (Col, Col)
$cquotRem :: Col -> Col -> (Col, Col)
mod :: Col -> Col -> Col
$cmod :: Col -> Col -> Col
div :: Col -> Col -> Col
$cdiv :: Col -> Col -> Col
rem :: Col -> Col -> Col
$crem :: Col -> Col -> Col
quot :: Col -> Col -> Col
$cquot :: Col -> Col -> Col
Integral)

-- | A 0-based line/col position in a character-based stream.
data LinePos = LinePos
  { LinePos -> Offset
lpOffset :: !Offset
  , LinePos -> Line
lpLine :: !Line
  , LinePos -> Col
lpCol :: !Col
  } deriving (LinePos -> LinePos -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: LinePos -> LinePos -> Bool
$c/= :: LinePos -> LinePos -> Bool
== :: LinePos -> LinePos -> Bool
$c== :: LinePos -> LinePos -> Bool
Eq, Int -> LinePos -> ShowS
[LinePos] -> ShowS
LinePos -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [LinePos] -> ShowS
$cshowList :: [LinePos] -> ShowS
show :: LinePos -> String
$cshow :: LinePos -> String
showsPrec :: Int -> LinePos -> ShowS
$cshowsPrec :: Int -> LinePos -> ShowS
Show, Eq LinePos
LinePos -> LinePos -> Bool
LinePos -> LinePos -> Ordering
LinePos -> LinePos -> LinePos
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 :: LinePos -> LinePos -> LinePos
$cmin :: LinePos -> LinePos -> LinePos
max :: LinePos -> LinePos -> LinePos
$cmax :: LinePos -> LinePos -> LinePos
>= :: LinePos -> LinePos -> Bool
$c>= :: LinePos -> LinePos -> Bool
> :: LinePos -> LinePos -> Bool
$c> :: LinePos -> LinePos -> Bool
<= :: LinePos -> LinePos -> Bool
$c<= :: LinePos -> LinePos -> Bool
< :: LinePos -> LinePos -> Bool
$c< :: LinePos -> LinePos -> Bool
compare :: LinePos -> LinePos -> Ordering
$ccompare :: LinePos -> LinePos -> Ordering
Ord)

-- | The canonical initial position.
initLinePos :: LinePos
initLinePos :: LinePos
initLinePos = Offset -> Line -> Col -> LinePos
LinePos Offset
0 Line
0 Col
0

incrLinePosToken :: LinePos -> Char -> LinePos
incrLinePosToken :: LinePos -> Char -> LinePos
incrLinePosToken (LinePos Offset
o Line
l Col
c) Char
z
  | Char
z forall a. Eq a => a -> a -> Bool
== Char
'\n' = Offset -> Line -> Col -> LinePos
LinePos (forall a. Enum a => a -> a
succ Offset
o) (forall a. Enum a => a -> a
succ Line
l) Col
0
  | Bool
otherwise = Offset -> Line -> Col -> LinePos
LinePos (forall a. Enum a => a -> a
succ Offset
o) Line
l (forall a. Enum a => a -> a
succ Col
c)

incrLinePosChunk :: LinePos -> [Char] -> LinePos
incrLinePosChunk :: LinePos -> String -> LinePos
incrLinePosChunk = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' LinePos -> Char -> LinePos
incrLinePosToken

-- | Stream wrapper that maintains a line/col position.
data LinePosStream s = LinePosStream
  { forall s. LinePosStream s -> LinePos
lpsLinePos :: !LinePos
  , forall s. LinePosStream s -> s
lpsState :: !s
  } deriving (LinePosStream s -> LinePosStream s -> Bool
forall s. Eq s => LinePosStream s -> LinePosStream s -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: LinePosStream s -> LinePosStream s -> Bool
$c/= :: forall s. Eq s => LinePosStream s -> LinePosStream s -> Bool
== :: LinePosStream s -> LinePosStream s -> Bool
$c== :: forall s. Eq s => LinePosStream s -> LinePosStream s -> Bool
Eq, Int -> LinePosStream s -> ShowS
forall s. Show s => Int -> LinePosStream s -> ShowS
forall s. Show s => [LinePosStream s] -> ShowS
forall s. Show s => LinePosStream s -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [LinePosStream s] -> ShowS
$cshowList :: forall s. Show s => [LinePosStream s] -> ShowS
show :: LinePosStream s -> String
$cshow :: forall s. Show s => LinePosStream s -> String
showsPrec :: Int -> LinePosStream s -> ShowS
$cshowsPrec :: forall s. Show s => Int -> LinePosStream s -> ShowS
Show, forall a b. a -> LinePosStream b -> LinePosStream a
forall a b. (a -> b) -> LinePosStream a -> LinePosStream b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> LinePosStream b -> LinePosStream a
$c<$ :: forall a b. a -> LinePosStream b -> LinePosStream a
fmap :: forall a b. (a -> b) -> LinePosStream a -> LinePosStream b
$cfmap :: forall a b. (a -> b) -> LinePosStream a -> LinePosStream b
Functor, forall a. Eq a => a -> LinePosStream a -> Bool
forall a. Num a => LinePosStream a -> a
forall a. Ord a => LinePosStream a -> a
forall m. Monoid m => LinePosStream m -> m
forall a. LinePosStream a -> Bool
forall a. LinePosStream a -> Int
forall a. LinePosStream a -> [a]
forall a. (a -> a -> a) -> LinePosStream a -> a
forall m a. Monoid m => (a -> m) -> LinePosStream a -> m
forall b a. (b -> a -> b) -> b -> LinePosStream a -> b
forall a b. (a -> b -> b) -> b -> LinePosStream a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: forall a. Num a => LinePosStream a -> a
$cproduct :: forall a. Num a => LinePosStream a -> a
sum :: forall a. Num a => LinePosStream a -> a
$csum :: forall a. Num a => LinePosStream a -> a
minimum :: forall a. Ord a => LinePosStream a -> a
$cminimum :: forall a. Ord a => LinePosStream a -> a
maximum :: forall a. Ord a => LinePosStream a -> a
$cmaximum :: forall a. Ord a => LinePosStream a -> a
elem :: forall a. Eq a => a -> LinePosStream a -> Bool
$celem :: forall a. Eq a => a -> LinePosStream a -> Bool
length :: forall a. LinePosStream a -> Int
$clength :: forall a. LinePosStream a -> Int
null :: forall a. LinePosStream a -> Bool
$cnull :: forall a. LinePosStream a -> Bool
toList :: forall a. LinePosStream a -> [a]
$ctoList :: forall a. LinePosStream a -> [a]
foldl1 :: forall a. (a -> a -> a) -> LinePosStream a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> LinePosStream a -> a
foldr1 :: forall a. (a -> a -> a) -> LinePosStream a -> a
$cfoldr1 :: forall a. (a -> a -> a) -> LinePosStream a -> a
foldl' :: forall b a. (b -> a -> b) -> b -> LinePosStream a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> LinePosStream a -> b
foldl :: forall b a. (b -> a -> b) -> b -> LinePosStream a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> LinePosStream a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> LinePosStream a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> LinePosStream a -> b
foldr :: forall a b. (a -> b -> b) -> b -> LinePosStream a -> b
$cfoldr :: forall a b. (a -> b -> b) -> b -> LinePosStream a -> b
foldMap' :: forall m a. Monoid m => (a -> m) -> LinePosStream a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> LinePosStream a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> LinePosStream a -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> LinePosStream a -> m
fold :: forall m. Monoid m => LinePosStream m -> m
$cfold :: forall m. Monoid m => LinePosStream m -> m
Foldable, Functor LinePosStream
Foldable LinePosStream
forall (t :: * -> *).
Functor t
-> Foldable t
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a.
Monad m =>
LinePosStream (m a) -> m (LinePosStream a)
forall (f :: * -> *) a.
Applicative f =>
LinePosStream (f a) -> f (LinePosStream a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> LinePosStream a -> m (LinePosStream b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> LinePosStream a -> f (LinePosStream b)
sequence :: forall (m :: * -> *) a.
Monad m =>
LinePosStream (m a) -> m (LinePosStream a)
$csequence :: forall (m :: * -> *) a.
Monad m =>
LinePosStream (m a) -> m (LinePosStream a)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> LinePosStream a -> m (LinePosStream b)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> LinePosStream a -> m (LinePosStream b)
sequenceA :: forall (f :: * -> *) a.
Applicative f =>
LinePosStream (f a) -> f (LinePosStream a)
$csequenceA :: forall (f :: * -> *) a.
Applicative f =>
LinePosStream (f a) -> f (LinePosStream a)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> LinePosStream a -> f (LinePosStream b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> LinePosStream a -> f (LinePosStream b)
Traversable)

instance (Stream s, Token s ~ Char) => Stream (LinePosStream s) where
  type Chunk (LinePosStream s) = Chunk s
  type Token (LinePosStream s) = Token s

  streamTake1 :: LinePosStream s -> Maybe (Token (LinePosStream s), LinePosStream s)
streamTake1 (LinePosStream LinePos
p s
s) = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(Char
a, s
b) -> (Char
a, forall s. LinePos -> s -> LinePosStream s
LinePosStream (LinePos -> Char -> LinePos
incrLinePosToken LinePos
p Char
a) s
b)) (forall s. Stream s => s -> Maybe (Token s, s)
streamTake1 s
s)
  streamTakeN :: Int
-> LinePosStream s
-> Maybe (Chunk (LinePosStream s), LinePosStream s)
streamTakeN Int
n (LinePosStream LinePos
p s
s) = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Chunk s, s) -> (Chunk s, LinePosStream s)
go (forall s. Stream s => Int -> s -> Maybe (Chunk s, s)
streamTakeN Int
n s
s) where
    go :: (Chunk s, s) -> (Chunk s, LinePosStream s)
go (Chunk s
a, s
b) = (Chunk s
a, forall s. LinePos -> s -> LinePosStream s
LinePosStream (LinePos -> String -> LinePos
incrLinePosChunk LinePos
p (forall chunk token. Chunked chunk token => chunk -> [token]
chunkToTokens Chunk s
a)) s
b)
  streamTakeWhile :: (Token (LinePosStream s) -> Bool)
-> LinePosStream s -> (Chunk (LinePosStream s), LinePosStream s)
streamTakeWhile Token (LinePosStream s) -> Bool
pcate (LinePosStream LinePos
p s
s) =
    let (Chunk s
a, s
b) = forall s. Stream s => (Token s -> Bool) -> s -> (Chunk s, s)
streamTakeWhile Token (LinePosStream s) -> Bool
pcate s
s
    in (Chunk s
a, forall s. LinePos -> s -> LinePosStream s
LinePosStream (LinePos -> String -> LinePos
incrLinePosChunk LinePos
p (forall chunk token. Chunked chunk token => chunk -> [token]
chunkToTokens Chunk s
a)) s
b)

  -- Drops can't be specialized because we need to examine each character for newlines.

instance (Stream s, Token s ~ Char) => PosStream (LinePosStream s) where
  type Pos (LinePosStream s) = LinePos

  streamViewPos :: LinePosStream s -> Pos (LinePosStream s)
streamViewPos (LinePosStream LinePos
p s
_) = LinePos
p

newLinePosStream :: s -> LinePosStream s
newLinePosStream :: forall s. s -> LinePosStream s
newLinePosStream = forall s. LinePos -> s -> LinePosStream s
LinePosStream LinePos
initLinePos

-- | A range between two positions.
data Span p = Span
  { forall p. Span p -> p
spanStart :: !p
  , forall p. Span p -> p
spanEnd :: !p
  } deriving (Span p -> Span p -> Bool
forall p. Eq p => Span p -> Span p -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Span p -> Span p -> Bool
$c/= :: forall p. Eq p => Span p -> Span p -> Bool
== :: Span p -> Span p -> Bool
$c== :: forall p. Eq p => Span p -> Span p -> Bool
Eq, Int -> Span p -> ShowS
forall p. Show p => Int -> Span p -> ShowS
forall p. Show p => [Span p] -> ShowS
forall p. Show p => Span p -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Span p] -> ShowS
$cshowList :: forall p. Show p => [Span p] -> ShowS
show :: Span p -> String
$cshow :: forall p. Show p => Span p -> String
showsPrec :: Int -> Span p -> ShowS
$cshowsPrec :: forall p. Show p => Int -> Span p -> ShowS
Show, Span p -> Span p -> Bool
Span p -> Span p -> Ordering
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
forall {p}. Ord p => Eq (Span p)
forall p. Ord p => Span p -> Span p -> Bool
forall p. Ord p => Span p -> Span p -> Ordering
forall p. Ord p => Span p -> Span p -> Span p
min :: Span p -> Span p -> Span p
$cmin :: forall p. Ord p => Span p -> Span p -> Span p
max :: Span p -> Span p -> Span p
$cmax :: forall p. Ord p => Span p -> Span p -> Span p
>= :: Span p -> Span p -> Bool
$c>= :: forall p. Ord p => Span p -> Span p -> Bool
> :: Span p -> Span p -> Bool
$c> :: forall p. Ord p => Span p -> Span p -> Bool
<= :: Span p -> Span p -> Bool
$c<= :: forall p. Ord p => Span p -> Span p -> Bool
< :: Span p -> Span p -> Bool
$c< :: forall p. Ord p => Span p -> Span p -> Bool
compare :: Span p -> Span p -> Ordering
$ccompare :: forall p. Ord p => Span p -> Span p -> Ordering
Ord)

-- | Allows projections into (Line, Col) for more exotic stream positions.
class HasLinePos p where
  viewLine :: p -> Line
  viewCol :: p -> Col

instance HasLinePos LinePos where
  viewLine :: LinePos -> Line
viewLine = LinePos -> Line
lpLine
  viewCol :: LinePos -> Col
viewCol = LinePos -> Col
lpCol