@@ -25,137 +25,161 @@ public enum CaptureStructure: Equatable {
25
25
}
26
26
}
27
27
28
+ // TODO: Below are all flattening constructors. Instead create
29
+ // a builder/visitor that can store the structuralization
30
+ // approach
31
+
28
32
extension CaptureStructure {
29
- public init < C: Collection > (
30
- alternating children: C
31
- ) where C. Element: _TreeNode {
32
- assert ( children. count > 1 )
33
- self = children
34
- . map ( \. captureStructure)
35
- . reduce ( . empty, + )
36
- . map ( CaptureStructure . optional)
33
+ public struct Constructor {
34
+ var strategy : Strategy
35
+
36
+ public init ( _ strategy: Strategy = . flatten) {
37
+ guard strategy == . flatten else {
38
+ fatalError ( " TODO: adjust creator methods " )
39
+ }
40
+ self . strategy = strategy
41
+ }
42
+ }
43
+ }
44
+
45
+ extension CaptureStructure . Constructor {
46
+ public mutating func alternating< C: Collection > (
47
+ _ children: C
48
+ ) -> CaptureStructure where C. Element: _TreeNode {
49
+ // assert(children.count > 1)
50
+ return children. map {
51
+ $0. _captureStructure ( & self )
52
+ } . reduce ( . empty, + )
53
+ . map ( CaptureStructure . optional)
37
54
}
38
- public init < C: Collection > (
39
- concatenating children: C
40
- ) where C. Element: _TreeNode {
41
- self = children. map ( \. captureStructure) . reduce ( . empty, + )
55
+ public mutating func concatenating< C: Collection > (
56
+ _ children: C
57
+ ) -> CaptureStructure where C. Element: _TreeNode {
58
+ return children. map {
59
+ $0. _captureStructure ( & self )
60
+ } . reduce ( . empty, + )
42
61
}
43
62
44
- public init < T: _TreeNode > (
45
- grouping child: T , as kind: AST . Group . Kind
46
- ) {
47
- let innerCaptures = child. captureStructure
63
+ public mutating func grouping < T: _TreeNode > (
64
+ _ child: T , as kind: AST . Group . Kind
65
+ ) -> CaptureStructure {
66
+ let innerCaptures = child. _captureStructure ( & self )
48
67
switch kind {
49
68
case . capture:
50
- self = . atom( ) + innerCaptures
69
+ return . atom( ) + innerCaptures
51
70
case . namedCapture( let name) :
52
- self = . atom( name: name. value) + innerCaptures
71
+ return . atom( name: name. value) + innerCaptures
53
72
case . balancedCapture( let b) :
54
- self = . atom( name: b. name? . value) + innerCaptures
73
+ return . atom( name: b. name? . value) + innerCaptures
55
74
default :
56
75
precondition ( !kind. isCapturing)
57
- self = innerCaptures
76
+ return innerCaptures
58
77
}
59
78
}
60
79
61
- public init < T: _TreeNode > (
62
- grouping child: T ,
80
+ public mutating func grouping < T: _TreeNode > (
81
+ _ child: T ,
63
82
as kind: AST . Group . Kind ,
64
83
withTransform transform: CaptureTransform
65
- ) {
66
- let innerCaptures = child. captureStructure
84
+ ) -> CaptureStructure {
85
+ let innerCaptures = child. _captureStructure ( & self )
67
86
switch kind {
68
87
case . capture:
69
- self = . atom( type: AnyType ( transform. resultType) ) + innerCaptures
88
+ return . atom( type: AnyType ( transform. resultType) ) + innerCaptures
70
89
case . namedCapture( let name) :
71
- self = . atom( name: name. value, type: AnyType ( transform. resultType) )
90
+ return . atom( name: name. value, type: AnyType ( transform. resultType) )
72
91
+ innerCaptures
73
92
default :
74
- self = innerCaptures
93
+ return innerCaptures
75
94
}
76
95
}
77
96
78
97
// TODO: We'll likely want/need a generalization of
79
98
// conditional's condition kind.
80
- public init < T: _TreeNode > (
81
- condition: AST . Conditional . Condition . Kind ,
99
+ public mutating func condition < T: _TreeNode > (
100
+ _ condition: AST . Conditional . Condition . Kind ,
82
101
trueBranch: T ,
83
102
falseBranch: T
84
- ) {
103
+ ) -> CaptureStructure {
85
104
// A conditional's capture structure is effectively that of an alternation
86
105
// between the true and false branches. However the condition may also
87
106
// have captures in the case of a group condition.
88
107
var captures = CaptureStructure . empty
89
108
switch condition {
90
109
case . group( let g) :
91
- captures = captures + AST. Node. group ( g) . captureStructure
110
+ captures = captures + AST. Node. group ( g) . _captureStructure ( & self )
92
111
default :
93
112
break
94
113
}
95
- let branchCaptures = trueBranch. captureStructure +
96
- falseBranch. captureStructure
97
- self = captures + branchCaptures. map (
114
+ let branchCaptures = trueBranch. _captureStructure ( & self ) +
115
+ falseBranch. _captureStructure ( & self )
116
+ return captures + branchCaptures. map (
98
117
CaptureStructure . optional)
99
118
}
100
119
101
- public init < T: _TreeNode > (
102
- quantifying child: T , amount: AST . Quantification . Amount
103
- ) {
104
- self = child. captureStructure . map (
120
+ public mutating func quantifying < T: _TreeNode > (
121
+ _ child: T , amount: AST . Quantification . Amount
122
+ ) -> CaptureStructure {
123
+ return child. _captureStructure ( & self ) . map (
105
124
amount == . zeroOrOne
106
125
? CaptureStructure . optional
107
126
: CaptureStructure . array)
108
127
}
109
128
110
129
// TODO: Will need to adjust for DSLTree support, and
111
130
// "absent" isn't the best name for these.
112
- public init (
113
- absent kind: AST . AbsentFunction . Kind
114
- ) {
131
+ public mutating func absent (
132
+ _ kind: AST . AbsentFunction . Kind
133
+ ) -> CaptureStructure {
115
134
// Only the child of an expression absent function is relevant, as the
116
135
// other expressions don't actually get matched against.
117
136
switch kind {
118
137
case . expression( _, _, let child) :
119
- self = child. captureStructure
138
+ return child. _captureStructure ( & self )
120
139
case . clearer, . repeater, . stopper:
121
- self = . empty
140
+ return . empty
122
141
}
123
142
}
124
143
125
144
}
126
145
127
146
extension AST . Node {
128
- public var captureStructure : CaptureStructure {
147
+ public func _captureStructure(
148
+ _ constructor: inout CaptureStructure . Constructor
149
+ ) -> CaptureStructure {
150
+ guard constructor. strategy == . flatten else {
151
+ fatalError ( " TODO " )
152
+ }
153
+
129
154
// Note: This implementation could be more optimized.
130
155
switch self {
131
156
case let . alternation( a) :
132
- return CaptureStructure ( alternating: a. children)
157
+ return constructor . alternating ( a. children)
133
158
134
159
case let . concatenation( c) :
135
- return CaptureStructure ( concatenating: c. children)
160
+ return constructor . concatenating ( c. children)
136
161
137
162
case let . group( g) :
138
- return CaptureStructure (
139
- grouping: g. child, as: g. kind. value)
163
+ return constructor. grouping ( g. child, as: g. kind. value)
140
164
141
165
case . groupTransform( let g, let transform) :
142
- return CaptureStructure (
143
- grouping : g. child,
166
+ return constructor . grouping (
167
+ g. child,
144
168
as: g. kind. value,
145
169
withTransform: transform)
146
170
147
171
case . conditional( let c) :
148
- return CaptureStructure (
149
- condition : c. condition. kind,
172
+ return constructor . condition (
173
+ c. condition. kind,
150
174
trueBranch: c. trueBranch,
151
175
falseBranch: c. falseBranch)
152
176
153
177
case . quantification( let q) :
154
- return CaptureStructure (
155
- quantifying : q. child, amount: q. amount. value)
178
+ return constructor . quantifying (
179
+ q. child, amount: q. amount. value)
156
180
157
181
case . absentFunction( let abs) :
158
- return CaptureStructure ( absent: abs. kind)
182
+ return constructor . absent ( abs. kind)
159
183
160
184
case . quote, . trivia, . atom, . customCharacterClass, . empty:
161
185
return . empty
@@ -436,3 +460,11 @@ extension CaptureStructure: CustomStringConvertible {
436
460
}
437
461
}
438
462
}
463
+
464
+ extension CaptureStructure . Constructor {
465
+ public enum Strategy {
466
+ case flatten
467
+ case nest
468
+ // case drop(after: Int)...
469
+ }
470
+ }
0 commit comments