@@ -25,137 +25,161 @@ public enum CaptureStructure: Equatable {
2525 }
2626}
2727
28+ // TODO: Below are all flattening constructors. Instead create
29+ // a builder/visitor that can store the structuralization
30+ // approach
31+
2832extension 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)
3754 }
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, + )
4261 }
4362
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 )
4867 switch kind {
4968 case . capture:
50- self = . atom( ) + innerCaptures
69+ return . atom( ) + innerCaptures
5170 case . namedCapture( let name) :
52- self = . atom( name: name. value) + innerCaptures
71+ return . atom( name: name. value) + innerCaptures
5372 case . balancedCapture( let b) :
54- self = . atom( name: b. name? . value) + innerCaptures
73+ return . atom( name: b. name? . value) + innerCaptures
5574 default :
5675 precondition ( !kind. isCapturing)
57- self = innerCaptures
76+ return innerCaptures
5877 }
5978 }
6079
61- public init < T: _TreeNode > (
62- grouping child: T ,
80+ public mutating func grouping < T: _TreeNode > (
81+ _ child: T ,
6382 as kind: AST . Group . Kind ,
6483 withTransform transform: CaptureTransform
65- ) {
66- let innerCaptures = child. captureStructure
84+ ) -> CaptureStructure {
85+ let innerCaptures = child. _captureStructure ( & self )
6786 switch kind {
6887 case . capture:
69- self = . atom( type: AnyType ( transform. resultType) ) + innerCaptures
88+ return . atom( type: AnyType ( transform. resultType) ) + innerCaptures
7089 case . namedCapture( let name) :
71- self = . atom( name: name. value, type: AnyType ( transform. resultType) )
90+ return . atom( name: name. value, type: AnyType ( transform. resultType) )
7291 + innerCaptures
7392 default :
74- self = innerCaptures
93+ return innerCaptures
7594 }
7695 }
7796
7897 // TODO: We'll likely want/need a generalization of
7998 // 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 ,
82101 trueBranch: T ,
83102 falseBranch: T
84- ) {
103+ ) -> CaptureStructure {
85104 // A conditional's capture structure is effectively that of an alternation
86105 // between the true and false branches. However the condition may also
87106 // have captures in the case of a group condition.
88107 var captures = CaptureStructure . empty
89108 switch condition {
90109 case . group( let g) :
91- captures = captures + AST. Node. group ( g) . captureStructure
110+ captures = captures + AST. Node. group ( g) . _captureStructure ( & self )
92111 default :
93112 break
94113 }
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 (
98117 CaptureStructure . optional)
99118 }
100119
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 (
105124 amount == . zeroOrOne
106125 ? CaptureStructure . optional
107126 : CaptureStructure . array)
108127 }
109128
110129 // TODO: Will need to adjust for DSLTree support, and
111130 // "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 {
115134 // Only the child of an expression absent function is relevant, as the
116135 // other expressions don't actually get matched against.
117136 switch kind {
118137 case . expression( _, _, let child) :
119- self = child. captureStructure
138+ return child. _captureStructure ( & self )
120139 case . clearer, . repeater, . stopper:
121- self = . empty
140+ return . empty
122141 }
123142 }
124143
125144}
126145
127146extension 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+
129154 // Note: This implementation could be more optimized.
130155 switch self {
131156 case let . alternation( a) :
132- return CaptureStructure ( alternating: a. children)
157+ return constructor . alternating ( a. children)
133158
134159 case let . concatenation( c) :
135- return CaptureStructure ( concatenating: c. children)
160+ return constructor . concatenating ( c. children)
136161
137162 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)
140164
141165 case . groupTransform( let g, let transform) :
142- return CaptureStructure (
143- grouping : g. child,
166+ return constructor . grouping (
167+ g. child,
144168 as: g. kind. value,
145169 withTransform: transform)
146170
147171 case . conditional( let c) :
148- return CaptureStructure (
149- condition : c. condition. kind,
172+ return constructor . condition (
173+ c. condition. kind,
150174 trueBranch: c. trueBranch,
151175 falseBranch: c. falseBranch)
152176
153177 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)
156180
157181 case . absentFunction( let abs) :
158- return CaptureStructure ( absent: abs. kind)
182+ return constructor . absent ( abs. kind)
159183
160184 case . quote, . trivia, . atom, . customCharacterClass, . empty:
161185 return . empty
@@ -436,3 +460,11 @@ extension CaptureStructure: CustomStringConvertible {
436460 }
437461 }
438462}
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