@@ -47,6 +47,8 @@ module Streamly.Internal.Data.StreamK
48 , parseBreakChunks
48 , parseBreakChunks
49 , parseChunks
49 , parseChunks
51 -- ** Specialized Folds
53 -- ** Specialized Folds
@@ -1424,6 +1426,135 @@ parseChunks :: (Monad m, Unbox a) =>
1424 ParserK (Array a) m b -> StreamK m (Array a) -> m (Either ParseError b)
1426 ParserK (Array a) m b -> StreamK m (Array a) -> m (Either ParseError b)
1425parseChunks f = fmap fst . parseBreakChunks f
1427parseChunks f = fmap fst . parseBreakChunks f
1429+-------------------------------------------------------------------------------
1430+-- Parsing using ParserK.Generic
1431+-------------------------------------------------------------------------------
1433+{-# INLINE backTrackSingular #-}
1434+backTrackSingular :: Int -> [a] -> StreamK m a -> (StreamK m a, [a])
1435+backTrackSingular = go
1439+ go _ [] stream = (stream, [])
1440+ go n xs stream | n <= 0 = (stream, xs)
1442+ let (appendBuf, newBTBuf) = splitAt n xs
1443+ in (append (fromList (Prelude.reverse appendBuf)) stream, newBTBuf)
1446+-- | Similar to 'parseBreak' but works on singular elements.
1448+{-# INLINE_NORMAL parseBreakSingular #-}
1450+ :: forall m a b. Monad m
1451+ => ParserK.ParserK a m b
1453+ -> m (Either ParseError b, StreamK m a)
1454+parseBreakSingular parser input = do
1455+ let parserk = ParserK.runParser parser parserDone 0 0
1456+ in go [] parserk input
1460+ {-# INLINE goStop #-}
1463+ -> (ParserK.Input a -> m (ParserK.Step a m b))
1464+ -> m (Either ParseError b, StreamK m a)
1465+ goStop backBuf parserk = do
1466+ pRes <- parserk ParserK.None
1468+ -- If we stop in an alternative, it will try calling the next
1469+ -- parser, the next parser may call initial returning Partial and
1470+ -- then immediately we have to call extract on it.
1471+ ParserK.Partial 0 cont1 ->
1473+ ParserK.Partial n cont1 -> do
1475+ assertM(n1 >= 0 && n1 <= length backBuf)
1476+ let (s1, backBuf1) = backTrackSingular n1 backBuf nil
1477+ in go backBuf1 cont1 s1
1478+ ParserK.Continue 0 cont1 ->
1479+ go backBuf cont1 nil
1480+ ParserK.Continue n cont1 -> do
1482+ assertM(n1 >= 0 && n1 <= length backBuf)
1483+ let (s1, backBuf1) = backTrackSingular n1 backBuf nil
1484+ in go backBuf1 cont1 s1
1485+ ParserK.Done 0 b ->
1486+ return (Right b, nil)
1487+ ParserK.Done n b -> do
1489+ assertM(n1 >= 0 && n1 <= length backBuf)
1490+ let (s1, _) = backTrackSingular n1 backBuf nil
1491+ in return (Right b, s1)
1492+ ParserK.Error _ err -> return (Left (ParseError err), nil)
1495+ error $ "parseBreakSingular: Partial: forward seek not implemented n = "
1500+ -> (ParserK.Input a -> m (ParserK.Step a m b))
1503+ -> m (Either ParseError b, StreamK m a)
1504+ yieldk backBuf parserk arr stream = do
1505+ pRes <- parserk (ParserK.Chunk arr)
1507+ ParserK.Partial 1 cont1 -> go [] cont1 stream
1508+ ParserK.Partial 0 cont1 -> go [] cont1 (cons arr stream)
1509+ ParserK.Partial n _ | n > 1 -> seekErr n
1510+ ParserK.Partial n cont1 -> do
1512+ bufLen = length backBuf
1513+ s = cons arr stream
1514+ assertM(n1 >= 0 && n1 <= bufLen)
1515+ let (s1, _) = backTrackSingular n1 backBuf s
1517+ ParserK.Continue 1 cont1 -> go (arr:backBuf) cont1 stream
1518+ ParserK.Continue 0 cont1 ->
1519+ go backBuf cont1 (cons arr stream)
1520+ ParserK.Continue n _ | n > 1 -> seekErr n
1521+ ParserK.Continue n cont1 -> do
1523+ bufLen = length backBuf
1524+ s = cons arr stream
1525+ assertM(n1 >= 0 && n1 <= bufLen)
1526+ let (s1, backBuf1) = backTrackSingular n1 backBuf s
1527+ go backBuf1 cont1 s1
1528+ ParserK.Done 1 b -> pure (Right b, stream)
1529+ ParserK.Done 0 b -> pure (Right b, cons arr stream)
1530+ ParserK.Done n _ | n > 1 -> seekErr n
1531+ ParserK.Done n b -> do
1533+ bufLen = length backBuf
1534+ s = cons arr stream
1535+ assertM(n1 >= 0 && n1 <= bufLen)
1536+ let (s1, _) = backTrackSingular n1 backBuf s
1538+ ParserK.Error _ err -> return (Left (ParseError err), nil)
1542+ -> (ParserK.Input a -> m (ParserK.Step a m b))
1544+ -> m (Either ParseError b, StreamK m a)
1545+ go backBuf parserk stream = do
1546+ let stop = goStop backBuf parserk
1547+ single a = yieldk backBuf parserk a nil
1549+ defState (yieldk backBuf parserk) single stop stream
1551+-- | Run a 'ParserK' over a 'StreamK'. Please use 'parseChunks' where possible,
1552+-- for better performance.
1553+{-# INLINE parseSingular #-}
1554+parseSingular :: Monad m =>
1555+ ParserK.ParserK a m b -> StreamK m a -> m (Either ParseError b)
1556+parseSingular f = fmap fst . parseBreakSingular f
1427-------------------------------------------------------------------------------
1558-------------------------------------------------------------------------------
1428-- Sorting
1559-- Sorting
1429-------------------------------------------------------------------------------
1560-------------------------------------------------------------------------------