on master help sign in
Make Parser initial of type Initial
commit4f556e8b4d9e3f17f7bb346459d5a15d408a5625 authorAdithya Kumar <adithya@composewell.com> dateMon 18 Jan 2021, 05:32 (6 years ago) parentf32a166
11 files changed+609−246
bin/bench-exec-one.sh+1 cabal.project−2 src/Streamly/Internal/Data/Binary/Decode.hs+6−6 src/Streamly/Internal/Data/Parser/ParserD.hs+126−69 src/Streamly/Internal/Data/Parser/ParserD/Tee.hs+78−13 src/Streamly/Internal/Data/Parser/ParserD/Types.hs+260−106 src/Streamly/Internal/Data/Parser/ParserK/Types.hs+18−12 src/Streamly/Internal/Data/Producer/Source.hs+7−2 src/Streamly/Internal/Data/Stream/IsStream/Eliminate.hs+1−1 src/Streamly/Internal/Data/Stream/StreamD/Eliminate.hs+63−1 src/Streamly/Internal/Data/Stream/StreamD/Nesting.hs+49−34
bin/bench-exec-one.sh+1
@@ -52,6 +52,7 @@ bench_rts_opts_specific () {
5252 Prelude.Parallel/o-n-space/monad-outer-product/*) echo -n "-K4M -M256M" ;;
5353
5454 Prelude.Rate/o-1-space/*) echo -n "-K128K" ;;
55+ Prelude.Rate/o-1-space/asyncly/*) echo -n "-K128K" ;;
5556
5657 # XXX For GHC-9.0
5758 Prelude.Serial/o-1-space/mixed/sum-product-fold) echo -n "-K64M" ;;
cabal.project−2
@@ -1,5 +1,3 @@
11packages: streamly.cabal
22 , test/streamly-tests.cabal
33 , benchmark/streamly-benchmarks.cabal
4−
5−
src/Streamly/Internal/Data/Binary/Decode.hs+6−6
@@ -113,7 +113,7 @@ word16beD = PRD.Parser step initial extract
113113
114114 where
115115
116− initial = return Nothing'
116+ initial = return $ PRD.IPartial Nothing'
117117
118118 step Nothing' a =
119119 -- XXX We can use a non-failing parser or a fold so that we do not
@@ -140,7 +140,7 @@ word16leD = PRD.Parser step initial extract
140140
141141 where
142142
143− initial = return Nothing'
143+ initial = return $ PRD.IPartial Nothing'
144144
145145 step Nothing' a =
146146 return $ PRD.Continue 0 (Just' (fromIntegral a))
@@ -165,7 +165,7 @@ word32beD = PRD.Parser step initial extract
165165
166166 where
167167
168− initial = return $ Tuple' 0 24
168+ initial = return $ PRD.IPartial $ Tuple' 0 24
169169
170170 step (Tuple' w sh) a = return $
171171 if sh /= 0
@@ -192,7 +192,7 @@ word32leD = PRD.Parser step initial extract
192192
193193 where
194194
195− initial = return $ Tuple' 0 0
195+ initial = return $ PRD.IPartial $ Tuple' 0 0
196196
197197 step (Tuple' w sh) a = return $
198198 let w1 = w .|. (fromIntegral a `unsafeShiftL` sh)
@@ -218,7 +218,7 @@ word64beD = PRD.Parser step initial extract
218218
219219 where
220220
221− initial = return $ Tuple' 0 56
221+ initial = return $ PRD.IPartial $ Tuple' 0 56
222222
223223 step (Tuple' w sh) a = return $
224224 if sh /= 0
@@ -245,7 +245,7 @@ word64leD = PRD.Parser step initial extract
245245
246246 where
247247
248− initial = return $ Tuple' 0 0
248+ initial = return $ PRD.IPartial $ Tuple' 0 0
249249
250250 step (Tuple' w sh) a = return $
251251 let w1 = w .|. (fromIntegral a `unsafeShiftL` sh)
src/Streamly/Internal/Data/Parser/ParserD.hs+126−69
@@ -15,6 +15,7 @@ module Streamly.Internal.Data.Parser.ParserD
1515 Parser (..)
1616 , ParseError (..)
1717 , Step (..)
18+ , Initial (..)
1819
1920 -- First order parsers
2021 -- * Accumulators
@@ -191,20 +192,23 @@ import Streamly.Internal.Data.Parser.ParserD.Types
191192--
192193{-# INLINE fromFold #-}
193194fromFold :: Monad m => Fold m a b -> Parser m a b
194−fromFold (Fold fstep finitial fextract) = Parser step finitial extract
195+fromFold (Fold fstep finitial fextract) = Parser step initial fextract
195196
196197 where
197198
198− step (FL.Partial s) a = do
199+ initial = do
200+ res <- finitial
201+ return
202+ $ case res of
203+ FL.Partial s1 -> IPartial s1
204+ FL.Done b -> IDone b
205+
206+ step s a = do
199207 res <- fstep s a
200208 return
201209 $ case res of
202− FL.Partial s1 -> Partial 0 (FL.Partial s1)
210+ FL.Partial s1 -> Partial 0 s1
203211 FL.Done b -> Done 0 b
204− step (FL.Done b) _ = return $ Done 1 b
205−
206− extract (FL.Partial s) = fextract s
207− extract (FL.Done b) = return b
208212
209213-------------------------------------------------------------------------------
210214-- Failing Parsers
@@ -220,7 +224,7 @@ peek = Parser step initial extract
220224
221225 where
222226
223− initial = return ()
227+ initial = return $ IPartial ()
224228
225229 step () a = return $ Done 1 a
226230
@@ -236,7 +240,7 @@ eof = Parser step initial return
236240
237241 where
238242
239− initial = return ()
243+ initial = return $ IPartial ()
240244
241245 step () _ = return $ Error "eof: not at end of input"
242246
@@ -250,7 +254,7 @@ satisfy predicate = Parser step initial extract
250254
251255 where
252256
253− initial = return ()
257+ initial = return $ IPartial ()
254258
255259 step () a = return $
256260 if predicate a
@@ -269,7 +273,7 @@ maybe parser = Parser step initial extract
269273
270274 where
271275
272− initial = return ()
276+ initial = return $ IPartial ()
273277
274278 step () a = return $
275279 case parser a of
@@ -288,7 +292,7 @@ either parser = Parser step initial extract
288292
289293 where
290294
291− initial = return ()
295+ initial = return $ IPartial ()
292296
293297 step () a = return $
294298 case parser a of
@@ -315,10 +319,15 @@ takeBetween low high (Fold fstep finitial fextract) =
315319
316320 initial = do
317321 res <- finitial
318− case res of
319− FL.Partial s -> return $ Tuple' 0 s
320− FL.Done _ ->
321− error "takeBetween: Done/Error in initial not implemented yet."
322+ return $ case res of
323+ FL.Partial s -> IPartial $ Tuple' 0 s
324+ FL.Done b ->
325+ if low <= 0
326+ then IDone b
327+ else IError
328+ $ "takeBetween: the collecting fold terminated without"
329+ ++ " consuming any elements"
330+ ++ " minimum" ++ show low ++ " elements needed"
322331
323332 step (Tuple' i s) a
324333 | low > high =
@@ -374,10 +383,15 @@ takeEQ n (Fold fstep finitial fextract) = Parser step initial extract
374383
375384 initial = do
376385 res <- finitial
377− case res of
378− FL.Partial s -> return $ Tuple' 0 s
379− FL.Done _ ->
380− error "takeEQ: Done/Error in initial not implemented yet."
386+ return $ case res of
387+ FL.Partial s -> IPartial $ Tuple' 0 s
388+ FL.Done b ->
389+ if cnt == 0
390+ then IDone b
391+ else IError
392+ $ "takeEQ: Expecting exactly " ++ show cnt
393+ ++ " elements, fold terminated without"
394+ ++ " consuming any elements"
381395
382396 step (Tuple' i r) a
383397 | i1 < cnt = do
@@ -424,10 +438,15 @@ takeGE n (Fold fstep finitial fextract) = Parser step initial extract
424438 cnt = max n 0
425439 initial = do
426440 res <- finitial
427− case res of
428− FL.Partial s -> return $ Tuple' 0 s
429− FL.Done _ ->
430− error "takeGE: Done/Error in initial not implemented yet."
441+ return $ case res of
442+ FL.Partial s -> IPartial $ Tuple' 0 s
443+ FL.Done b ->
444+ if cnt == 0
445+ then IDone b
446+ else IError
447+ $ "takeGE: Expecting at least " ++ show cnt
448+ ++ " elements, fold terminated without"
449+ ++ " consuming any elements"
431450
432451 step (Tuple' i r) a
433452 | i1 < cnt = do
@@ -471,10 +490,9 @@ takeWhile predicate (Fold fstep finitial fextract) =
471490
472491 initial = do
473492 res <- finitial
474− case res of
475− FL.Partial s -> return s
476− FL.Done _ ->
477− error "takeWhile: Done/Error in initial not implemented yet."
493+ return $ case res of
494+ FL.Partial s -> IPartial s
495+ FL.Done b -> IDone b
478496
479497 step s a =
480498 if predicate a
@@ -497,35 +515,36 @@ takeWhile1 predicate (Fold fstep finitial fextract) =
497515
498516 where
499517
500− initial = return Nothing
501−
502− step Nothing a =
503− let err = Error "takeWhile1: predicate failed on first element"
504− in if predicate a
505− then do
506− res <- finitial
507− case res of
508− FL.Partial s -> do
509− sr <- fstep s a
510− return
511− $ case sr of
512− FL.Partial s1 -> Partial 0 (Just s1)
513− FL.Done b -> Done 0 b
514− FL.Done _ -> return err
515− else return err
516− step (Just s) a =
518+ initial = do
519+ res <- finitial
520+ return $ case res of
521+ FL.Partial s -> IPartial (Left s)
522+ FL.Done _ ->
523+ IError
524+ $ "takeWhile1: fold terminated without consuming:"
525+ ++ " any element"
526+
527+ {-# INLINE process #-}
528+ process s a = do
529+ res <- fstep s a
530+ return
531+ $ case res of
532+ FL.Partial s1 -> Partial 0 (Right s1)
533+ FL.Done b -> Done 0 b
534+
535+ step (Left s) a =
517536 if predicate a
518− then do
519− sr <- fstep s a
520− case sr of
521− FL.Partial r -> return $ Partial 0 (Just r)
522− FL.Done b -> return $ Done 0 b
537+ then process s a
538+ else return $ Error "takeWhile1: predicate failed on first element"
539+ step (Right s) a =
540+ if predicate a
541+ then process s a
523542 else do
524543 b <- fextract s
525544 return $ Done 1 b
526545
527− extract Nothing = throwM $ ParseError "takeWhile1: end of input"
528− extract (Just s) = fextract s
546+ extract (Left _) = throwM $ ParseError "takeWhile1: end of input"
547+ extract (Right s) = fextract s
529548
530549-- | See 'Streamly.Internal.Data.Parser.sliceSepByP'.
531550--
@@ -566,8 +585,8 @@ sliceBeginWith cond (Fold fstep finitial fextract) =
566585 res <- finitial
567586 return $
568587 case res of
569− FL.Partial s -> Left' s
570− FL.Done _ -> error "sliceBeginWith : bad finitial"
588+ FL.Partial s -> IPartial (Left' s)
589+ FL.Done _ -> IError "sliceBeginWith : bad finitial"
571590
572591 {-# INLINE process #-}
573592 process s a = do
@@ -613,8 +632,8 @@ wordBy predicate (Fold fstep finitial fextract) = Parser step initial extract
613632 res <- finitial
614633 return
615634 $ case res of
616− FL.Partial s -> WBLeft s
617− FL.Done _ -> error "wordBy: Done in initial not implemented"
635+ FL.Partial s -> IPartial $ WBLeft s
636+ FL.Done b -> IDone b
618637
619638 step (WBLeft s) a =
620639 if not (predicate a)
@@ -661,8 +680,8 @@ groupBy eq (Fold fstep finitial fextract) = Parser step initial extract
661680 res <- finitial
662681 return
663682 $ case res of
664− FL.Partial s -> GroupByInit s
665− FL.Done _ -> error "groupBy: Done in initial not implemented"
683+ FL.Partial s -> IPartial $ GroupByInit s
684+ FL.Done b -> IDone b
666685
667686 step (GroupByInit s) a = grouper s a a
668687 step (GroupByGrouping a0 s) a =
@@ -693,8 +712,8 @@ groupByRolling eq (Fold fstep finitial fextract) = Parser step initial extract
693712 res <- finitial
694713 return
695714 $ case res of
696− FL.Partial s -> GroupByInit s
697− FL.Done _ -> error "groupByRolling: Done in initial not implemented"
715+ FL.Partial s -> IPartial $ GroupByInit s
716+ FL.Done b -> IDone b
698717
699718 step (GroupByInit s) a = grouper s a
700719 step (GroupByGrouping a0 s) a =
@@ -718,7 +737,7 @@ eqBy cmp str = Parser step initial extract
718737
719738 where
720739
721− initial = return str
740+ initial = return $ IPartial str
722741
723742 step [] _ = return $ Done 0 ()
724743 step [x] a =
@@ -804,7 +823,12 @@ lookAhead (Parser step1 initial1 _) = Parser step initial extract
804823
805824 where
806825
807− initial = Tuple' 0 <$> initial1
826+ initial = do
827+ res <- initial1
828+ return $ case res of
829+ IPartial s -> IPartial (Tuple' 0 s)
830+ IDone b -> IDone b
831+ IError e -> IError e
808832
809833 step (Tuple' cnt st) a = do
810834 r <- step1 st a
@@ -932,11 +956,33 @@ manyTill (Fold fstep finitial fextract)
932956
933957 where
934958
959+ -- Caution: Mutual recursion
960+
961+ -- Don't inline this
962+ scrutL fs p c d e = do
963+ resL <- initialL
964+ case resL of
965+ IPartial sl -> return $ c (ManyTillL 0 fs sl)
966+ IDone bl -> do
967+ fr <- fstep fs bl
968+ case fr of
969+ FL.Partial fs1 -> scrutR fs1 p c d e
970+ FL.Done fb -> return $ d fb
971+ IError err -> return $ e err
972+
973+ {-# INLINE scrutR #-}
974+ scrutR fs p c d e = do
975+ resR <- initialR
976+ case resR of
977+ IPartial sr -> return $ p (ManyTillR 0 fs sr)
978+ IDone _ -> d <$> fextract fs
979+ IError _ -> scrutL fs p c d e
980+
935981 initial = do
936982 res <- finitial
937983 case res of
938− FL.Partial fs -> ManyTillR 0 fs <$> initialR
939− FL.Done _ -> error "manyTill: Done in initial not implemented"
984+ FL.Partial fs -> scrutR fs IPartial IPartial IDone IError
985+ FL.Done b -> return $ IDone b
940986
941987 step (ManyTillR cnt fs st) a = do
942988 r <- stepR st a
@@ -949,8 +995,20 @@ manyTill (Fold fstep finitial fextract)
949995 b <- fextract fs
950996 return $ Done n b
951997 Error _ -> do
952− rR <- initialL
953− return $ Continue (cnt + 1) (ManyTillL 0 fs rR)
998+ resL <- initialL
999+ case resL of
1000+ IPartial sl ->
1001+ return $ Continue (cnt + 1) (ManyTillL 0 fs sl)
1002+ IDone bl -> do
1003+ fr <- fstep fs bl
1004+ let cnt1 = cnt + 1
1005+ p = Partial cnt
1006+ c = Continue cnt
1007+ d = Done cnt
1008+ case fr of
1009+ FL.Partial fs1 -> scrutR fs1 p c d Error
1010+ FL.Done fb -> return $ Done cnt1 fb
1011+ IError err -> return $ Error err
9541012 -- XXX the cnt is being used only by the assert
9551013 step (ManyTillL cnt fs st) a = do
9561014 r <- stepL st a
@@ -962,9 +1020,8 @@ manyTill (Fold fstep finitial fextract)
9621020 Done n b -> do
9631021 fs1 <- fstep fs b
9641022 case fs1 of
965− FL.Partial s -> do
966− l <- initialR
967− return $ Partial n (ManyTillR 0 s l)
1023+ FL.Partial s ->
1024+ scrutR s (Partial n) (Continue n) (Done n) Error
9681025 FL.Done b1 -> return $ Done n b1
9691026 Error err -> return $ Error err
9701027
src/Streamly/Internal/Data/Parser/ParserD/Tee.hs+78−13
@@ -44,7 +44,7 @@ import Prelude
4444
4545import Fusion.Plugin.Types (Fuse(..))
4646import Streamly.Internal.Data.Parser.ParserD.Types
47− (Parser(..), Step(..), ParseError)
47+ (Initial(..), Parser(..), Step(..), ParseError)
4848
4949-------------------------------------------------------------------------------
5050-- Distribute input to two parsers and collect both results
@@ -81,6 +81,7 @@ import Streamly.Internal.Data.Parser.ParserD.Types
8181-- different lengths of the stream we consider the maximum of the two as
8282-- consumed.
8383--
84+ -- XXX We can use Initial instead of StepState
8485{-# ANN type StepState Fuse #-}
8586data StepState s a = StepState s | StepResult a
8687
@@ -108,9 +109,24 @@ teeWith zf (Parser stepL initialL extractL) (Parser stepR initialR extractR) =
108109
109110 {-# INLINE_LATE initial #-}
110111 initial = do
111− sL <- initialL
112− sR <- initialR
113− return $ TeePair ([], StepState sL, [], []) ([], StepState sR, [], [])
112+ resL <- initialL
113+ resR <- initialR
114+ return $ case resL of
115+ IPartial sl ->
116+ case resR of
117+ IPartial sr -> IPartial $ TeePair ([], StepState sl, [], [])
118+ ([], StepState sr, [], [])
119+ IDone br -> IPartial $ TeePair ([], StepState sl, [], [])
120+ ([], StepResult br, [], [])
121+ IError err -> IError err
122+ IDone bl ->
123+ case resR of
124+ IPartial sr ->
125+ IPartial $ TeePair ([], StepResult bl, [], [])
126+ ([], StepState sr, [], [])
127+ IDone br -> IDone $ zf bl br
128+ IError err -> IError err
129+ IError err -> IError err
114130
115131 {-# INLINE consume #-}
116132 consume buf inp1 inp2 stp st y = do
@@ -236,9 +252,22 @@ teeWithFst zf (Parser stepL initialL extractL)
236252
237253 {-# INLINE_LATE initial #-}
238254 initial = do
239− sL <- initialL
240− sR <- initialR
241− return $ TeePair ([], StepState sL, [], []) ([], StepState sR, [], [])
255+ resL <- initialL
256+ resR <- initialR
257+ case resL of
258+ IPartial sl ->
259+ return $ case resR of
260+ IPartial sr -> IPartial $ TeePair ([], StepState sl, [], [])
261+ ([], StepState sr, [], [])
262+ IDone br -> IPartial $ TeePair ([], StepState sl, [], [])
263+ ([], StepResult br, [], [])
264+ IError err -> IError err
265+ IDone bl ->
266+ case resR of
267+ IPartial sr -> IDone . zf bl <$> extractR sr
268+ IDone br -> return $ IDone $ zf bl br
269+ IError err -> return $ IError err
270+ IError err -> return $ IError err
242271
243272 {-# INLINE consume #-}
244273 consume buf inp1 inp2 stp st y = do
@@ -358,9 +387,21 @@ shortest (Parser stepL initialL extractL) (Parser stepR initialR _) =
358387
359388 {-# INLINE_LATE initial #-}
360389 initial = do
361− sL <- initialL
362− sR <- initialR
363− return $ TeePair ([], StepState sL, [], []) ([], StepState sR, [], [])
390+ resL <- initialL
391+ resR <- initialR
392+ return $ case resL of
393+ IPartial sl ->
394+ case resR of
395+ IPartial sr -> IPartial $ TeePair ([], StepState sl, [], [])
396+ ([], StepState sr, [], [])
397+ IDone br -> IDone br
398+ IError err -> IError err
399+ IDone bl -> IDone bl
400+ IError errL ->
401+ case resR of
402+ IPartial _ -> IError errL
403+ IDone br -> IDone br
404+ IError errR -> IError errR
364405
365406 {-# INLINE consume #-}
366407 consume buf inp1 inp2 stp st y = do
@@ -433,11 +474,35 @@ longest (Parser stepL initialL extractL) (Parser stepR initialR extractR) =
433474
434475 where
435476
477+
436478 {-# INLINE_LATE initial #-}
437479 initial = do
438− sL <- initialL
439− sR <- initialR
440− return $ TeePair ([], StepState sL, [], []) ([], StepState sR, [], [])
480+ resL <- initialL
481+ resR <- initialR
482+ return $ case resL of
483+ IPartial sl ->
484+ case resR of
485+ IPartial sr -> IPartial $ TeePair ([], StepState sl, [], [])
486+ ([], StepState sr, [], [])
487+ IDone br -> IPartial $ TeePair ([], StepState sl, [], [])
488+ ([], StepResult br, [], [])
489+ IError _ ->
490+ IPartial $ TeePair ([], StepState sl, [], [])
491+ ([], StepResult undefined, [], [])
492+ IDone bl ->
493+ case resR of
494+ IPartial sr ->
495+ IPartial $ TeePair ([], StepResult bl, [], [])
496+ ([], StepState sr, [], [])
497+ IDone _ -> IDone bl
498+ IError _ -> IDone bl
499+ IError _ ->
500+ case resR of
501+ IPartial sr ->
502+ IPartial $ TeePair ([], StepResult undefined, [], [])
503+ ([], StepState sr, [], [])
504+ IDone br -> IDone br
505+ IError err -> IError err
441506
442507 {-# INLINE consume #-}
443508 consume buf inp1 inp2 stp st y = do
src/Streamly/Internal/Data/Parser/ParserD/Types.hs+260−106
@@ -36,9 +36,9 @@
3636-- 'Step' functor provides the following commands to the fold driver
3737-- corresponding to the use cases outlined in the previous para:
3838--
39−-- 1. 'Continue': buffer the current input and go back to a previous
39+-- 1. 'Continue': buffer the current input and optionally go back to a previous
4040-- position in the stream
41−-- 2. 'Partial': buffer the current input and go back to a previous
41+-- 2. 'Partial': buffer the current input and optionally go back to a previous
4242-- position in the stream, drop the buffer before that position.
4343-- 3. 'Done': parser succeeded, returns how much input was leftover
4444-- 4. 'Error': indicates that the parser has failed without a result
@@ -111,7 +111,8 @@
111111
112112module Streamly.Internal.Data.Parser.ParserD.Types
113113 (
114− Step (..)
114+ Initial (..)
115+ , Step (..)
115116 , Parser (..)
116117 , ParseError (..)
117118
@@ -135,6 +136,7 @@ import Control.Applicative (Alternative(..))
135136import Control.Exception (assert, Exception(..))
136137import Control.Monad (MonadPlus(..))
137138import Control.Monad.Catch (MonadCatch, try, throwM, MonadThrow)
139+import Data.Bifunctor (Bifunctor(..))
138140import Fusion.Plugin.Types (Fuse(..))
139141import Streamly.Internal.Data.Fold.Types (Fold(..), toList)
140142import Streamly.Internal.Data.Tuple.Strict (Tuple3'(..))
@@ -151,6 +153,48 @@ import Prelude hiding (concatMap)
151153-- >>> import qualified Streamly.Internal.Data.Stream.IsStream as Stream (parse)
152154-- >>> import qualified Streamly.Internal.Data.Parser as Parser
153155
156+-- | The type of a 'Parser''s initial action.
157+--
158+-- /Internal/
159+--
160+{-# ANN type Initial Fuse #-}
161+data Initial s b
162+ = IPartial !s -- ^ Wait for step function to be called with state @s@.
163+ | IDone !b -- ^ Return a result right away without an input.
164+ | IError String -- ^ Return an error right away without an input.
165+
166+-- | @first@ maps on 'IPartial' and @second@ maps on 'IDone'.
167+--
168+-- /Internal/
169+--
170+instance Bifunctor Initial where
171+ {-# INLINE bimap #-}
172+ bimap f _ (IPartial a) = IPartial (f a)
173+ bimap _ g (IDone b) = IDone (g b)
174+ bimap _ _ (IError err) = IError err
175+
176+ {-# INLINE first #-}
177+ first f (IPartial a) = IPartial (f a)
178+ first _ (IDone x) = IDone x
179+ first _ (IError err) = IError err
180+
181+ {-# INLINE second #-}
182+ second _ (IPartial x) = IPartial x
183+ second f (IDone a) = IDone (f a)
184+ second _ (IError err) = IError err
185+
186+-- | Maps a function over the result held by 'IDone'.
187+--
188+-- @
189+-- fmap = 'second'
190+-- @
191+--
192+-- /Internal/
193+--
194+instance Functor (Initial s) where
195+ {-# INLINE fmap #-}
196+ fmap = second
197+
154198-- | The return type of a 'Parser' step.
155199--
156200-- The parse operation feeds the input stream to the parser one element at a
@@ -231,7 +275,7 @@ instance Functor (Step s) where
231275-- /Internal/
232276--
233277data Parser m a b =
234− forall s. Parser (s -> a -> m (Step s b)) (m s) (s -> m b)
278+ forall s. Parser (s -> a -> m (Step s b)) (m (Initial s b)) (s -> m b)
235279
236280-- | This exception is used for two purposes:
237281--
@@ -249,11 +293,12 @@ instance Exception ParseError where
249293
250294instance Functor m => Functor (Parser m a) where
251295 {-# INLINE fmap #-}
252− fmap f (Parser step1 initial extract) =
296+ fmap f (Parser step1 initial1 extract) =
253297 Parser step initial (fmap2 f extract)
254298
255299 where
256300
301+ initial = fmap2 f initial1
257302 step s b = fmap2 f (step1 s b)
258303 fmap2 g = fmap (fmap g)
259304
@@ -263,9 +308,7 @@ instance Functor m => Functor (Parser m a) where
263308--
264309{-# INLINE_NORMAL yield #-}
265310yield :: Monad m => b -> Parser m a b
266−yield b = Parser (\_ _ -> pure $ Done 1 b) -- step
267− (pure ()) -- initial
268− (\_ -> pure b) -- extract
311+yield b = Parser undefined (pure $ IDone b) undefined
269312
270313-- | See 'Streamly.Internal.Data.Parser.yieldM'.
271314--
@@ -273,9 +316,7 @@ yield b = Parser (\_ _ -> pure $ Done 1 b) -- step
273316--
274317{-# INLINE yieldM #-}
275318yieldM :: Monad m => m b -> Parser m a b
276−yieldM b = Parser (\_ _ -> Done 1 <$> b) -- step
277− (pure ()) -- initial
278− (const b) -- extract
319+yieldM b = Parser undefined (IDone <$> b) undefined
279320
280321-------------------------------------------------------------------------------
281322-- Sequential applicative
@@ -296,7 +337,7 @@ data SeqParseState sl f sr = SeqParseL sl | SeqParseR f sr
296337-- /Internal/
297338--
298339{-# INLINE splitWith #-}
299−splitWith :: Monad m
340+splitWith :: MonadThrow m
300341 => (a -> b -> c) -> Parser m x a -> Parser m x b -> Parser m x c
301342splitWith func (Parser stepL initialL extractL)
302343 (Parser stepR initialR extractR) =
@@ -304,38 +345,55 @@ splitWith func (Parser stepL initialL extractL)
304345
305346 where
306347
307− initial = SeqParseL <$> initialL
348+ initial = do
349+ resL <- initialL
350+ case resL of
351+ IPartial sl -> return $ IPartial $ SeqParseL sl
352+ IDone bl -> do
353+ resR <- initialR
354+ return $ case resR of
355+ IPartial sr -> IPartial $ SeqParseR (func bl) sr
356+ IDone br -> IDone (func bl br)
357+ IError err -> IError err
358+ IError err -> return $ IError err
308359
309360 -- Note: For the composed parse to terminate, the left parser has to be
310361 -- a terminating parser returning a Done at some point.
311− step (SeqParseL st) a = do
312− r <- stepL st a
313− case r of
362+ step (SeqParseL st) a =
363+ (\resL initR ->
364+ case resL of
314365 -- Note: We need to buffer the input for a possible Alternative
315366 -- e.g. in ((,) <$> p1 <*> p2) <|> p3, if p2 fails we have to
316367 -- backtrack and start running p3. So we need to keep the input
317368 -- buffered until we know that the applicative cannot fail.
318− Partial n s -> return $ Continue n (SeqParseL s)
319− Continue n s -> return $ Continue n (SeqParseL s)
320− Done n b -> Continue n <$> (SeqParseR (func b) <$> initialR)
321− Error err -> return $ Error err
369+ Partial n s -> Continue n (SeqParseL s)
370+ Continue n s -> Continue n (SeqParseL s)
371+ Done n b ->
372+ case initR of
373+ IPartial sr -> Continue n $ SeqParseR (func b) sr
374+ IDone br -> Done n (func b br)
375+ IError err -> Error err
376+ Error err -> Error err) <$> stepL st a <*> initialR
322377
323− step (SeqParseR f st) a = do
324− r <- stepR st a
325− return $ case r of
378+ step (SeqParseR f st) a =
379+ (\case
326380 Partial n s -> Partial n (SeqParseR f s)
327381 Continue n s -> Continue n (SeqParseR f s)
328382 Done n b -> Done n (f b)
329− Error err -> Error err
383+ Error err -> Error err) <$> stepR st a
330384
331385 extract (SeqParseR f sR) = fmap f (extractR sR)
332386 extract (SeqParseL sL) = do
333387 rL <- extractL sL
334− sR <- initialR
335− rR <- extractR sR
336− return $ func rL rR
337−
338−-- Only use this if you know what you're doing
388+ res <- initialR
389+ case res of
390+ IPartial sR -> do
391+ rR <- extractR sR
392+ return $ func rL rR
393+ IDone rR -> return $ func rL rR
394+ IError err -> throwM $ ParseError err
395+
396+-- | Works correctly only if the first parser is guaranteed to never fail.
339397{-# INLINE noErrorUnsafeSplitWith #-}
340398noErrorUnsafeSplitWith :: Monad m
341399 => (a -> b -> c) -> Parser m x a -> Parser m x b -> Parser m x c
@@ -345,14 +403,34 @@ noErrorUnsafeSplitWith func (Parser stepL initialL extractL)
345403
346404 where
347405
348− initial = SeqParseL <$> initialL
406+ initial = do
407+ resL <- initialL
408+ case resL of
409+ IPartial sl -> return $ IPartial $ SeqParseL sl
410+ IDone bl -> do
411+ resR <- initialR
412+ return $ case resR of
413+ IPartial sr -> IPartial $ SeqParseR (func bl) sr
414+ IDone br -> IDone (func bl br)
415+ IError err -> IError err
416+ IError err -> return $ IError err
349417
418+ -- Note: For the composed parse to terminate, the left parser has to be
419+ -- a terminating parser returning a Done at some point.
350420 step (SeqParseL st) a = do
351421 r <- stepL st a
352422 case r of
423+ -- Assume that the first parser can never fail, therefore we do not
424+ -- need to keep the input for backtracking.
353425 Partial n s -> return $ Partial n (SeqParseL s)
354426 Continue n s -> return $ Partial n (SeqParseL s)
355− Done n b -> Partial n <$> (SeqParseR (func b) <$> initialR)
427+ Done n b -> do
428+ res <- initialR
429+ return
430+ $ case res of
431+ IPartial sr -> Partial n $ SeqParseR (func b) sr
432+ IDone br -> Done n (func b br)
433+ IError err -> Error err
356434 Error err -> return $ Error err
357435
358436 step (SeqParseR f st) a = do
@@ -366,9 +444,15 @@ noErrorUnsafeSplitWith func (Parser stepL initialL extractL)
366444 extract (SeqParseR f sR) = fmap f (extractR sR)
367445 extract (SeqParseL sL) = do
368446 rL <- extractL sL
369− sR <- initialR
370− rR <- extractR sR
371− return $ func rL rR
447+ res <- initialR
448+ case res of
449+ IPartial sR -> do
450+ rR <- extractR sR
451+ return $ func rL rR
452+ IDone rR -> return $ func rL rR
453+ IError err -> error $ "noErrorUnsafeSplitWith: cannot use a "
454+ ++ "failing parser. Parser failed with: " ++ err
455+
372456
373457{-# ANN type SeqAState Fuse #-}
374458data SeqAState sl sr = SeqAL sl | SeqAR sr
@@ -379,23 +463,37 @@ data SeqAState sl sr = SeqAL sl | SeqAR sr
379463-- /Internal/
380464--
381465{-# INLINE split_ #-}
382−split_ :: Monad m => Parser m x a -> Parser m x b -> Parser m x b
466+split_ :: MonadThrow m => Parser m x a -> Parser m x b -> Parser m x b
383467split_ (Parser stepL initialL extractL) (Parser stepR initialR extractR) =
384468 Parser step initial extract
385469
386470 where
387471
388− initial = SeqAL <$> initialL
472+ initial = do
473+ resL <- initialL
474+ case resL of
475+ IPartial sl -> return $ IPartial $ SeqAL sl
476+ IDone _ -> do
477+ resR <- initialR
478+ return $ case resR of
479+ IPartial sr -> IPartial $ SeqAR sr
480+ IDone br -> IDone br
481+ IError err -> IError err
482+ IError err -> return $ IError err
389483
390484 -- Note: For the composed parse to terminate, the left parser has to be
391485 -- a terminating parser returning a Done at some point.
392486 step (SeqAL st) a =
393− (\r i -> case r of
487+ (\resL initR -> case resL of
394488 -- Note: this leads to buffering even if we are not in an
395489 -- Alternative composition.
396490 Partial n s -> Continue n (SeqAL s)
397491 Continue n s -> Continue n (SeqAL s)
398− Done n _ -> Continue n (SeqAR i)
492+ Done n _ -> do
493+ case initR of
494+ IPartial s -> Continue n (SeqAR s)
495+ IDone b -> Done n b
496+ IError err -> Error err
399497 -- XXX should we sequence initialR monadically?
400498 Error err -> Error err) <$> stepL st a <*> initialR
401499
@@ -409,10 +507,14 @@ split_ (Parser stepL initialL extractL) (Parser stepR initialR extractR) =
409507 extract (SeqAR sR) = extractR sR
410508 extract (SeqAL sL) = do
411509 _ <- extractL sL
412− initialR >>= extractR
510+ res <- initialR
511+ case res of
512+ IPartial sR -> extractR sR
513+ IDone rR -> return rR
514+ IError err -> throwM $ ParseError err
413515
414516-- | 'Applicative' form of 'splitWith'.
415−instance Monad m => Applicative (Parser m a) where
517+instance MonadThrow m => Applicative (Parser m a) where
416518 {-# INLINE pure #-}
417519 pure = yield
418520
@@ -445,7 +547,17 @@ alt (Parser stepL initialL extractL) (Parser stepR initialR extractR) =
445547
446548 where
447549
448− initial = AltParseL 0 <$> initialL
550+ initial = do
551+ resL <- initialL
552+ case resL of
553+ IPartial sl -> return $ IPartial $ AltParseL 0 sl
554+ IDone bl -> return $ IDone bl
555+ IError _ -> do
556+ resR <- initialR
557+ return $ case resR of
558+ IPartial sr -> IPartial $ AltParseR sr
559+ IDone br -> IDone br
560+ IError err -> IError err
449561
450562 -- Once a parser yields at least one value it cannot fail. This
451563 -- restriction helps us make backtracking more efficient, as we do not need
@@ -461,8 +573,12 @@ alt (Parser stepL initialL extractL) (Parser stepR initialR extractR) =
461573 return $ Continue n (AltParseL (cnt + 1 - n) s)
462574 Done n b -> return $ Done n b
463575 Error _ -> do
464− rR <- initialR
465− return $ Continue (cnt + 1) (AltParseR rR)
576+ res <- initialR
577+ return
578+ $ case res of
579+ IPartial rR -> Continue (cnt + 1) (AltParseR rR)
580+ IDone b -> Done (cnt + 1) b
581+ IError err -> Error err
466582
467583 step (AltParseR st) a = do
468584 r <- stepR st a
@@ -486,14 +602,25 @@ splitMany (Fold fstep finitial fextract) (Parser step1 initial1 extract1) =
486602
487603 where
488604
489− initial = do
490− ps <- initial1 -- parse state
491− res <- finitial -- fold state
492− return
493− $ case res of
494− FL.Partial fs -> Tuple3' ps (0 :: Int) fs
495− FL.Done _ ->
496− error "splitMany: Done in initial not implemented"
605+ -- Caution! There is mutual recursion here, inlining the right functions is
606+ -- important.
607+
608+ {-# INLINE handleCollect #-}
609+ handleCollect partial done fres =
610+ case fres of
611+ FL.Partial fs -> do
612+ pres <- initial1
613+ case pres of
614+ IPartial ps -> return $ partial $ Tuple3' ps 0 fs
615+ IDone pb ->
616+ runCollectorWith (handleCollect partial done) fs pb
617+ IError _ -> done <$> fextract fs
618+ FL.Done fb -> return $ done fb
619+
620+ -- Do not inline this
621+ runCollectorWith cont fs pb = fstep fs pb >>= cont
622+
623+ initial = finitial >>= handleCollect IPartial IDone
497624
498625 {-# INLINE step #-}
499626 step (Tuple3' st cnt fs) a = do
@@ -507,13 +634,8 @@ splitMany (Fold fstep finitial fextract) (Parser step1 initial1 extract1) =
507634 assert (cnt1 - n >= 0) (return ())
508635 return $ Continue n (Tuple3' s (cnt1 - n) fs)
509636 Done n b -> do
510− s <- initial1
511− fs1 <- fstep fs b
512637 assert (cnt1 - n >= 0) (return ())
513− return
514− $ case fs1 of
515− FL.Partial s1 -> Partial n (Tuple3' s 0 s1)
516− FL.Done b1 -> Done n b1
638+ fstep fs b >>= handleCollect (Partial n) (Done n)
517639 Error _ -> do
518640 xs <- fextract fs
519641 return $ Done cnt1 xs
@@ -540,14 +662,39 @@ splitSome (Fold fstep finitial fextract) (Parser step1 initial1 extract1) =
540662
541663 where
542664
665+ -- Caution! There is mutual recursion here, inlining the right functions is
666+ -- important.
667+
668+ {-# INLINE handleCollect #-}
669+ handleCollect partial done fres =
670+ case fres of
671+ FL.Partial fs -> do
672+ pres <- initial1
673+ case pres of
674+ IPartial ps -> return $ partial $ Tuple3' ps 0 $ Right fs
675+ IDone pb ->
676+ runCollectorWith (handleCollect partial done) fs pb
677+ IError _ -> done <$> fextract fs
678+ FL.Done fb -> return $ done fb
679+
680+ -- Do not inline this
681+ runCollectorWith cont fs pb = fstep fs pb >>= cont
682+
543683 initial = do
544− ps <- initial1 -- parse state
545− res <- finitial -- fold state
546− return
547− $ case res of
548− FL.Partial fs -> Tuple3' ps (0 :: Int) (Left fs)
549− FL.Done _ ->
550− error "splitSome: Done/Error in initial not implemented"
684+ fres <- finitial
685+ case fres of
686+ FL.Partial fs -> do
687+ pres <- initial1
688+ case pres of
689+ IPartial ps -> return $ IPartial $ Tuple3' ps 0 $ Left fs
690+ IDone pb ->
691+ runCollectorWith (handleCollect IPartial IDone) fs pb
692+ IError err -> return $ IError err
693+ FL.Done _ ->
694+ return
695+ $ IError
696+ $ "splitSome: The collecting fold terminated without"
697+ ++ " consuming any elements."
551698
552699 {-# INLINE step #-}
553700 step (Tuple3' st cnt (Left fs)) a = do
@@ -563,12 +710,7 @@ splitSome (Fold fstep finitial fextract) (Parser step1 initial1 extract1) =
563710 return $ Continue n (Tuple3' s (cnt1 - n) (Left fs))
564711 Done n b -> do
565712 assert (cnt1 - n >= 0) (return ())
566− s <- initial1
567− fs1 <- fstep fs b
568− return
569− $ case fs1 of
570− FL.Partial s1 -> Partial n (Tuple3' s 0 (Right s1))
571− FL.Done b1 -> Done n b1
713+ fstep fs b >>= handleCollect (Partial n) (Done n)
572714 Error err -> return $ Error err
573715 step (Tuple3' st cnt (Right fs)) a = do
574716 r <- step1 st a
@@ -582,12 +724,7 @@ splitSome (Fold fstep finitial fextract) (Parser step1 initial1 extract1) =
582724 return $ Continue n (Tuple3' s (cnt1 - n) (Right fs))
583725 Done n b -> do
584726 assert (cnt1 - n >= 0) (return ())
585− s <- initial1
586− fs1 <- fstep fs b
587− return
588− $ case fs1 of
589− FL.Partial s1 -> Partial n (Tuple3' s 0 (Right s1))
590− FL.Done b1 -> Done n b1
727+ fstep fs b >>= handleCollect (Partial n) (Done n)
591728 Error _ -> Done cnt1 <$> fextract fs
592729
593730 -- XXX The "try" may impact performance if this parser is used as a scan
@@ -613,10 +750,7 @@ splitSome (Fold fstep finitial fextract) (Parser step1 initial1 extract1) =
613750--
614751{-# INLINE_NORMAL die #-}
615752die :: MonadThrow m => String -> Parser m a b
616−die err =
617− Parser (\_ _ -> pure $ Error err) -- step
618− (pure ()) -- initial
619− (\_ -> throwM $ ParseError err) -- extract
753+die err = Parser undefined (pure (IError err)) undefined
620754
621755-- | See 'Streamly.Internal.Data.Parser.dieM'.
622756--
@@ -624,10 +758,7 @@ die err =
624758--
625759{-# INLINE dieM #-}
626760dieM :: MonadThrow m => m String -> Parser m a b
627−dieM err =
628− Parser (\_ _ -> Error <$> err) -- step
629− (pure ()) -- initial
630− (\_ -> err >>= throwM . ParseError) -- extract
761+dieM err = Parser undefined (IError <$> err) undefined
631762
632763-- Note: The default implementations of "some" and "many" loop infinitely
633764-- because of the strict pattern match on both the arguments in applicative and
@@ -659,47 +790,70 @@ instance MonadCatch m => Alternative (Parser m a) where
659790 some = splitSome toList
660791
661792{-# ANN type ConcatParseState Fuse #-}
662−data ConcatParseState sl p = ConcatParseL sl | ConcatParseR p
793+data ConcatParseState sl m a b =
794+ ConcatParseL sl
795+ | forall s. ConcatParseR (s -> a -> m (Step s b)) s (s -> m b)
663796
664797-- | See 'Streamly.Internal.Data.Parser.concatMap'.
665798--
666799-- /Internal/
667800--
668801{-# INLINE concatMap #-}
669−concatMap :: Monad m => (b -> Parser m a c) -> Parser m a b -> Parser m a c
802+concatMap :: MonadThrow m =>
803+ (b -> Parser m a c) -> Parser m a b -> Parser m a c
670804concatMap func (Parser stepL initialL extractL) = Parser step initial extract
671805
672806 where
673807
674− initial = ConcatParseL <$> initialL
808+ {-# INLINE initializeR #-}
809+ initializeR (Parser stepR initialR extractR) = do
810+ resR <- initialR
811+ return $ case resR of
812+ IPartial sr -> IPartial $ ConcatParseR stepR sr extractR
813+ IDone br -> IDone br
814+ IError err -> IError err
815+
816+ initial = do
817+ res <- initialL
818+ case res of
819+ IPartial s -> return $ IPartial $ ConcatParseL s
820+ IDone b -> initializeR (func b)
821+ IError err -> return $ IError err
822+
823+ {-# INLINE initializeRL #-}
824+ initializeRL n (Parser stepR initialR extractR) = do
825+ resR <- initialR
826+ return $ case resR of
827+ IPartial sr -> Continue n $ ConcatParseR stepR sr extractR
828+ IDone br -> Done n br
829+ IError err -> Error err
675830
676831 step (ConcatParseL st) a = do
677832 r <- stepL st a
678− return $ case r of
679− Partial n s -> Continue n (ConcatParseL s)
680− Continue n s -> Continue n (ConcatParseL s)
681− Done n b -> Continue n (ConcatParseR (func b))
682− Error err -> Error err
833+ case r of
834+ Partial n s -> return $ Continue n (ConcatParseL s)
835+ Continue n s -> return $ Continue n (ConcatParseL s)
836+ Done n b -> initializeRL n (func b)
837+ Error err -> return $ Error err
683838
684− step (ConcatParseR (Parser stepR initialR extractR)) a = do
685− st <- initialR
839+ step (ConcatParseR stepR st extractR) a = do
686840 r <- stepR st a
687841 return $ case r of
688− Partial n s ->
689− Partial n (ConcatParseR (Parser stepR (return s) extractR))
690− Continue n s ->
691− Continue n (ConcatParseR (Parser stepR (return s) extractR))
842+ Partial n s -> Partial n $ ConcatParseR stepR s extractR
843+ Continue n s -> Continue n $ ConcatParseR stepR s extractR
692844 Done n b -> Done n b
693845 Error err -> Error err
694846
695− extract (ConcatParseR (Parser _ initialR extractR)) =
696− initialR >>= extractR
697−
698− extract (ConcatParseL sL) = extractL sL >>= f . func
699−
700− where
847+ {-# INLINE extractP #-}
848+ extractP (Parser _ initialR extractR) = do
849+ res <- initialR
850+ case res of
851+ IPartial s -> extractR s
852+ IDone b -> return b
853+ IError err -> throwM $ ParseError err
701854
702− f (Parser _ initialR extractR) = initialR >>= extractR
855+ extract (ConcatParseR _ s extractR) = extractR s
856+ extract (ConcatParseL sL) = extractL sL >>= extractP . func
703857
704858-- Note: The monad instance has quadratic performance complexity. It works fine
705859-- for small number of compositions but for a scalable implementation we need a
@@ -707,7 +861,7 @@ concatMap func (Parser stepL initialL extractL) = Parser step initial extract
707861
708862-- | See documentation of 'Streamly.Internal.Data.Parser.ParserK.Types.Parser'.
709863--
710−instance Monad m => Monad (Parser m a) where
864+instance MonadThrow m => Monad (Parser m a) where
711865 {-# INLINE return #-}
712866 return = pure
713867
src/Streamly/Internal/Data/Parser/ParserK/Types.hs+18−12
@@ -112,15 +112,19 @@ newtype Parser m a b = MkParser
112112parseDToK
113113 :: MonadCatch m
114114 => (s -> a -> m (D.Step s b))
115− -> m s
115+ -> m (D.Initial s b)
116116 -> (s -> m b)
117117 -> Int
118118 -> (Int, Int)
119119 -> ((Int, Int) -> Parse b -> m (Driver m a r))
120120 -> m (Driver m a r)
121121
122−parseDToK pstep initial extract leftover (0, _) cont =
123− return $ Continue leftover (parseCont initial)
122+parseDToK pstep initial extract leftover (0, _) cont = do
123+ res <- initial
124+ case res of
125+ D.IPartial r -> return $ Continue leftover (parseCont (return r))
126+ D.IDone b -> cont (0,0) (Done 0 b)
127+ D.IError err -> cont (0,0) (Error err)
124128
125129 where
126130
@@ -140,8 +144,12 @@ parseDToK pstep initial extract leftover (0, _) cont =
140144 Left (e :: D.ParseError) -> cont (0,0) (Error (displayException e))
141145 Right b -> cont (0,0) (Done 0 b)
142146
143−parseDToK pstep initial extract leftover (level, count) cont =
144− return $ Continue leftover (parseCont count initial)
147+parseDToK pstep initial extract leftover (level, count) cont = do
148+ res <- initial
149+ case res of
150+ D.IPartial r -> return $ Continue leftover (parseCont count (return r))
151+ D.IDone b -> cont (level,count) (Done 0 b)
152+ D.IError err -> cont (level,count) (Error err)
145153
146154 where
147155
@@ -203,7 +211,7 @@ extractParse cont = do
203211 Continue _ cont1 -> extractParse cont1
204212 Failed e -> throwM $ D.ParseError e
205213
206−data FromParserK b e c = FPKDone !Int !b | FPKError !e | FPKCont c
214+data FromParserK b c = FPKDone !Int !b | FPKCont c
207215
208216-- | Convert a CPS style 'Parser' to a direct style 'D.Parser'.
209217--
@@ -221,10 +229,10 @@ fromParserK parser = D.Parser step initial extract
221229 initial = do
222230 r <- runParser parser 0 (0,0) parserDone
223231 return $ case r of
224− Stop n b -> FPKDone n b
225− Failed e -> FPKError e
226− Partial _ cont -> FPKCont cont -- XXX can we get this?
227− Continue _ cont -> FPKCont cont
232+ Stop n b -> D.IPartial $ FPKDone n b
233+ Failed e -> D.IError e
234+ Partial _ cont -> D.IPartial $ FPKCont cont -- XXX can we get this?
235+ Continue _ cont -> D.IPartial $ FPKCont cont
228236
229237 -- Note, we can only reach FPKDone and FPKError from "initial". FPKCont
230238 -- always transitions to only FPKCont. The input remains unconsumed in
@@ -232,7 +240,6 @@ fromParserK parser = D.Parser step initial extract
232240 step (FPKDone n b) _ = do
233241 assertM (n == 0)
234242 return $ D.Done (n + 1) b
235− step (FPKError e) _ = return $ D.Error e
236243 step (FPKCont cont) a = do
237244 r <- cont (Just a)
238245 return $ case r of
@@ -243,7 +250,6 @@ fromParserK parser = D.Parser step initial extract
243250
244251 -- Note, we can only reach FPKDone and FPKError from "initial".
245252 extract (FPKDone _ b) = return b
246− extract (FPKError e) = throwM $ D.ParseError e
247253 extract (FPKCont cont) = extractParse cont
248254
249255#ifndef DISABLE_FUSION
src/Streamly/Internal/Data/Producer/Source.hs+7−2
@@ -122,8 +122,13 @@ parseD
122122 (Producer ustep uinject uextract)
123123 seed = do
124124
125− state <- uinject seed
126− initial >>= go SPEC state (List [])
125+ res <- initial
126+ case res of
127+ ParserD.IPartial s -> do
128+ state <- uinject seed
129+ go SPEC state (List []) s
130+ ParserD.IDone b -> return (b, seed)
131+ ParserD.IError err -> throwM $ ParseError err
127132
128133 where
129134
src/Streamly/Internal/Data/Stream/IsStream/Eliminate.hs+1−1
@@ -338,7 +338,7 @@ runSink = fold . toFold
338338--
339339{-# INLINE_NORMAL parseD #-}
340340parseD :: MonadThrow m => PRD.Parser m a b -> SerialT m a -> m b
341−parseD (PRD.Parser step initial extract) = P.parselMx' step initial extract
341+parseD p = D.parse p . toStreamD
342342
343343{-# INLINE parseK #-}
344344parseK :: MonadThrow m => PRK.Parser m a b -> SerialT m a -> m b
src/Streamly/Internal/Data/Stream/StreamD/Eliminate.hs+63−1
@@ -16,7 +16,7 @@ module Streamly.Internal.Data.Stream.StreamD.Eliminate
1616 foldOnce -- XXX rename to "fold"
1717
1818 -- -- * Running a 'Parser'
19− -- , parse
19+ , parse
2020
2121 -- * Stream Deconstruction
2222 , uncons
@@ -83,6 +83,7 @@ import GHC.Types (SPEC(..))
8383import Streamly.Internal.Data.Parser (ParseError(..))
8484
8585import qualified Streamly.Internal.Data.Parser as PR
86+import qualified Streamly.Internal.Data.Parser.ParserD as PRD
8687
8788import Prelude hiding
8889 ( all, any, elem, foldr, foldr1, head, last, lookup, mapM, mapM_
@@ -193,6 +194,67 @@ parselMx' pstep initial extract (Stream step state) = do
193194 PR.Done _ b -> return b
194195 PR.Error err -> throwM $ ParseError err
195196
197+-- | Run a 'Parse' over a stream.
198+{-# INLINE_NORMAL parse #-}
199+parse :: MonadThrow m => PRD.Parser m a b -> Stream m a -> m b
200+parse (PRD.Parser pstep initial extract) (Stream step state) = do
201+ res <- initial
202+ case res of
203+ PRD.IPartial s -> go SPEC state (List []) s
204+ PRD.IDone b -> return b
205+ PRD.IError err -> throwM $ ParseError err
206+
207+ where
208+
209+ -- XXX currently we are using a dumb list based approach for backtracking
210+ -- buffer. This can be replaced by a sliding/ring buffer using Data.Array.
211+ -- That will allow us more efficient random back and forth movement.
212+ {-# INLINE go #-}
213+ go !_ st buf !pst = do
214+ r <- step defState st
215+ case r of
216+ Yield x s -> do
217+ pRes <- pstep pst x
218+ case pRes of
219+ PR.Partial 0 pst1 -> go SPEC s (List []) pst1
220+ PR.Partial n pst1 -> do
221+ assert (n <= length (x:getList buf)) (return ())
222+ let src0 = Prelude.take n (x:getList buf)
223+ src = Prelude.reverse src0
224+ gobuf SPEC s (List []) (List src) pst1
225+ PR.Continue 0 pst1 -> go SPEC s (List (x:getList buf)) pst1
226+ PR.Continue n pst1 -> do
227+ assert (n <= length (x:getList buf)) (return ())
228+ let (src0, buf1) = splitAt n (x:getList buf)
229+ src = Prelude.reverse src0
230+ gobuf SPEC s (List buf1) (List src) pst1
231+ -- Specialcase the Done 1 case
232+ PR.Done _ b -> return b
233+ PR.Error err -> throwM $ ParseError err
234+ Skip s -> go SPEC s buf pst
235+ Stop -> extract pst
236+
237+ gobuf !_ s buf (List []) !pst = go SPEC s buf pst
238+ gobuf !_ s buf (List (x:xs)) !pst = do
239+ pRes <- pstep pst x
240+ case pRes of
241+ PR.Partial 0 pst1 ->
242+ gobuf SPEC s (List []) (List xs) pst1
243+ PR.Partial n pst1 -> do
244+ assert (n <= length (x:getList buf)) (return ())
245+ let src0 = Prelude.take n (x:getList buf)
246+ src = Prelude.reverse src0 ++ xs
247+ gobuf SPEC s (List []) (List src) pst1
248+ PR.Continue 0 pst1 ->
249+ gobuf SPEC s (List (x:getList buf)) (List xs) pst1
250+ PR.Continue n pst1 -> do
251+ assert (n <= length (x:getList buf)) (return ())
252+ let (src0, buf1) = splitAt n (x:getList buf)
253+ src = Prelude.reverse src0 ++ xs
254+ gobuf SPEC s (List buf1) (List src) pst1
255+ PR.Done _ b -> return b
256+ PR.Error err -> throwM $ ParseError err
257+
196258------------------------------------------------------------------------------
197259-- Specialized Folds
198260------------------------------------------------------------------------------
src/Streamly/Internal/Data/Stream/StreamD/Nesting.hs+49−34
@@ -986,13 +986,28 @@ parseMany (PRD.Parser pstep initial extract) (Stream step state) =
986986 stepOuter gst (ParseChunksInit [] st) = do
987987 r <- step (adaptState gst) st
988988 case r of
989− Yield x s -> initial >>= return . Skip . ParseChunksBuf [x] s []
989+ Yield x s -> do
990+ res <- initial
991+ case res of
992+ PRD.IPartial ps ->
993+ return $ Skip $ ParseChunksBuf [x] s [] ps
994+ PRD.IDone pb ->
995+ let next = ParseChunksInit [x] s
996+ in return $ Skip $ ParseChunksYield pb next
997+ PRD.IError err -> throwM $ ParseError err
990998 Skip s -> return $ Skip $ ParseChunksInit [] s
991999 Stop -> return Stop
9921000
9931001 -- Buffer is not empty, go to buffered processing loop
9941002 stepOuter _ (ParseChunksInit src st) = do
995− initial >>= return . Skip . ParseChunksBuf src st []
1003+ res <- initial
1004+ case res of
1005+ PRD.IPartial ps ->
1006+ return $ Skip $ ParseChunksBuf src st [] ps
1007+ PRD.IDone pb ->
1008+ let next = ParseChunksInit src st
1009+ in return $ Skip $ ParseChunksYield pb next
1010+ PRD.IError err -> throwM $ ParseError err
9961011
9971012 -- XXX we just discard any leftover input at the end
9981013 stepOuter _ (ParseChunksInitLeftOver _) = return Stop
@@ -1067,12 +1082,12 @@ parseMany (PRD.Parser pstep initial extract) (Stream step state) =
10671082 stepOuter _ (ParseChunksYield a next) = return $ Yield a next
10681083
10691084{-# ANN type ConcatParseState Fuse #-}
1070−data ConcatParseState x inpBuf st p =
1085+data ConcatParseState b inpBuf st p m a =
10711086 ConcatParseInit inpBuf st p
10721087 | ConcatParseInitLeftOver inpBuf
1073− | ConcatParseStream st inpBuf p
1074− | ConcatParseBuf inpBuf st inpBuf p
1075− | ConcatParseYield x (ConcatParseState x inpBuf st p)
1088+ | forall s. ConcatParseStream st inpBuf (s -> a -> m (PRD.Step s b)) s (s -> m b)
1089+ | forall s. ConcatParseBuf inpBuf st inpBuf (s -> a -> m (PRD.Step s b)) s (s -> m b)
1090+ | ConcatParseYield b (ConcatParseState b inpBuf st p m a)
10761091
10771092{-# INLINE_NORMAL parseIterate #-}
10781093parseIterate
@@ -1089,44 +1104,51 @@ parseIterate func seed (Stream step state) =
10891104 {-# INLINE_LATE stepOuter #-}
10901105 -- Buffer is empty, go to stream processing loop
10911106 stepOuter _ (ConcatParseInit [] st (PRD.Parser pstep initial extract)) = do
1092− initial >>= \r -> return $ Skip $ ConcatParseStream st []
1093− (PRD.Parser pstep (return r) extract)
1107+ res <- initial
1108+ case res of
1109+ PRD.IPartial ps ->
1110+ return $ Skip $ ConcatParseStream st [] pstep ps extract
1111+ PRD.IDone pb ->
1112+ let next = ConcatParseInit [] st (func pb)
1113+ in return $ Skip $ ConcatParseYield pb next
1114+ PRD.IError err -> throwM $ ParseError err
10941115
10951116 -- Buffer is not empty, go to buffered processing loop
10961117 stepOuter _ (ConcatParseInit src st
10971118 (PRD.Parser pstep initial extract)) = do
1098− initial >>= \r -> return $ Skip $ ConcatParseBuf src st []
1099− (PRD.Parser pstep (return r) extract)
1119+ res <- initial
1120+ case res of
1121+ PRD.IPartial ps ->
1122+ return $ Skip $ ConcatParseBuf src st [] pstep ps extract
1123+ PRD.IDone pb ->
1124+ let next = ConcatParseInit src st (func pb)
1125+ in return $ Skip $ ConcatParseYield pb next
1126+ PRD.IError err -> throwM $ ParseError err
11001127
11011128 -- XXX we just discard any leftover input at the end
11021129 stepOuter _ (ConcatParseInitLeftOver _) = return Stop
11031130
11041131 -- Buffer is empty process elements from the stream
1105− stepOuter gst (ConcatParseStream st buf
1106− p@(PRD.Parser pstep initial extract)) = do
1132+ stepOuter gst (ConcatParseStream st buf pstep pst extract) = do
11071133 r <- step (adaptState gst) st
11081134 case r of
11091135 Yield x s -> do
1110− pst <- initial
11111136 pRes <- pstep pst x
11121137 case pRes of
11131138 PR.Partial 0 pst1 ->
1114− return $ Skip $ ConcatParseStream s []
1115− (PRD.Parser pstep (return pst1) extract)
1139+ return $ Skip $ ConcatParseStream s [] pstep pst1 extract
11161140 PR.Partial n pst1 -> do
11171141 assert (n <= length (x:buf)) (return ())
11181142 let src0 = Prelude.take n (x:buf)
11191143 src = Prelude.reverse src0
1120− return $ Skip $ ConcatParseBuf src s []
1121− (PRD.Parser pstep (return pst1) extract)
1144+ return $ Skip $ ConcatParseBuf src s [] pstep pst1 extract
11221145 -- PR.Continue 0 pst1 ->
11231146 -- return $ Skip $ ConcatParseStream s (x:buf) pst1
11241147 PR.Continue n pst1 -> do
11251148 assert (n <= length (x:buf)) (return ())
11261149 let (src0, buf1) = splitAt n (x:buf)
11271150 src = Prelude.reverse src0
1128− return $ Skip $ ConcatParseBuf src s buf1
1129− (PRD.Parser pstep (return pst1) extract)
1151+ return $ Skip $ ConcatParseBuf src s buf1 pstep pst1 extract
11301152 -- XXX Specialize for Stop 0 common case?
11311153 PR.Done n b -> do
11321154 assert (n <= length (x:buf)) (return ())
@@ -1134,40 +1156,33 @@ parseIterate func seed (Stream step state) =
11341156 return $ Skip $
11351157 ConcatParseYield b (ConcatParseInit src s (func b))
11361158 PR.Error err -> throwM $ ParseError err
1137− Skip s -> return $ Skip $ ConcatParseStream s buf p
1159+ Skip s -> return $ Skip $ ConcatParseStream s buf pstep pst extract
11381160 Stop -> do
1139− pst <- initial
11401161 b <- extract pst
11411162 let src = Prelude.reverse buf
1142− return $ Skip $
1143− ConcatParseYield b (ConcatParseInitLeftOver src)
1163+ return $ Skip $ ConcatParseYield b (ConcatParseInitLeftOver src)
11441164
11451165 -- go back to stream processing mode
1146− stepOuter _ (ConcatParseBuf [] s buf p) =
1147− return $ Skip $ ConcatParseStream s buf p
1166+ stepOuter _ (ConcatParseBuf [] s buf pstep ps extract) =
1167+ return $ Skip $ ConcatParseStream s buf pstep ps extract
11481168
11491169 -- buffered processing loop
1150− stepOuter _ (ConcatParseBuf (x:xs) s buf
1151− (PRD.Parser pstep initial extract)) = do
1152− pst <- initial
1170+ stepOuter _ (ConcatParseBuf (x:xs) s buf pstep pst extract) = do
11531171 pRes <- pstep pst x
11541172 case pRes of
11551173 PR.Partial 0 pst1 ->
1156− return $ Skip $ ConcatParseBuf xs s []
1157− (PRD.Parser pstep (return pst1) extract)
1174+ return $ Skip $ ConcatParseBuf xs s [] pstep pst1 extract
11581175 PR.Partial n pst1 -> do
11591176 assert (n <= length (x:buf)) (return ())
11601177 let src0 = Prelude.take n (x:buf)
11611178 src = Prelude.reverse src0 ++ xs
1162− return $ Skip $ ConcatParseBuf src s []
1163− (PRD.Parser pstep (return pst1) extract)
1179+ return $ Skip $ ConcatParseBuf src s [] pstep pst1 extract
11641180 -- PR.Continue 0 pst1 -> return $ Skip $ ConcatParseBuf xs s (x:buf) pst1
11651181 PR.Continue n pst1 -> do
11661182 assert (n <= length (x:buf)) (return ())
11671183 let (src0, buf1) = splitAt n (x:buf)
11681184 src = Prelude.reverse src0 ++ xs
1169− return $ Skip $ ConcatParseBuf src s buf1
1170− (PRD.Parser pstep (return pst1) extract)
1185+ return $ Skip $ ConcatParseBuf src s buf1 pstep pst1 extract
11711186 -- XXX Specialize for Stop 0 common case?
11721187 PR.Done n b -> do
11731188 assert (n <= length (x:buf)) (return ())