@@ -277,20 +277,28 @@ splitCapT input sep = do
277
277
-- 2. The sep parser succeeds but does not consume any input
278
278
runParserT input (Tuple <$> (splitCapCombinator sep) <*> rest) >>= case _ of
279
279
Left _ -> pure (singleton (Left input))
280
- Right (Tuple ( Tuple rlist _) remain) -> case uncons rlist of
280
+ Right (Tuple {carry, rlist} remain) -> case uncons rlist of
281
281
Nothing -> pure (singleton (Left input))
282
282
Just {head: Tuple hunmatched hmatched ,tail} ->
283
283
let term =
284
284
if String .null remain then
285
285
if String .null hunmatched then
286
- (Right hmatched : Nil )
286
+ case carry of
287
+ Nothing -> Right hmatched : Nil
288
+ Just cp -> Right hmatched : Left (CodePoint .singleton cp) : Nil
287
289
else
288
- (Left hunmatched : Right hmatched : Nil )
290
+ case carry of
291
+ Nothing -> Left hunmatched : Right hmatched : Nil
292
+ Just cp -> Left hunmatched : Right hmatched : Left (CodePoint .singleton cp) : Nil
289
293
else
290
294
if String .null hunmatched then
291
- (Right hmatched : Left remain : Nil )
295
+ case carry of
296
+ Nothing -> Right hmatched : Left remain : Nil
297
+ Just cp -> Right hmatched : Left (CodePoint .singleton cp <> remain) : Nil
292
298
else
293
- (Left hunmatched : Right hmatched : Left remain : Nil )
299
+ case carry of
300
+ Nothing -> Left hunmatched : Right hmatched : Left remain : Nil
301
+ Just cp -> Left hunmatched : Right hmatched : Left (CodePoint .singleton cp <> remain) : Nil
294
302
list = foldl (\ls (Tuple unmatched matched) ->
295
303
if String .null unmatched then
296
304
(Right matched : ls)
@@ -301,43 +309,47 @@ splitCapT input sep = do
301
309
pure $ unsafePartial $ fromJust $ fromList list
302
310
303
311
-- | Internal splitCap helper combinator. Returns
304
- -- | - the reversed `many anyTill` List
305
- -- | - the length of the nonempty tuple elements in the List.
312
+ -- | - The reversed `many anyTill` List.
313
+ -- | - The length of the nonempty tuple elements in the List.
314
+ -- | - One CodePoint carried over from the last parser match, in case the
315
+ -- | parser succeeded without consuming any input. This is where most
316
+ -- | of the complexity comes from.
306
317
splitCapCombinator
307
318
:: forall m a
308
319
. Monad m
309
320
=> ParserT String m a
310
- -> ParserT String m (Tuple (List (Tuple String a )) Int )
311
- splitCapCombinator sep = tailRecM accum {lastPosIndex:0 ,carry:Nothing ,list:Nil ,arraySize:0 }
321
+ -> ParserT String m { carry :: Maybe CodePoint ,rlist :: List (Tuple String a ),arraySize :: Int }
322
+
323
+ splitCapCombinator sep = tailRecM accum {lastPosIndex:0 ,carry:Nothing ,rlist:Nil ,arraySize:0 }
312
324
where
313
- accum :: { lastPosIndex :: Int ,carry :: Maybe CodePoint ,list :: List (Tuple String a ),arraySize :: Int } -> ParserT String m (Step { lastPosIndex :: Int ,carry :: Maybe CodePoint ,list :: List (Tuple String a ),arraySize :: Int } ( Tuple ( List (Tuple String a )) Int ) )
314
- accum {lastPosIndex,carry,list ,arraySize} = do
325
+ accum :: { lastPosIndex :: Int ,carry :: Maybe CodePoint ,rlist :: List (Tuple String a ),arraySize :: Int } -> ParserT String m (Step { lastPosIndex :: Int ,carry :: Maybe CodePoint ,rlist :: List (Tuple String a ),arraySize :: Int } { carry :: Maybe CodePoint , rlist :: List (Tuple String a ), arraySize :: Int } )
326
+ accum {lastPosIndex,carry,rlist ,arraySize} = do
315
327
optionMaybe (try $ anyTill sep) >>= case _ of
316
328
Just (Tuple unmatched matched) -> do
329
+ Position {index:posIndex} <- position
317
330
let
318
331
carry_unmatched = case carry of
319
332
Nothing -> unmatched
320
333
Just cp -> CodePoint .singleton cp <> unmatched
321
- Position {index:posIndex} <- position
322
334
if posIndex == lastPosIndex then do
323
335
-- sep succeeded but consumed no input, so advance by one codepoint and
324
336
-- carry the codepoint over to cons to the next unmatched
325
- carryNext <- anyCodePoint
337
+ carryNext <- optionMaybe anyCodePoint
326
338
pure $ Loop
327
339
{ lastPosIndex: posIndex+1
328
- , carry: Just carryNext
329
- , list : (Tuple carry_unmatched matched : list )
330
- , arraySize: if String .null unmatched then arraySize + 1 else arraySize + 2
340
+ , carry: carryNext
341
+ , rlist : (Tuple carry_unmatched matched : rlist )
342
+ , arraySize: if String .null carry_unmatched then arraySize + 1 else arraySize + 2
331
343
}
332
344
else
333
345
pure $ Loop
334
346
{ lastPosIndex: posIndex
335
347
, carry: Nothing
336
- , list : (Tuple carry_unmatched matched : list )
337
- , arraySize: if String .null unmatched then arraySize + 1 else arraySize + 2
348
+ , rlist : (Tuple carry_unmatched matched : rlist )
349
+ , arraySize: if String .null carry_unmatched then arraySize + 1 else arraySize + 2
338
350
}
339
351
Nothing -> -- no pattern found, so we're done
340
- pure (Done ( Tuple list arraySize) )
352
+ pure (Done {carry,rlist, arraySize} )
341
353
342
354
343
355
-- | #### Split on and capture all patterns
0 commit comments