Skip to content

Commit 0253ec0

Browse files
committed
WIP
1 parent 96ad113 commit 0253ec0

File tree

2 files changed

+38
-29
lines changed

2 files changed

+38
-29
lines changed

src/Parsing/String/Replace.purs

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -277,20 +277,28 @@ splitCapT input sep = do
277277
-- 2. The sep parser succeeds but does not consume any input
278278
runParserT input (Tuple <$> (splitCapCombinator sep) <*> rest) >>= case _ of
279279
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
281281
Nothing -> pure (singleton (Left input))
282282
Just {head: Tuple hunmatched hmatched ,tail} ->
283283
let term =
284284
if String.null remain then
285285
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
287289
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
289293
else
290294
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
292298
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
294302
list = foldl (\ls (Tuple unmatched matched) ->
295303
if String.null unmatched then
296304
(Right matched : ls)
@@ -301,43 +309,47 @@ splitCapT input sep = do
301309
pure $ unsafePartial $ fromJust $ fromList list
302310

303311
-- | 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.
306317
splitCapCombinator
307318
:: forall m a
308319
. Monad m
309320
=> 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}
312324
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
315327
optionMaybe (try $ anyTill sep) >>= case _ of
316328
Just (Tuple unmatched matched) -> do
329+
Position {index:posIndex} <- position
317330
let
318331
carry_unmatched = case carry of
319332
Nothing -> unmatched
320333
Just cp -> CodePoint.singleton cp <> unmatched
321-
Position {index:posIndex} <- position
322334
if posIndex == lastPosIndex then do
323335
-- sep succeeded but consumed no input, so advance by one codepoint and
324336
-- carry the codepoint over to cons to the next unmatched
325-
carryNext <- anyCodePoint
337+
carryNext <- optionMaybe anyCodePoint
326338
pure $ Loop
327339
{ 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
331343
}
332344
else
333345
pure $ Loop
334346
{ lastPosIndex: posIndex
335347
, 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
338350
}
339351
Nothing -> -- no pattern found, so we're done
340-
pure (Done (Tuple list arraySize))
352+
pure (Done {carry,rlist,arraySize})
341353

342354

343355
-- | #### Split on and capture all patterns

test/Main.purs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -925,20 +925,17 @@ main = do
925925
, expected: "aBaBa"
926926
}
927927
assertEqual' "splitCap8"
928-
{ actual: splitCap "aa" (lookAhead $ string "a")
929-
, expected: NonEmptyList $ Right "a" :| Left "a" : Right "a" : Left "a" : Nil
928+
{ actual: splitCap "aa" (lookAhead $ string "a" *> pure unit)
929+
, expected: NonEmptyList $ Right unit :| Left "a" : Right unit : Left "a" : Nil
930930
}
931931
assertEqual' "splitCap8B"
932-
{ actual: splitCap "BaBa" (lookAhead $ string "B")
933-
, expected: NonEmptyList $ Right "B" :| Left "Ba" : Right "B" : Left "Ba" : Nil
932+
{ actual: splitCap "BaBa" (lookAhead $ string "B" *> pure unit)
933+
, expected: NonEmptyList $ Right unit :| Left "Ba" : Right unit : Left "Ba" : Nil
934934
}
935935
assertEqual' "splitCap9" $
936-
let
937-
output = splitCap "aBaBa" (match $ lookAhead $ string "B")
938-
in
939-
{ actual: fold (either identity fst <$> output)
940-
, expected: "aaa"
941-
}
936+
{ actual: splitCap "aBaBa" (match $ lookAhead $ string "B" *> pure unit)
937+
, expected: NonEmptyList $ Left "a" :| Right (Tuple "" unit) : Left "Ba" : Right (Tuple "" unit) : Left "Ba" : Nil
938+
}
942939
assertEqual' "streamEdit1"
943940
{ actual: streamEdit "aBa" (match $ string "B") fst
944941
, expected: "aBa"

0 commit comments

Comments
 (0)