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