Skip to content

Commit 3fe6fe2

Browse files
committed
wip: on the way to total un-switching while converting to non-mutating
1 parent eb6e0e0 commit 3fe6fe2

File tree

1 file changed

+29
-100
lines changed

1 file changed

+29
-100
lines changed

Sources/_StringProcessing/Engine/MEQuantify.swift

Lines changed: 29 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -21,69 +21,44 @@ extension Processor {
2121
// TODO: this was pre-refactoring behavior, should we fatal error
2222
// instead?
2323
return false
24-
case (.eager, 0, nil):
25-
let (next, savePointRange) = input.runEagerZeroOrMoreQuantify(
24+
case (_, 0, nil):
25+
let (next, savePointRange) = input.runZeroOrMoreQuantify(
2626
payload,
2727
asciiBitset: asciiBitset,
2828
at: currentPosition,
2929
limitedBy: end)
30-
assert((next, savePointRange) == input.runGeneralQuantify(
31-
payload,
32-
asciiBitset: asciiBitset,
33-
at: currentPosition,
34-
limitedBy: end)!)
3530
if let savePointRange {
3631
savePoints.append(makeQuantifiedSavePoint(
3732
savePointRange, isScalarSemantics: payload.isScalarSemantics))
3833
}
3934
currentPosition = next
4035
return true
41-
case (.eager, 1, nil):
36+
case (_, 1, nil):
4237
guard let (next, savePointRange) = input.runEagerOneOrMoreQuantify(
4338
payload,
4439
asciiBitset: asciiBitset,
4540
at: currentPosition,
4641
limitedBy: end
4742
) else {
48-
assert(nil == input.runGeneralQuantify(
49-
payload,
50-
asciiBitset: asciiBitset,
51-
at: currentPosition,
52-
limitedBy: end))
5343
signalFailure()
5444
return false
5545
}
56-
assert((next, savePointRange) == input.runGeneralQuantify(
57-
payload,
58-
asciiBitset: asciiBitset,
59-
at: currentPosition,
60-
limitedBy: end)!)
6146
if let savePointRange {
6247
savePoints.append(makeQuantifiedSavePoint(
6348
savePointRange, isScalarSemantics: payload.isScalarSemantics))
6449
}
6550
currentPosition = next
6651
return true
67-
case (.eager, _, nil):
68-
guard let (next, savePointRange) = input.runEagerNOrMoreQuantify(
52+
case (_, _, nil):
53+
guard let (next, savePointRange) = input.runNOrMoreQuantify(
6954
payload,
7055
asciiBitset: asciiBitset,
7156
at: currentPosition,
7257
limitedBy: end
7358
) else {
74-
assert(nil == input.runGeneralQuantify(
75-
payload,
76-
asciiBitset: asciiBitset,
77-
at: currentPosition,
78-
limitedBy: end))
7959
signalFailure()
8060
return false
8161
}
82-
assert((next, savePointRange) == input.runGeneralQuantify(
83-
payload,
84-
asciiBitset: asciiBitset,
85-
at: currentPosition,
86-
limitedBy: end)!)
8762
if let savePointRange {
8863
savePoints.append(makeQuantifiedSavePoint(
8964
savePointRange, isScalarSemantics: payload.isScalarSemantics))
@@ -180,82 +155,35 @@ extension String {
180155
)? {
181156
assert(payload.quantKind != .reluctant)
182157

183-
var trips = 0
184-
var maxExtraTrips = payload.maxExtraTrips
185-
var currentPosition = currentPosition
186-
187-
while trips < payload.minTrips {
188-
guard let next = doQuantifyMatch(
189-
payload,
190-
asciiBitset: asciiBitset,
191-
at: currentPosition,
192-
limitedBy: end
193-
) else {
194-
return nil
195-
}
196-
currentPosition = next
197-
trips += 1
198-
}
199-
200-
if maxExtraTrips == 0 {
201-
// We're done
202-
return (currentPosition, nil)
158+
let minTrips = payload.minTrips
159+
let maxTrips: UInt64
160+
if let maxExtraTrips = payload.maxExtraTrips {
161+
maxTrips = payload.minTrips + maxExtraTrips
162+
} else {
163+
maxTrips = UInt64.max
203164
}
204165

205-
guard let next = doQuantifyMatch(
166+
return _runEagerNOrMoreQuantify(
206167
payload,
168+
minTrips: minTrips,
169+
maxTrips: maxTrips,
207170
asciiBitset: asciiBitset,
208171
at: currentPosition,
209-
limitedBy: end
210-
) else {
211-
return (currentPosition, nil)
212-
}
213-
maxExtraTrips = maxExtraTrips.map { $0 - 1 }
214-
215-
// Remember the range of valid positions in case we can create a quantified
216-
// save point
217-
let rangeStart = currentPosition
218-
var rangeEnd = currentPosition
219-
currentPosition = next
220-
221-
while true {
222-
if maxExtraTrips == 0 { break }
223-
224-
guard let next = doQuantifyMatch(
225-
payload,
226-
asciiBitset: asciiBitset,
227-
at: currentPosition,
228-
limitedBy: end
229-
) else {
230-
break
231-
}
232-
maxExtraTrips = maxExtraTrips.map({$0 - 1})
233-
rangeEnd = currentPosition
234-
currentPosition = next
235-
}
236-
237-
if payload.quantKind == .eager {
238-
return (currentPosition, rangeStart..<rangeEnd)
239-
} else {
240-
// No backtracking permitted after a successful advance
241-
assert(payload.quantKind == .possessive)
242-
}
243-
return (currentPosition, nil)
172+
limitedBy: end)
244173
}
245174

246175
/// Specialized quantify instruction interpreter for `*`, always succeeds
247-
fileprivate func runEagerZeroOrMoreQuantify(
176+
fileprivate func runZeroOrMoreQuantify(
248177
_ payload: QuantifyPayload,
249178
asciiBitset: ASCIIBitset?, // Necessary ugliness...
250179
at currentPosition: Index,
251180
limitedBy end: Index
252181
) -> (Index, savePointRange: Range<Index>?) {
253-
assert(payload.quantKind == .eager
254-
&& payload.minTrips == 0
255-
&& payload.maxExtraTrips == nil)
182+
assert(payload.minTrips == 0 && payload.maxExtraTrips == nil)
256183
guard let res = _runEagerNOrMoreQuantify(
257184
payload,
258185
minTrips: 0,
186+
maxTrips: UInt64.max,
259187
asciiBitset: asciiBitset,
260188
at: currentPosition,
261189
limitedBy: end
@@ -273,13 +201,13 @@ extension String {
273201
fileprivate func _runEagerNOrMoreQuantify(
274202
_ payload: QuantifyPayload,
275203
minTrips: UInt64,
204+
maxTrips: UInt64,
276205
asciiBitset: ASCIIBitset?, // Necessary ugliness...
277206
at currentPosition: Index,
278207
limitedBy end: Index
279208
) -> (Index, savePointRange: Range<Index>?)? {
280-
assert(payload.quantKind == .eager)
281-
assert(payload.maxExtraTrips == nil)
282209
assert(minTrips == payload.minTrips)
210+
assert(minTrips + (payload.maxExtraTrips ?? UInt64.max - minTrips) == maxTrips)
283211

284212
// Create a quantified save point for every part of the input matched up
285213
// to the final position.
@@ -292,7 +220,7 @@ extension String {
292220

293221
switch payload.type {
294222
case .asciiBitset:
295-
while true {
223+
while numMatches < maxTrips {
296224
assert(asciiBitset != nil, "Invariant: needs to be passed in")
297225
guard let next = matchASCIIBitset(
298226
asciiBitset!,
@@ -312,7 +240,7 @@ extension String {
312240
}
313241
case .asciiChar:
314242
let asciiScalar = UnicodeScalar.init(_value: UInt32(payload.asciiChar))
315-
while true {
243+
while numMatches < maxTrips {
316244
guard let next = matchScalar(
317245
asciiScalar,
318246
at: currentPosition,
@@ -334,7 +262,7 @@ extension String {
334262
let builtin = payload.builtin
335263
let isInverted = payload.builtinIsInverted
336264
let isStrictASCII = payload.builtinIsStrict
337-
while true {
265+
while numMatches < maxTrips {
338266
guard let next = matchBuiltinCC(
339267
builtin,
340268
at: currentPosition,
@@ -355,7 +283,7 @@ extension String {
355283
}
356284
case .any:
357285
let anyMatchesNewline = payload.anyMatchesNewline
358-
while true {
286+
while numMatches < maxTrips {
359287
guard let next = matchRegexDot(
360288
at: currentPosition,
361289
limitedBy: end,
@@ -378,7 +306,7 @@ extension String {
378306
return nil
379307
}
380308

381-
guard numMatches > minTrips else {
309+
guard payload.quantKind == .eager && numMatches > minTrips else {
382310
// Consumed no input, no point saved
383311
return (currentPosition, nil)
384312
}
@@ -392,18 +320,18 @@ extension String {
392320
}
393321

394322
/// Specialized quantify instruction interpreter for `+`
395-
fileprivate func runEagerNOrMoreQuantify(
323+
fileprivate func runNOrMoreQuantify(
396324
_ payload: QuantifyPayload,
397325
asciiBitset: ASCIIBitset?, // Necessary ugliness...
398326
at currentPosition: Index,
399327
limitedBy end: Index
400328
) -> (Index, savePointRange: Range<Index>?)? {
401-
assert(payload.quantKind == .eager
402-
&& payload.maxExtraTrips == nil)
329+
assert(payload.maxExtraTrips == nil)
403330

404331
return _runEagerNOrMoreQuantify(
405332
payload,
406333
minTrips: payload.minTrips,
334+
maxTrips: UInt64.max,
407335
asciiBitset: asciiBitset,
408336
at: currentPosition,
409337
limitedBy: end)
@@ -423,6 +351,7 @@ extension String {
423351
return _runEagerNOrMoreQuantify(
424352
payload,
425353
minTrips: 1,
354+
maxTrips: UInt64.max,
426355
asciiBitset: asciiBitset,
427356
at: currentPosition,
428357
limitedBy: end)

0 commit comments

Comments
 (0)