-- | 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 (..)
  , defaultStreamDropN
  , defaultStreamDropWhile
  , TextualStream
  , PosStream (..)
  , Offset (..)
  , OffsetStream (..)
  , newOffsetStream
  , Line (..)
  , Col (..)
  , LinePos (..)
  , LinePosStream (..)
  , newLinePosStream
  , Span (..)
  ) 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 family Chunk s :: Type
  type family Token s :: Type

  streamTake1 :: s -> Maybe (Token s, s)
  streamTakeN :: Int -> s -> Maybe (Chunk s, s)
  streamTakeWhile :: (Token s -> Bool) -> s -> (Chunk s, s)

  streamDropN :: Int -> s -> Maybe (Int, s)
  streamDropN = Int -> s -> Maybe (Int, s)
forall s. Stream s => Int -> s -> Maybe (Int, s)
defaultStreamDropN

  streamDropWhile :: (Token s -> Bool) -> s -> (Int, s)
  streamDropWhile = (Token s -> Bool) -> s -> (Int, s)
forall s. Stream s => (Token s -> Bool) -> s -> (Int, s)
defaultStreamDropWhile

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

defaultStreamDropWhile :: Stream s => (Token s -> Bool) -> s -> (Int, s)
defaultStreamDropWhile :: (Token s -> Bool) -> s -> (Int, s)
defaultStreamDropWhile Token s -> Bool
pcate = (Chunk s -> Int) -> (Chunk s, s) -> (Int, s)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first Chunk s -> Int
forall chunk token. Chunked chunk token => chunk -> Int
chunkLength ((Chunk s, s) -> (Int, s)) -> (s -> (Chunk s, s)) -> s -> (Int, s)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Token s -> Bool) -> s -> (Chunk s, s)
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 instance Chunk [a] = [a]
  type instance Token [a] = a

  streamTake1 :: [a] -> Maybe (Token [a], [a])
streamTake1 = [a] -> Maybe (Token [a], [a])
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 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 = ([a], [a]) -> Maybe ([a], [a])
forall a. a -> Maybe a
Just ([], [a]
s)
    | [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [a]
s = Maybe (Chunk [a], [a])
forall a. Maybe a
Nothing
    | Bool
otherwise = ([a], [a]) -> Maybe ([a], [a])
forall a. a -> Maybe a
Just (Int -> [a] -> ([a], [a])
forall a. Int -> [a] -> ([a], [a])
splitAt Int
n [a]
s)
  streamTakeWhile :: (Token [a] -> Bool) -> [a] -> (Chunk [a], [a])
streamTakeWhile = (Token [a] -> Bool) -> [a] -> (Chunk [a], [a])
forall a. (a -> Bool) -> [a] -> ([a], [a])
span

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

  streamTake1 :: Seq a -> Maybe (Token (Seq a), Seq a)
streamTake1 = Seq a -> Maybe (Token (Seq a), Seq a)
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 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 = (Seq a, Seq a) -> Maybe (Seq a, Seq a)
forall a. a -> Maybe a
Just (Seq a
forall a. Seq a
Seq.empty, Seq a
s)
    | Seq a -> Bool
forall a. Seq a -> Bool
Seq.null Seq a
s = Maybe (Chunk (Seq a), Seq a)
forall a. Maybe a
Nothing
    | Bool
otherwise = (Seq a, Seq a) -> Maybe (Seq a, Seq a)
forall a. a -> Maybe a
Just (Int -> Seq a -> (Seq a, Seq a)
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 = (Token (Seq a) -> Bool) -> Seq a -> (Chunk (Seq a), Seq a)
forall a. (a -> Bool) -> Seq a -> (Seq a, Seq a)
Seq.spanl

  -- TODO(ejconlon) Specialize drops

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

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

  -- TODO(ejconlon) Specialize drops

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

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

  -- TODO(ejconlon) Specialize drops

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

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

  -- TODO(ejconlon) Specialize drops

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

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

  -- TODO(ejconlon) Specialize drops

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

  streamViewPos :: s -> Pos s

newtype Offset = Offset { Offset -> Int
unOffset :: Int }
  deriving newtype (Offset -> Offset -> Bool
(Offset -> Offset -> Bool)
-> (Offset -> Offset -> Bool) -> Eq Offset
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
(Int -> Offset -> ShowS)
-> (Offset -> String) -> ([Offset] -> ShowS) -> Show Offset
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
Eq Offset
-> (Offset -> Offset -> Ordering)
-> (Offset -> Offset -> Bool)
-> (Offset -> Offset -> Bool)
-> (Offset -> Offset -> Bool)
-> (Offset -> Offset -> Bool)
-> (Offset -> Offset -> Offset)
-> (Offset -> Offset -> Offset)
-> Ord 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
$cp1Ord :: Eq Offset
Ord, Int -> Offset
Offset -> Int
Offset -> [Offset]
Offset -> Offset
Offset -> Offset -> [Offset]
Offset -> Offset -> Offset -> [Offset]
(Offset -> Offset)
-> (Offset -> Offset)
-> (Int -> Offset)
-> (Offset -> Int)
-> (Offset -> [Offset])
-> (Offset -> Offset -> [Offset])
-> (Offset -> Offset -> [Offset])
-> (Offset -> Offset -> Offset -> [Offset])
-> Enum 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
(Offset -> Offset -> Offset)
-> (Offset -> Offset -> Offset)
-> (Offset -> Offset -> Offset)
-> (Offset -> Offset)
-> (Offset -> Offset)
-> (Offset -> Offset)
-> (Integer -> Offset)
-> Num 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
Num Offset -> Ord Offset -> (Offset -> Rational) -> Real Offset
Offset -> Rational
forall a. Num a -> Ord a -> (a -> Rational) -> Real a
toRational :: Offset -> Rational
$ctoRational :: Offset -> Rational
$cp2Real :: Ord Offset
$cp1Real :: Num Offset
Real, Enum Offset
Real Offset
Real Offset
-> Enum Offset
-> (Offset -> Offset -> Offset)
-> (Offset -> Offset -> Offset)
-> (Offset -> Offset -> Offset)
-> (Offset -> Offset -> Offset)
-> (Offset -> Offset -> (Offset, Offset))
-> (Offset -> Offset -> (Offset, Offset))
-> (Offset -> Integer)
-> Integral 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
$cp2Integral :: Enum Offset
$cp1Integral :: Real Offset
Integral)

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

instance Stream s => Stream (OffsetStream s) where
  type instance Chunk (OffsetStream s) = Chunk s
  type instance Token (OffsetStream s) = Token s
  streamTake1 :: OffsetStream s -> Maybe (Token (OffsetStream s), OffsetStream s)
streamTake1 (OffsetStream Offset
o s
s) = ((Token s, s) -> (Token s, OffsetStream s))
-> Maybe (Token s, s) -> Maybe (Token s, OffsetStream s)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((s -> OffsetStream s) -> (Token s, s) -> (Token s, OffsetStream s)
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second (Offset -> s -> OffsetStream s
forall s. Offset -> s -> OffsetStream s
OffsetStream (Offset -> Offset
forall a. Enum a => a -> a
succ Offset
o))) (s -> Maybe (Token s, s)
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) = ((Chunk s, s) -> (Chunk s, OffsetStream s))
-> Maybe (Chunk s, s) -> Maybe (Chunk s, OffsetStream s)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Chunk s, s) -> (Chunk s, OffsetStream s)
go (Int -> s -> Maybe (Chunk s, s)
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, Offset -> s -> OffsetStream s
forall s. Offset -> s -> OffsetStream s
OffsetStream (Int -> Offset
Offset (Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Chunk s -> Int
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) = (Token s -> Bool) -> s -> (Chunk s, s)
forall s. Stream s => (Token s -> Bool) -> s -> (Chunk s, s)
streamTakeWhile Token s -> Bool
Token (OffsetStream s) -> Bool
pcate s
s
    in (Chunk s
Chunk (OffsetStream s)
a, Offset -> s -> OffsetStream s
forall s. Offset -> s -> OffsetStream s
OffsetStream (Int -> Offset
Offset (Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Chunk s -> Int
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) = ((Int, s) -> (Int, OffsetStream s))
-> Maybe (Int, s) -> Maybe (Int, OffsetStream s)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int, s) -> (Int, OffsetStream s)
go (Int -> s -> Maybe (Int, s)
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, Offset -> s -> OffsetStream s
forall s. Offset -> s -> OffsetStream s
OffsetStream (Int -> Offset
Offset (Int
x Int -> Int -> Int
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) = (Token s -> Bool) -> s -> (Int, s)
forall s. Stream s => (Token s -> Bool) -> s -> (Int, s)
streamDropWhile Token s -> Bool
Token (OffsetStream s) -> Bool
pcate s
s
    in (Int
m, Offset -> s -> OffsetStream s
forall s. Offset -> s -> OffsetStream s
OffsetStream (Int -> Offset
Offset (Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
m)) s
b)

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

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

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

newtype Line = Line { Line -> Int
unLine :: Int }
  deriving newtype (Line -> Line -> Bool
(Line -> Line -> Bool) -> (Line -> Line -> Bool) -> Eq Line
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
(Int -> Line -> ShowS)
-> (Line -> String) -> ([Line] -> ShowS) -> Show Line
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
Eq Line
-> (Line -> Line -> Ordering)
-> (Line -> Line -> Bool)
-> (Line -> Line -> Bool)
-> (Line -> Line -> Bool)
-> (Line -> Line -> Bool)
-> (Line -> Line -> Line)
-> (Line -> Line -> Line)
-> Ord 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
$cp1Ord :: Eq Line
Ord, Int -> Line
Line -> Int
Line -> [Line]
Line -> Line
Line -> Line -> [Line]
Line -> Line -> Line -> [Line]
(Line -> Line)
-> (Line -> Line)
-> (Int -> Line)
-> (Line -> Int)
-> (Line -> [Line])
-> (Line -> Line -> [Line])
-> (Line -> Line -> [Line])
-> (Line -> Line -> Line -> [Line])
-> Enum 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
(Line -> Line -> Line)
-> (Line -> Line -> Line)
-> (Line -> Line -> Line)
-> (Line -> Line)
-> (Line -> Line)
-> (Line -> Line)
-> (Integer -> Line)
-> Num 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
Num Line -> Ord Line -> (Line -> Rational) -> Real Line
Line -> Rational
forall a. Num a -> Ord a -> (a -> Rational) -> Real a
toRational :: Line -> Rational
$ctoRational :: Line -> Rational
$cp2Real :: Ord Line
$cp1Real :: Num Line
Real, Enum Line
Real Line
Real Line
-> Enum Line
-> (Line -> Line -> Line)
-> (Line -> Line -> Line)
-> (Line -> Line -> Line)
-> (Line -> Line -> Line)
-> (Line -> Line -> (Line, Line))
-> (Line -> Line -> (Line, Line))
-> (Line -> Integer)
-> Integral 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
$cp2Integral :: Enum Line
$cp1Integral :: Real Line
Integral)

newtype Col = Col { Col -> Int
unCol :: Int }
  deriving newtype (Col -> Col -> Bool
(Col -> Col -> Bool) -> (Col -> Col -> Bool) -> Eq Col
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
(Int -> Col -> ShowS)
-> (Col -> String) -> ([Col] -> ShowS) -> Show Col
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
Eq Col
-> (Col -> Col -> Ordering)
-> (Col -> Col -> Bool)
-> (Col -> Col -> Bool)
-> (Col -> Col -> Bool)
-> (Col -> Col -> Bool)
-> (Col -> Col -> Col)
-> (Col -> Col -> Col)
-> Ord 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
$cp1Ord :: Eq Col
Ord, Int -> Col
Col -> Int
Col -> [Col]
Col -> Col
Col -> Col -> [Col]
Col -> Col -> Col -> [Col]
(Col -> Col)
-> (Col -> Col)
-> (Int -> Col)
-> (Col -> Int)
-> (Col -> [Col])
-> (Col -> Col -> [Col])
-> (Col -> Col -> [Col])
-> (Col -> Col -> Col -> [Col])
-> Enum 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
(Col -> Col -> Col)
-> (Col -> Col -> Col)
-> (Col -> Col -> Col)
-> (Col -> Col)
-> (Col -> Col)
-> (Col -> Col)
-> (Integer -> Col)
-> Num 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
Num Col -> Ord Col -> (Col -> Rational) -> Real Col
Col -> Rational
forall a. Num a -> Ord a -> (a -> Rational) -> Real a
toRational :: Col -> Rational
$ctoRational :: Col -> Rational
$cp2Real :: Ord Col
$cp1Real :: Num Col
Real, Enum Col
Real Col
Real Col
-> Enum Col
-> (Col -> Col -> Col)
-> (Col -> Col -> Col)
-> (Col -> Col -> Col)
-> (Col -> Col -> Col)
-> (Col -> Col -> (Col, Col))
-> (Col -> Col -> (Col, Col))
-> (Col -> Integer)
-> Integral 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
$cp2Integral :: Enum Col
$cp1Integral :: Real 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
(LinePos -> LinePos -> Bool)
-> (LinePos -> LinePos -> Bool) -> Eq LinePos
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
(Int -> LinePos -> ShowS)
-> (LinePos -> String) -> ([LinePos] -> ShowS) -> Show LinePos
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
Eq LinePos
-> (LinePos -> LinePos -> Ordering)
-> (LinePos -> LinePos -> Bool)
-> (LinePos -> LinePos -> Bool)
-> (LinePos -> LinePos -> Bool)
-> (LinePos -> LinePos -> Bool)
-> (LinePos -> LinePos -> LinePos)
-> (LinePos -> LinePos -> LinePos)
-> Ord 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
$cp1Ord :: Eq LinePos
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 Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\n' = Offset -> Line -> Col -> LinePos
LinePos (Offset -> Offset
forall a. Enum a => a -> a
succ Offset
o) (Line -> Line
forall a. Enum a => a -> a
succ Line
l) Col
0
  | Bool
otherwise = Offset -> Line -> Col -> LinePos
LinePos (Offset -> Offset
forall a. Enum a => a -> a
succ Offset
o) Line
l (Col -> Col
forall a. Enum a => a -> a
succ Col
c)

incrLinePosChunk :: LinePos -> [Char] -> LinePos
incrLinePosChunk :: LinePos -> String -> LinePos
incrLinePosChunk = (LinePos -> Char -> LinePos) -> LinePos -> String -> LinePos
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
  { LinePosStream s -> LinePos
lpsLinePos :: !LinePos
  , LinePosStream s -> s
lpsState :: !s
  } deriving (LinePosStream s -> LinePosStream s -> Bool
(LinePosStream s -> LinePosStream s -> Bool)
-> (LinePosStream s -> LinePosStream s -> Bool)
-> Eq (LinePosStream s)
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
[LinePosStream s] -> ShowS
LinePosStream s -> String
(Int -> LinePosStream s -> ShowS)
-> (LinePosStream s -> String)
-> ([LinePosStream s] -> ShowS)
-> Show (LinePosStream s)
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, a -> LinePosStream b -> LinePosStream a
(a -> b) -> LinePosStream a -> LinePosStream b
(forall a b. (a -> b) -> LinePosStream a -> LinePosStream b)
-> (forall a b. a -> LinePosStream b -> LinePosStream a)
-> Functor LinePosStream
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
<$ :: a -> LinePosStream b -> LinePosStream a
$c<$ :: forall a b. a -> LinePosStream b -> LinePosStream a
fmap :: (a -> b) -> LinePosStream a -> LinePosStream b
$cfmap :: forall a b. (a -> b) -> LinePosStream a -> LinePosStream b
Functor, LinePosStream a -> Bool
(a -> m) -> LinePosStream a -> m
(a -> b -> b) -> b -> LinePosStream a -> b
(forall m. Monoid m => LinePosStream m -> m)
-> (forall m a. Monoid m => (a -> m) -> LinePosStream a -> m)
-> (forall m a. Monoid m => (a -> m) -> LinePosStream a -> m)
-> (forall a b. (a -> b -> b) -> b -> LinePosStream a -> b)
-> (forall a b. (a -> b -> b) -> b -> LinePosStream a -> b)
-> (forall b a. (b -> a -> b) -> b -> LinePosStream a -> b)
-> (forall b a. (b -> a -> b) -> b -> LinePosStream a -> b)
-> (forall a. (a -> a -> a) -> LinePosStream a -> a)
-> (forall a. (a -> a -> a) -> LinePosStream a -> a)
-> (forall a. LinePosStream a -> [a])
-> (forall a. LinePosStream a -> Bool)
-> (forall a. LinePosStream a -> Int)
-> (forall a. Eq a => a -> LinePosStream a -> Bool)
-> (forall a. Ord a => LinePosStream a -> a)
-> (forall a. Ord a => LinePosStream a -> a)
-> (forall a. Num a => LinePosStream a -> a)
-> (forall a. Num a => LinePosStream a -> a)
-> Foldable LinePosStream
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 :: LinePosStream a -> a
$cproduct :: forall a. Num a => LinePosStream a -> a
sum :: LinePosStream a -> a
$csum :: forall a. Num a => LinePosStream a -> a
minimum :: LinePosStream a -> a
$cminimum :: forall a. Ord a => LinePosStream a -> a
maximum :: LinePosStream a -> a
$cmaximum :: forall a. Ord a => LinePosStream a -> a
elem :: a -> LinePosStream a -> Bool
$celem :: forall a. Eq a => a -> LinePosStream a -> Bool
length :: LinePosStream a -> Int
$clength :: forall a. LinePosStream a -> Int
null :: LinePosStream a -> Bool
$cnull :: forall a. LinePosStream a -> Bool
toList :: LinePosStream a -> [a]
$ctoList :: forall a. LinePosStream a -> [a]
foldl1 :: (a -> a -> a) -> LinePosStream a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> LinePosStream a -> a
foldr1 :: (a -> a -> a) -> LinePosStream a -> a
$cfoldr1 :: forall a. (a -> a -> a) -> LinePosStream a -> a
foldl' :: (b -> a -> b) -> b -> LinePosStream a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> LinePosStream a -> b
foldl :: (b -> a -> b) -> b -> LinePosStream a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> LinePosStream a -> b
foldr' :: (a -> b -> b) -> b -> LinePosStream a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> LinePosStream a -> b
foldr :: (a -> b -> b) -> b -> LinePosStream a -> b
$cfoldr :: forall a b. (a -> b -> b) -> b -> LinePosStream a -> b
foldMap' :: (a -> m) -> LinePosStream a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> LinePosStream a -> m
foldMap :: (a -> m) -> LinePosStream a -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> LinePosStream a -> m
fold :: LinePosStream m -> m
$cfold :: forall m. Monoid m => LinePosStream m -> m
Foldable, Functor LinePosStream
Foldable LinePosStream
Functor LinePosStream
-> Foldable LinePosStream
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> LinePosStream a -> f (LinePosStream b))
-> (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 (m :: * -> *) a.
    Monad m =>
    LinePosStream (m a) -> m (LinePosStream a))
-> Traversable LinePosStream
(a -> f b) -> LinePosStream a -> f (LinePosStream b)
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 :: LinePosStream (m a) -> m (LinePosStream a)
$csequence :: forall (m :: * -> *) a.
Monad m =>
LinePosStream (m a) -> m (LinePosStream a)
mapM :: (a -> m b) -> LinePosStream a -> m (LinePosStream b)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> LinePosStream a -> m (LinePosStream b)
sequenceA :: LinePosStream (f a) -> f (LinePosStream a)
$csequenceA :: forall (f :: * -> *) a.
Applicative f =>
LinePosStream (f a) -> f (LinePosStream a)
traverse :: (a -> f b) -> LinePosStream a -> f (LinePosStream b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> LinePosStream a -> f (LinePosStream b)
$cp2Traversable :: Foldable LinePosStream
$cp1Traversable :: Functor LinePosStream
Traversable)

instance (Stream s, Token s ~ Char) => Stream (LinePosStream s) where
  type instance Chunk (LinePosStream s) = Chunk s
  type instance Token (LinePosStream s) = Token s
  streamTake1 :: LinePosStream s -> Maybe (Token (LinePosStream s), LinePosStream s)
streamTake1 (LinePosStream LinePos
p s
s) = ((Char, s) -> (Char, LinePosStream s))
-> Maybe (Char, s) -> Maybe (Char, LinePosStream s)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(Char
a, s
b) -> (Char
a, LinePos -> s -> LinePosStream s
forall s. LinePos -> s -> LinePosStream s
LinePosStream (LinePos -> Char -> LinePos
incrLinePosToken LinePos
p Char
a) s
b)) (s -> Maybe (Token s, s)
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) = ((Chunk s, s) -> (Chunk s, LinePosStream s))
-> Maybe (Chunk s, s) -> Maybe (Chunk s, LinePosStream s)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Chunk s, s) -> (Chunk s, LinePosStream s)
go (Int -> s -> Maybe (Chunk s, s)
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, LinePos -> s -> LinePosStream s
forall s. LinePos -> s -> LinePosStream s
LinePosStream (LinePos -> String -> LinePos
incrLinePosChunk LinePos
p (Chunk s -> String
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) = (Token s -> Bool) -> s -> (Chunk s, s)
forall s. Stream s => (Token s -> Bool) -> s -> (Chunk s, s)
streamTakeWhile Token s -> Bool
Token (LinePosStream s) -> Bool
pcate s
s
    in (Chunk s
Chunk (LinePosStream s)
a, LinePos -> s -> LinePosStream s
forall s. LinePos -> s -> LinePosStream s
LinePosStream (LinePos -> String -> LinePos
incrLinePosChunk LinePos
p (Chunk s -> String
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 instance Pos (LinePosStream s) = LinePos

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

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

-- | A range between two positions.
data Span p = Span
  { Span p -> p
spanStart :: !p
  , Span p -> p
spanEnd :: !p
  } deriving (Span p -> Span p -> Bool
(Span p -> Span p -> Bool)
-> (Span p -> Span p -> Bool) -> Eq (Span p)
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
[Span p] -> ShowS
Span p -> String
(Int -> Span p -> ShowS)
-> (Span p -> String) -> ([Span p] -> ShowS) -> Show (Span p)
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, Eq (Span p)
Eq (Span p)
-> (Span p -> Span p -> Ordering)
-> (Span p -> Span p -> Bool)
-> (Span p -> Span p -> Bool)
-> (Span p -> Span p -> Bool)
-> (Span p -> Span p -> Bool)
-> (Span p -> Span p -> Span p)
-> (Span p -> Span p -> Span p)
-> Ord (Span p)
Span p -> Span p -> Bool
Span p -> Span p -> Ordering
Span p -> Span p -> Span p
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
$cp1Ord :: forall p. Ord p => Eq (Span p)
Ord)