1
- // swift run VariadicsGenerator --max-arity 7 > Sources/RegexDSL/Concatenation.swift
1
+ // swift run VariadicsGenerator --max-arity 7 > Sources/_StringProcessing/ RegexDSL/Concatenation.swift
2
2
3
3
import ArgumentParser
4
4
5
5
struct Permutation {
6
6
let arity : Int
7
7
// 1 -> no extra constraint
8
- // 0 -> where T.Capture : NoCaptureProtocol
8
+ // 0 -> where T.Match : NoCaptureProtocol
9
9
let bits : Int64
10
10
11
11
func isCaptureless( at index: Int ) -> Bool {
@@ -77,8 +77,6 @@ func outputForEach<C: Collection>(
77
77
if let lt = lineTerminator {
78
78
let indent = needsSep ? " " : " "
79
79
output ( " \( lt) \n \( indent) " )
80
- } else if needsSep {
81
- output ( " " )
82
80
}
83
81
}
84
82
}
@@ -87,12 +85,13 @@ typealias Counter = Int64
87
85
let patternProtocolName = " RegexProtocol "
88
86
let concatenationStructTypeBaseName = " Concatenate "
89
87
let capturingGroupTypeBaseName = " CapturingGroup "
88
+ let matchAssociatedTypeName = " Match "
90
89
let captureAssociatedTypeName = " Capture "
91
90
let patternBuilderTypeName = " RegexBuilder "
92
91
let patternProtocolRequirementName = " regex "
93
92
let PatternTypeBaseName = " Regex "
94
- let emptyProtocolName = " EmptyProtocol "
95
- let emptyStructName = " Empty "
93
+ let emptyProtocolName = " EmptyCaptureProtocol "
94
+ let baseMatchTypeName = " Substring "
96
95
97
96
@main
98
97
struct VariadicsGenerator : ParsableCommand {
@@ -114,6 +113,10 @@ struct VariadicsGenerator: ParsableCommand {
114
113
115
114
""" )
116
115
116
+ for arity in 2 ... maxArity+ 1 {
117
+ emitTupleStruct ( arity: arity)
118
+ }
119
+
117
120
for arity in minArity... maxArity {
118
121
for permutation in Permutations ( arity: arity) {
119
122
emitConcatenation ( permutation: permutation)
@@ -124,42 +127,111 @@ struct VariadicsGenerator: ParsableCommand {
124
127
output ( " // END AUTO-GENERATED CONTENT " )
125
128
}
126
129
130
+ func emitTupleStruct( arity: Int ) {
131
+ output ( " @frozen public struct Tuple \( arity) < " )
132
+ outputForEach ( 0 ..< arity, separator: " , " ) {
133
+ " _ \( $0) "
134
+ }
135
+ output ( " > { \n " )
136
+ // `public typealias Tuple = (_0, ...)`
137
+ output ( " \n public typealias Tuple = ( " )
138
+ outputForEach ( 0 ..< arity, separator: " , " ) { " _ \( $0) " }
139
+ output ( " ) " )
140
+ // `public var tuple: Tuple`
141
+ output ( " \n public var tuple: Tuple " )
142
+ output ( " } \n " )
143
+ output ( " extension Tuple \( arity) : \( emptyProtocolName) where " )
144
+ outputForEach ( 1 ..< arity, separator: " , " ) {
145
+ " _ \( $0) : \( emptyProtocolName) "
146
+ }
147
+ output ( " {} \n " )
148
+ output ( " extension Tuple \( arity) : MatchProtocol { \n " )
149
+ output ( " public typealias Capture = " )
150
+ if arity == 2 {
151
+ output ( " _1 " )
152
+ } else {
153
+ output ( " Tuple \( arity- 1 ) < " )
154
+ outputForEach ( 1 ..< arity, separator: " , " ) {
155
+ " _ \( $0) "
156
+ }
157
+ output ( " > " )
158
+ }
159
+ output ( " \n public init(_ tuple: Tuple) { self.tuple = tuple } " )
160
+ // `public init(_0: _0, ...) { ... }`
161
+ output ( " \n public init( " )
162
+ outputForEach ( 0 ..< arity, separator: " , " ) {
163
+ " _ _ \( $0) : _ \( $0) "
164
+ }
165
+ output ( " ) { \n " )
166
+ output ( " self.init(( " )
167
+ outputForEach ( 0 ..< arity, separator: " , " ) { " _ \( $0) " }
168
+ output ( " )) " )
169
+ output ( " } " )
170
+ output ( " \n } \n " )
171
+ // Equatable
172
+ output ( " extension Tuple \( arity) : Equatable where " )
173
+ outputForEach ( 0 ..< arity, separator: " , " ) {
174
+ " _ \( $0) : Equatable "
175
+ }
176
+ output ( " { \n " )
177
+ output ( " public static func == (lhs: Self, rhs: Self) -> Bool { \n " )
178
+ output ( " " )
179
+ outputForEach ( 0 ..< arity, separator: " && " ) {
180
+ " lhs._ \( $0) == rhs._ \( $0) "
181
+ }
182
+ output ( " \n } " )
183
+ output ( " } \n " )
184
+ }
185
+
127
186
func emitConcatenation( permutation: Permutation ) {
128
187
let arity = permutation. arity
188
+
189
+ func emitGenericParameters( withConstraints: Bool ) {
190
+ outputForEach ( 0 ..< arity, separator: " , " ) {
191
+ var base = " T \( $0) "
192
+ if withConstraints {
193
+ base += " : \( patternProtocolName) "
194
+ }
195
+ return base
196
+ }
197
+ }
198
+
129
199
// Emit concatenation type declarations.
130
200
// public struct Concatenation{n}_{perm}<...>: RegexProtocol {
131
- // public typealias Capture = ...
132
- // public let regex: Regex
201
+ // public typealias Match = ...
202
+ // public let regex: Regex<Match>
133
203
// public init(...) { ... }
134
204
// }
135
- let typeName = " \( concatenationStructTypeBaseName) \( arity) _ \( permutation. identifier) "
205
+ let typeName =
206
+ " \( concatenationStructTypeBaseName) \( arity) _ \( permutation. identifier) "
136
207
output ( " public struct \( typeName) < \n " )
137
- outputForEach ( 0 ..< arity , separator : " , " ) { " T \( $0 ) : \( patternProtocolName ) " }
208
+ emitGenericParameters ( withConstraints : true )
138
209
output ( " \n >: \( patternProtocolName) " )
139
210
if permutation. hasCaptureless {
140
211
output ( " where " )
141
- outputForEach ( permutation. capturelessIndices, separator: " , " ) {
142
- " T \( $0) . \( captureAssociatedTypeName) : \( emptyProtocolName) "
212
+ outputForEach ( permutation. capturelessIndices, separator: " , " ) {
213
+ " T \( $0) . \( matchAssociatedTypeName ) . \( captureAssociatedTypeName) : \( emptyProtocolName) "
143
214
}
144
215
}
145
216
output ( " { \n " )
146
217
let captureIndices = permutation. captureIndices
147
- output ( " public typealias \( captureAssociatedTypeName ) = " )
218
+ output ( " public typealias \( matchAssociatedTypeName ) = " )
148
219
let captureElements = captureIndices
149
- . map { " T \( $0) . \( captureAssociatedTypeName) " }
220
+ . map { " T \( $0) . \( matchAssociatedTypeName ) . \( captureAssociatedTypeName) " }
150
221
if captureElements. isEmpty {
151
- output ( emptyStructName )
222
+ output ( baseMatchTypeName )
152
223
} else {
153
- output ( " ( \( captureElements. joined ( separator: " , " ) ) ) " )
224
+ let count = captureElements. count + 1
225
+ output ( " Tuple \( count) < \( baseMatchTypeName) , \( captureElements. joined ( separator: " , " ) ) > " )
154
226
}
155
227
output ( " \n " )
156
- output ( " public let \( patternProtocolRequirementName) : \( PatternTypeBaseName) < \( captureAssociatedTypeName ) > \n " )
228
+ output ( " public let \( patternProtocolRequirementName) : \( PatternTypeBaseName) < \( matchAssociatedTypeName ) > \n " )
157
229
output ( " init( " )
158
- outputForEach ( 0 ..< arity, separator: " , " ) { " _ x \( $0) : T \( $0) " }
230
+ outputForEach ( 0 ..< arity, separator: " , " ) { " _ x \( $0) : T \( $0) " }
159
231
output ( " ) { \n " )
160
232
output ( " \( patternProtocolRequirementName) = .init(ast: concat( \n " )
161
233
outputForEach (
162
- 0 ..< arity, separator: " , " , lineTerminator: " "
234
+ 0 ..< arity, separator: " , " , lineTerminator: " "
163
235
) { i in
164
236
" x \( i) . \( patternProtocolRequirementName) .ast "
165
237
}
@@ -169,14 +241,14 @@ struct VariadicsGenerator: ParsableCommand {
169
241
// Emit concatenation builders.
170
242
output ( " extension \( patternBuilderTypeName) { \n " )
171
243
output ( " public static func buildBlock< " )
172
- outputForEach ( 0 ..< arity , separator : " , " ) { " T \( $0 ) " }
244
+ emitGenericParameters ( withConstraints : true )
173
245
output ( " >( \n " )
174
- outputForEach ( 0 ..< arity, separator: " , " ) { " _ x \( $0) : T \( $0) " }
246
+ outputForEach ( 0 ..< arity, separator: " , " ) { " _ x \( $0) : T \( $0) " }
175
247
output ( " \n ) -> \( typeName) < " )
176
- outputForEach ( 0 ..< arity , separator : " , " ) { " T \( $0 ) " }
248
+ emitGenericParameters ( withConstraints : false )
177
249
output ( " > { \n " )
178
250
output ( " \( typeName) ( " )
179
- outputForEach ( 0 ..< arity, separator: " , " ) { " x \( $0) " }
251
+ outputForEach ( 0 ..< arity, separator: " , " ) { " x \( $0) " }
180
252
output ( " ) \n } \n } \n \n " )
181
253
}
182
254
}
0 commit comments