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,121 @@ struct VariadicsGenerator: ParsableCommand {
124
127
output ( " // END AUTO-GENERATED CONTENT " )
125
128
}
126
129
130
+ func emitTupleStruct( arity: Int ) {
131
+ output ( """
132
+ @frozen @dynamicMemberLookup
133
+ public struct Tuple \( arity) <
134
+ """ )
135
+ outputForEach ( 0 ..< arity, separator: " , " ) {
136
+ " _ \( $0) "
137
+ }
138
+ output ( " > { \n " )
139
+ // `public typealias Tuple = (_0, ...)`
140
+ output ( " \n public typealias Tuple = ( " )
141
+ outputForEach ( 0 ..< arity, separator: " , " ) { " _ \( $0) " }
142
+ output ( " ) " )
143
+ // `public var tuple: Tuple`
144
+ output ( " \n public var tuple: Tuple \n " )
145
+ // `subscript(dynamicMember:)`
146
+ output ( """
147
+ public subscript<T>(dynamicMember keyPath: WritableKeyPath<Tuple, T>) -> T {
148
+ get { tuple[keyPath: keyPath] }
149
+ _modify { yield &tuple[keyPath: keyPath] }
150
+ }
151
+ """ )
152
+ output ( " \n } \n " )
153
+ output ( " extension Tuple \( arity) : \( emptyProtocolName) where " )
154
+ outputForEach ( 1 ..< arity, separator: " , " ) {
155
+ " _ \( $0) : \( emptyProtocolName) "
156
+ }
157
+ output ( " {} \n " )
158
+ output ( " extension Tuple \( arity) : MatchProtocol { \n " )
159
+ output ( " public typealias Capture = " )
160
+ if arity == 2 {
161
+ output ( " _1 " )
162
+ } else {
163
+ output ( " Tuple \( arity- 1 ) < " )
164
+ outputForEach ( 1 ..< arity, separator: " , " ) {
165
+ " _ \( $0) "
166
+ }
167
+ output ( " > " )
168
+ }
169
+ output ( " \n public init(_ tuple: Tuple) { self.tuple = tuple } " )
170
+ // `public init(_0: _0, ...) { ... }`
171
+ output ( " \n public init( " )
172
+ outputForEach ( 0 ..< arity, separator: " , " ) {
173
+ " _ _ \( $0) : _ \( $0) "
174
+ }
175
+ output ( " ) { \n " )
176
+ output ( " self.init(( " )
177
+ outputForEach ( 0 ..< arity, separator: " , " ) { " _ \( $0) " }
178
+ output ( " )) " )
179
+ output ( " } " )
180
+ output ( " \n } \n " )
181
+ // Equatable
182
+ output ( " extension Tuple \( arity) : Equatable where " )
183
+ outputForEach ( 0 ..< arity, separator: " , " ) {
184
+ " _ \( $0) : Equatable "
185
+ }
186
+ output ( " { \n " )
187
+ output ( " public static func == (lhs: Self, rhs: Self) -> Bool { \n " )
188
+ output ( " " )
189
+ outputForEach ( 0 ..< arity, separator: " && " ) {
190
+ " lhs.tuple. \( $0) == rhs.tuple. \( $0) "
191
+ }
192
+ output ( " \n } " )
193
+ output ( " } \n " )
194
+ }
195
+
127
196
func emitConcatenation( permutation: Permutation ) {
128
197
let arity = permutation. arity
198
+
199
+ func emitGenericParameters( withConstraints: Bool ) {
200
+ outputForEach ( 0 ..< arity, separator: " , " ) {
201
+ var base = " T \( $0) "
202
+ if withConstraints {
203
+ base += " : \( patternProtocolName) "
204
+ }
205
+ return base
206
+ }
207
+ }
208
+
129
209
// Emit concatenation type declarations.
130
210
// public struct Concatenation{n}_{perm}<...>: RegexProtocol {
131
- // public typealias Capture = ...
132
- // public let regex: Regex
211
+ // public typealias Match = ...
212
+ // public let regex: Regex<Match>
133
213
// public init(...) { ... }
134
214
// }
135
- let typeName = " \( concatenationStructTypeBaseName) \( arity) _ \( permutation. identifier) "
215
+ let typeName =
216
+ " \( concatenationStructTypeBaseName) \( arity) _ \( permutation. identifier) "
136
217
output ( " public struct \( typeName) < \n " )
137
- outputForEach ( 0 ..< arity , separator : " , " ) { " T \( $0 ) : \( patternProtocolName ) " }
218
+ emitGenericParameters ( withConstraints : true )
138
219
output ( " \n >: \( patternProtocolName) " )
139
220
if permutation. hasCaptureless {
140
221
output ( " where " )
141
- outputForEach ( permutation. capturelessIndices, separator: " , " ) {
142
- " T \( $0) . \( captureAssociatedTypeName) : \( emptyProtocolName) "
222
+ outputForEach ( permutation. capturelessIndices, separator: " , " ) {
223
+ " T \( $0) . \( matchAssociatedTypeName ) . \( captureAssociatedTypeName) : \( emptyProtocolName) "
143
224
}
144
225
}
145
226
output ( " { \n " )
146
227
let captureIndices = permutation. captureIndices
147
- output ( " public typealias \( captureAssociatedTypeName ) = " )
228
+ output ( " public typealias \( matchAssociatedTypeName ) = " )
148
229
let captureElements = captureIndices
149
- . map { " T \( $0) . \( captureAssociatedTypeName) " }
230
+ . map { " T \( $0) . \( matchAssociatedTypeName ) . \( captureAssociatedTypeName) " }
150
231
if captureElements. isEmpty {
151
- output ( emptyStructName )
232
+ output ( baseMatchTypeName )
152
233
} else {
153
- output ( " ( \( captureElements. joined ( separator: " , " ) ) ) " )
234
+ let count = captureElements. count + 1
235
+ output ( " Tuple \( count) < \( baseMatchTypeName) , \( captureElements. joined ( separator: " , " ) ) > " )
154
236
}
155
237
output ( " \n " )
156
- output ( " public let \( patternProtocolRequirementName) : \( PatternTypeBaseName) < \( captureAssociatedTypeName ) > \n " )
238
+ output ( " public let \( patternProtocolRequirementName) : \( PatternTypeBaseName) < \( matchAssociatedTypeName ) > \n " )
157
239
output ( " init( " )
158
- outputForEach ( 0 ..< arity, separator: " , " ) { " _ x \( $0) : T \( $0) " }
240
+ outputForEach ( 0 ..< arity, separator: " , " ) { " _ x \( $0) : T \( $0) " }
159
241
output ( " ) { \n " )
160
242
output ( " \( patternProtocolRequirementName) = .init(ast: concat( \n " )
161
243
outputForEach (
162
- 0 ..< arity, separator: " , " , lineTerminator: " "
244
+ 0 ..< arity, separator: " , " , lineTerminator: " "
163
245
) { i in
164
246
" x \( i) . \( patternProtocolRequirementName) .ast "
165
247
}
@@ -169,14 +251,14 @@ struct VariadicsGenerator: ParsableCommand {
169
251
// Emit concatenation builders.
170
252
output ( " extension \( patternBuilderTypeName) { \n " )
171
253
output ( " public static func buildBlock< " )
172
- outputForEach ( 0 ..< arity , separator : " , " ) { " T \( $0 ) " }
254
+ emitGenericParameters ( withConstraints : true )
173
255
output ( " >( \n " )
174
- outputForEach ( 0 ..< arity, separator: " , " ) { " _ x \( $0) : T \( $0) " }
256
+ outputForEach ( 0 ..< arity, separator: " , " ) { " _ x \( $0) : T \( $0) " }
175
257
output ( " \n ) -> \( typeName) < " )
176
- outputForEach ( 0 ..< arity , separator : " , " ) { " T \( $0 ) " }
258
+ emitGenericParameters ( withConstraints : false )
177
259
output ( " > { \n " )
178
260
output ( " \( typeName) ( " )
179
- outputForEach ( 0 ..< arity, separator: " , " ) { " x \( $0) " }
261
+ outputForEach ( 0 ..< arity, separator: " , " ) { " x \( $0) " }
180
262
output ( " ) \n } \n } \n \n " )
181
263
}
182
264
}
0 commit comments