@@ -160,6 +160,20 @@ struct VariadicsGenerator: ParsableCommand {
160
160
print ( to: & standardError)
161
161
}
162
162
163
+ print ( " Generating alternation overloads... " , to: & standardError)
164
+ for (leftArity, rightArity) in Permutations ( totalArity: maxArity) {
165
+ print (
166
+ " Left arity: \( leftArity) Right arity: \( rightArity) " ,
167
+ to: & standardError)
168
+ emitAlternation ( leftArity: leftArity, rightArity: rightArity)
169
+ }
170
+
171
+ print ( " Generating 'AlternationBuilder.buildBlock(_:)' overloads... " , to: & standardError)
172
+ for arity in 1 ..< maxArity {
173
+ print ( " Capture arity: \( arity) " , to: & standardError)
174
+ emitUnaryAlternationBuildBlock ( arity: arity)
175
+ }
176
+
163
177
output ( " \n \n " )
164
178
165
179
output ( " // END AUTO-GENERATED CONTENT \n " )
@@ -444,4 +458,90 @@ struct VariadicsGenerator: ParsableCommand {
444
458
445
459
""" )
446
460
}
461
+
462
+ func emitAlternation( leftArity: Int , rightArity: Int ) {
463
+ let typeName = " _Alternation_ \( leftArity) _ \( rightArity) "
464
+ let leftGenParams : String = {
465
+ if leftArity == 0 {
466
+ return " R0 "
467
+ }
468
+ return " R0, W0, " + ( 0 ..< leftArity) . map { " C \( $0) " } . joined ( separator: " , " )
469
+ } ( )
470
+ let rightGenParams : String = {
471
+ if rightArity == 0 {
472
+ return " R1 "
473
+ }
474
+ return " R1, W1, " + ( leftArity..< leftArity+ rightArity) . map { " C \( $0) " } . joined ( separator: " , " )
475
+ } ( )
476
+ let genericParams = leftGenParams + " , " + rightGenParams
477
+ let whereClause : String = {
478
+ var result = " where R0: \( regexProtocolName) , R1: \( regexProtocolName) "
479
+ if leftArity > 0 {
480
+ result += " , R0. \( matchAssociatedTypeName) == (W0, \( ( 0 ..< leftArity) . map { " C \( $0) " } . joined ( separator: " , " ) ) ) "
481
+ }
482
+ if rightArity > 0 {
483
+ result += " , R1. \( matchAssociatedTypeName) == (W1, \( ( leftArity..< leftArity+ rightArity) . map { " C \( $0) " } . joined ( separator: " , " ) ) ) "
484
+ }
485
+ return result
486
+ } ( )
487
+ let resultCaptures : String = {
488
+ var result = ( 0 ..< leftArity) . map { " C \( $0) " } . joined ( separator: " , " )
489
+ if leftArity > 0 , rightArity > 0 {
490
+ result += " , "
491
+ }
492
+ result += ( leftArity..< leftArity+ rightArity) . map { " C \( $0) ? " } . joined ( separator: " , " )
493
+ return result
494
+ } ( )
495
+ let matchType : String = {
496
+ if leftArity == 0 , rightArity == 0 {
497
+ return baseMatchTypeName
498
+ }
499
+ return " ( \( baseMatchTypeName) , \( resultCaptures) ) "
500
+ } ( )
501
+ output ( """
502
+ public struct \( typeName) < \( genericParams) >: \( regexProtocolName) \( whereClause) {
503
+ public typealias Match = \( matchType)
504
+ public let regex: Regex<Match>
505
+
506
+ public init(_ left: R0, _ right: R1) {
507
+ self.regex = .init(ast: alt(left.regex.ast, right.regex.ast))
508
+ }
509
+ }
510
+
511
+ extension AlternationBuilder {
512
+ public static func buildBlock< \( genericParams) >(combining next: R1, into combined: R0) -> \( typeName) < \( genericParams) > {
513
+ .init(combined, next)
514
+ }
515
+ }
516
+
517
+ public func | < \( genericParams) >(lhs: R0, rhs: R1) -> \( typeName) < \( genericParams) > {
518
+ .init(lhs, rhs)
519
+ }
520
+
521
+ """ )
522
+ }
523
+
524
+ func emitUnaryAlternationBuildBlock( arity: Int ) {
525
+ assert ( arity > 0 )
526
+ let captures = ( 0 ..< arity) . map { " C \( $0) " } . joined ( separator: " , " )
527
+ let genericParams : String = {
528
+ if arity == 0 {
529
+ return " R "
530
+ }
531
+ return " R, W, " + captures
532
+ } ( )
533
+ let whereClause : String = """
534
+ where R: \( regexProtocolName) , \
535
+ R. \( matchAssociatedTypeName) == (W, \( captures) )
536
+ """
537
+ let resultCaptures = ( 0 ..< arity) . map { " C \( $0) ? " } . joined ( separator: " , " )
538
+ output ( """
539
+ extension AlternationBuilder {
540
+ public static func buildBlock< \( genericParams) >(_ regex: R) -> Regex<(W, \( resultCaptures) )> \( whereClause) {
541
+ .init(ast: alt(regex.regex.ast))
542
+ }
543
+ }
544
+
545
+ """ )
546
+ }
447
547
}
0 commit comments