@@ -49,6 +49,8 @@ module Streamly.Internal.Data.StreamK
4949 , parseChunks
5050 , parseBreakSingular
5151 , parseSingular
52+ , parseBreakGenericChunks
53+ , parseGenericChunks
5254
5355 -- ** Specialized Folds
5456 , head
@@ -143,6 +145,7 @@ import Streamly.Internal.Data.Unbox (sizeOf, Unbox)
143145
144146import qualified Control.Monad.Catch as MC
145147import qualified Streamly.Internal.Data.Array.Type as Array
148+import qualified Streamly.Internal.Data.Array.Generic as GenArr
146149import qualified Streamly.Internal.Data.Fold.Type as FL
147150import qualified Streamly.Internal.Data.Parser as Parser
148151import qualified Streamly.Internal.Data.Parser.ParserD.Type as PR
@@ -1284,7 +1287,7 @@ parseD :: Monad m =>
12841287parseD f = fmap fst . parseDBreak f
12851288
12861289-------------------------------------------------------------------------------
1287−-- Chunked parsing using ParserK
1290+-- ParserK Chunked
12881291-------------------------------------------------------------------------------
12891292
12901293-- The backracking buffer consists of arrays in the most-recent-first order. We
@@ -1427,7 +1430,7 @@ parseChunks :: (Monad m, Unbox a) =>
14271430parseChunks f = fmap fst . parseBreakChunks f
14281431
14291432-------------------------------------------------------------------------------
1430−-- Parsing using ParserK.Generic
1433+-- ParserK Singular
14311434-------------------------------------------------------------------------------
14321435
14331436{-# INLINE backTrackSingular #-}
@@ -1555,6 +1558,151 @@ parseSingular :: Monad m =>
15551558 ParserK.ParserK a m b -> StreamK m a -> m (Either ParseError b)
15561559parseSingular f = fmap fst . parseBreakSingular f
15571560
1561+-------------------------------------------------------------------------------
1562+-- ParserK Chunked Generic
1563+-------------------------------------------------------------------------------
1564+
1565+{-# INLINE backTrackGenericChunks #-}
1566+backTrackGenericChunks ::
1567+ Int
1568+ -> [GenArr.Array a]
1569+ -> StreamK m (GenArr.Array a)
1570+ -> (StreamK m (GenArr.Array a), [GenArr.Array a])
1571+backTrackGenericChunks = go
1572+
1573+ where
1574+
1575+ go _ [] stream = (stream, [])
1576+ go n xs stream | n <= 0 = (stream, xs)
1577+ go n (x:xs) stream =
1578+ let len = GenArr.length x
1579+ in if n > len
1580+ then go (n - len) xs (cons x stream)
1581+ else if n == len
1582+ then (cons x stream, xs)
1583+ else let arr1 = GenArr.getSliceUnsafe (len - n) n x
1584+ arr2 = GenArr.getSliceUnsafe 0 (len - n) x
1585+ in (cons arr1 stream, arr2:xs)
1586+
1587+-- | Similar to 'parseBreak' but works on generic arrays
1588+--
1589+{-# INLINE_NORMAL parseBreakGenericChunks #-}
1590+parseBreakGenericChunks
1591+ :: forall m a b. Monad m
1592+ => ParserK.ParserK (GenArr.Array a) m b
1593+ -> StreamK m (GenArr.Array a)
1594+ -> m (Either ParseError b, StreamK m (GenArr.Array a))
1595+parseBreakGenericChunks parser input = do
1596+ let parserk = ParserK.runParser parser parserDone 0 0
1597+ in go [] parserk input
1598+
1599+ where
1600+
1601+ {-# INLINE goStop #-}
1602+ goStop
1603+ :: [GenArr.Array a]
1604+ -> (ParserK.Input (GenArr.Array a)
1605+ -> m (ParserK.Step (GenArr.Array a) m b))
1606+ -> m (Either ParseError b, StreamK m (GenArr.Array a))
1607+ goStop backBuf parserk = do
1608+ pRes <- parserk ParserK.None
1609+ case pRes of
1610+ -- If we stop in an alternative, it will try calling the next
1611+ -- parser, the next parser may call initial returning Partial and
1612+ -- then immediately we have to call extract on it.
1613+ ParserK.Partial 0 cont1 ->
1614+ go [] cont1 nil
1615+ ParserK.Partial n cont1 -> do
1616+ let n1 = negate n
1617+ assertM(n1 >= 0 && n1 <= sum (Prelude.map GenArr.length backBuf))
1618+ let (s1, backBuf1) = backTrackGenericChunks n1 backBuf nil
1619+ in go backBuf1 cont1 s1
1620+ ParserK.Continue 0 cont1 ->
1621+ go backBuf cont1 nil
1622+ ParserK.Continue n cont1 -> do
1623+ let n1 = negate n
1624+ assertM(n1 >= 0 && n1 <= sum (Prelude.map GenArr.length backBuf))
1625+ let (s1, backBuf1) = backTrackGenericChunks n1 backBuf nil
1626+ in go backBuf1 cont1 s1
1627+ ParserK.Done 0 b ->
1628+ return (Right b, nil)
1629+ ParserK.Done n b -> do
1630+ let n1 = negate n
1631+ assertM(n1 >= 0 && n1 <= sum (Prelude.map GenArr.length backBuf))
1632+ let (s1, _) = backTrackGenericChunks n1 backBuf nil
1633+ in return (Right b, s1)
1634+ ParserK.Error _ err -> return (Left (ParseError err), nil)
1635+
1636+ seekErr n len =
1637+ error $ "parseBreak: Partial: forward seek not implemented n = "
1638+ ++ show n ++ " len = " ++ show len
1639+
1640+ yieldk
1641+ :: [GenArr.Array a]
1642+ -> (ParserK.Input (GenArr.Array a)
1643+ -> m (ParserK.Step (GenArr.Array a) m b))
1644+ -> GenArr.Array a
1645+ -> StreamK m (GenArr.Array a)
1646+ -> m (Either ParseError b, StreamK m (GenArr.Array a))
1647+ yieldk backBuf parserk arr stream = do
1648+ pRes <- parserk (ParserK.Chunk arr)
1649+ let len = GenArr.length arr
1650+ case pRes of
1651+ ParserK.Partial n cont1 ->
1652+ case compare n len of
1653+ EQ -> go [] cont1 stream
1654+ LT -> do
1655+ if n >= 0
1656+ then yieldk [] cont1 arr stream
1657+ else do
1658+ let n1 = negate n
1659+ bufLen = sum (Prelude.map GenArr.length backBuf)
1660+ s = cons arr stream
1661+ assertM(n1 >= 0 && n1 <= bufLen)
1662+ let (s1, _) = backTrackGenericChunks n1 backBuf s
1663+ go [] cont1 s1
1664+ GT -> seekErr n len
1665+ ParserK.Continue n cont1 ->
1666+ case compare n len of
1667+ EQ -> go (arr:backBuf) cont1 stream
1668+ LT -> do
1669+ if n >= 0
1670+ then yieldk backBuf cont1 arr stream
1671+ else do
1672+ let n1 = negate n
1673+ bufLen = sum (Prelude.map GenArr.length backBuf)
1674+ s = cons arr stream
1675+ assertM(n1 >= 0 && n1 <= bufLen)
1676+ let (s1, backBuf1) = backTrackGenericChunks n1 backBuf s
1677+ go backBuf1 cont1 s1
1678+ GT -> seekErr n len
1679+ ParserK.Done n b -> do
1680+ let n1 = len - n
1681+ assertM(n1 <= sum (Prelude.map GenArr.length (arr:backBuf)))
1682+ let (s1, _) = backTrackGenericChunks n1 (arr:backBuf) stream
1683+ in return (Right b, s1)
1684+ ParserK.Error _ err -> return (Left (ParseError err), nil)
1685+
1686+ go
1687+ :: [GenArr.Array a]
1688+ -> (ParserK.Input (GenArr.Array a)
1689+ -> m (ParserK.Step (GenArr.Array a) m b))
1690+ -> StreamK m (GenArr.Array a)
1691+ -> m (Either ParseError b, StreamK m (GenArr.Array a))
1692+ go backBuf parserk stream = do
1693+ let stop = goStop backBuf parserk
1694+ single a = yieldk backBuf parserk a nil
1695+ in foldStream
1696+ defState (yieldk backBuf parserk) single stop stream
1697+
1698+{-# INLINE parseGenericChunks #-}
1699+parseGenericChunks ::
1700+ (Monad m)
1701+ => ParserK.ParserK (GenArr.Array a) m b
1702+ -> StreamK m (GenArr.Array a)
1703+ -> m (Either ParseError b)
1704+parseGenericChunks f = fmap fst . parseBreakGenericChunks f
1705+
15581706-------------------------------------------------------------------------------
15591707-- Sorting
15601708-------------------------------------------------------------------------------