@@ -89,7 +89,7 @@ struct StandardErrorStream: TextOutputStream {
89
89
var standardError = StandardErrorStream ( )
90
90
91
91
typealias Counter = Int64
92
- let patternProtocolName = " RegexProtocol "
92
+ let regexProtocolName = " RegexProtocol "
93
93
let concatenationStructTypeBaseName = " Concatenate "
94
94
let capturingGroupTypeBaseName = " CapturingGroup "
95
95
let matchAssociatedTypeName = " Match "
@@ -132,9 +132,10 @@ struct VariadicsGenerator: ParsableCommand {
132
132
emitTupleStruct ( arity: arity)
133
133
}
134
134
135
+ print ( " Generating concatenation overloads... " , to: & standardError)
135
136
for (leftArity, rightArity) in Permutations ( totalArity: maxArity) {
136
137
print (
137
- " Left arity: \( leftArity) Right arity: \( rightArity) " ,
138
+ " Left arity: \( leftArity) Right arity: \( rightArity) " ,
138
139
to: & standardError)
139
140
emitConcatenation ( leftArity: leftArity, rightArity: rightArity)
140
141
}
@@ -144,7 +145,20 @@ struct VariadicsGenerator: ParsableCommand {
144
145
}
145
146
146
147
output ( " \n \n " )
147
- output ( " // END AUTO-GENERATED CONTENT " )
148
+
149
+ print ( " Generating quantifiers... " , to: & standardError)
150
+ for arity in 0 ..< maxArity {
151
+ print ( " Arity \( arity) : " , terminator: " " , to: & standardError)
152
+ for kind in QuantifierKind . allCases {
153
+ print ( " \( kind. rawValue) " , terminator: " " , to: & standardError)
154
+ emitQuantifier ( kind: kind, arity: arity)
155
+ }
156
+ print ( to: & standardError)
157
+ }
158
+
159
+ output ( " \n \n " )
160
+
161
+ output ( " // END AUTO-GENERATED CONTENT \n " )
148
162
149
163
print ( " Done! " , to: & standardError)
150
164
}
@@ -231,7 +245,7 @@ struct VariadicsGenerator: ParsableCommand {
231
245
}
232
246
output ( " , " )
233
247
if withConstraints {
234
- output ( " R0: \( patternProtocolName ) , R1: \( patternProtocolName ) " )
248
+ output ( " R0: \( regexProtocolName ) , R1: \( regexProtocolName ) " )
235
249
} else {
236
250
output ( " R0, R1 " )
237
251
}
@@ -268,7 +282,7 @@ struct VariadicsGenerator: ParsableCommand {
268
282
let typeName = " \( concatenationStructTypeBaseName) _ \( leftArity) _ \( rightArity) "
269
283
output ( " public struct \( typeName) < \n " )
270
284
emitGenericParameters ( withConstraints: true )
271
- output ( " \n >: \( patternProtocolName ) " )
285
+ output ( " \n >: \( regexProtocolName ) " )
272
286
output ( " where " )
273
287
output ( " R0.Match == " )
274
288
if leftArity == 0 {
@@ -343,7 +357,7 @@ struct VariadicsGenerator: ParsableCommand {
343
357
" , C \( $0) "
344
358
}
345
359
output ( """
346
- , R0: \( patternProtocolName ) , R1: \( patternProtocolName ) >(
360
+ , R0: \( regexProtocolName ) , R1: \( regexProtocolName ) >(
347
361
combining next: R1, into combined: R0
348
362
) -> Regex<
349
363
""" )
@@ -374,4 +388,106 @@ struct VariadicsGenerator: ParsableCommand {
374
388
375
389
""" )
376
390
}
391
+
392
+ enum QuantifierKind : String , CaseIterable {
393
+ case zeroOrOne = " optionally "
394
+ case zeroOrMore = " many "
395
+ case oneOrMore = " oneOrMore "
396
+
397
+ var typeName : String {
398
+ switch self {
399
+ case . zeroOrOne: return " _ZeroOrOne "
400
+ case . zeroOrMore: return " _ZeroOrMore "
401
+ case . oneOrMore: return " _OneOrMore "
402
+ }
403
+ }
404
+
405
+ var operatorName : String {
406
+ switch self {
407
+ case . zeroOrOne: return " .? "
408
+ case . zeroOrMore: return " .+ "
409
+ case . oneOrMore: return " .* "
410
+ }
411
+ }
412
+
413
+ var astQuantifierAmount : String {
414
+ switch self {
415
+ case . zeroOrOne: return " zeroOrOne "
416
+ case . zeroOrMore: return " zeroOrMore "
417
+ case . oneOrMore: return " oneOrMore "
418
+ }
419
+ }
420
+ }
421
+
422
+ func emitQuantifier( kind: QuantifierKind , arity: Int ) {
423
+ assert ( arity >= 0 )
424
+ func genericParameters( withConstraints: Bool ) -> String {
425
+ var result = " "
426
+ if arity > 0 {
427
+ result += " W "
428
+ result += ( 0 ..< arity) . map { " , C \( $0) " } . joined ( )
429
+ result += " , "
430
+ }
431
+ result += " Component "
432
+ if withConstraints {
433
+ result += " : \( regexProtocolName) "
434
+ }
435
+ return result
436
+ }
437
+ let captures = ( 0 ..< arity) . map { " C \( $0) " } . joined ( separator: " , " )
438
+ let capturesTupled = arity == 1 ? captures : " Tuple \( arity) < \( captures) > "
439
+ let componentConstraint : String = arity == 0 ? " " :
440
+ " where Component.Match == Tuple \( arity+ 1 ) <W, \( captures) > "
441
+ let quantifiedCaptures : String = {
442
+ switch kind {
443
+ case . zeroOrOne:
444
+ return " \( capturesTupled) ? "
445
+ case . zeroOrMore, . oneOrMore:
446
+ return " [ \( capturesTupled) ] "
447
+ }
448
+ } ( )
449
+ let matchType = arity == 0 ? baseMatchTypeName : " Tuple2< \( baseMatchTypeName) , \( quantifiedCaptures) > "
450
+ output ( """
451
+ public struct \( kind. typeName) _ \( arity) < \( genericParameters ( withConstraints: true ) ) >: \( regexProtocolName) \( componentConstraint) {
452
+ public typealias \( matchAssociatedTypeName) = \( matchType)
453
+ public let regex: Regex< \( matchAssociatedTypeName) >
454
+ public init(component: Component) {
455
+ self.regex = .init(node: .quantification(. \( kind. astQuantifierAmount) , .eager, component.regex.root))
456
+ }
457
+ }
458
+
459
+ \( arity == 0 ? " @_disfavoredOverload " : " " )
460
+ public func \( kind. rawValue) < \( genericParameters ( withConstraints: true ) ) >(
461
+ _ component: Component
462
+ ) -> \( kind. typeName) _ \( arity) < \( genericParameters ( withConstraints: false ) ) > {
463
+ .init(component: component)
464
+ }
465
+
466
+ \( arity == 0 ? " @_disfavoredOverload " : " " )
467
+ public func \( kind. rawValue) < \( genericParameters ( withConstraints: true ) ) >(
468
+ @RegexBuilder _ component: () -> Component
469
+ ) -> \( kind. typeName) _ \( arity) < \( genericParameters ( withConstraints: false ) ) > {
470
+ \( kind. rawValue) (component())
471
+ }
472
+
473
+ \( arity == 0 ? " @_disfavoredOverload " : " " )
474
+ public postfix func \( kind. operatorName) < \( genericParameters ( withConstraints: true ) ) >(
475
+ _ component: Component
476
+ ) -> \( kind. typeName) _ \( arity) < \( genericParameters ( withConstraints: false ) ) > {
477
+ \( kind. rawValue) (component)
478
+ }
479
+
480
+ \( kind == . zeroOrOne ?
481
+ """
482
+ extension RegexBuilder {
483
+ public static func buildLimitedAvailability< \( genericParameters ( withConstraints: true ) ) >(
484
+ _ component: Component
485
+ ) -> \( kind. typeName) _ \( arity) < \( genericParameters ( withConstraints: false ) ) > {
486
+ \( kind. rawValue) (component)
487
+ }
488
+ }
489
+ """ : " " )
490
+
491
+ """ )
492
+ }
377
493
}
0 commit comments