Show More
@@ -108,3 +108,80 b' def prettyformat(tree, leafnodes):' | |||||
108 | _prettyformat(tree, leafnodes, 0, lines) |
|
108 | _prettyformat(tree, leafnodes, 0, lines) | |
109 | output = '\n'.join((' ' * l + s) for l, s in lines) |
|
109 | output = '\n'.join((' ' * l + s) for l, s in lines) | |
110 | return output |
|
110 | return output | |
|
111 | ||||
|
112 | def simplifyinfixops(tree, targetnodes): | |||
|
113 | """Flatten chained infix operations to reduce usage of Python stack | |||
|
114 | ||||
|
115 | >>> def f(tree): | |||
|
116 | ... print prettyformat(simplifyinfixops(tree, ('or',)), ('symbol',)) | |||
|
117 | >>> f(('or', | |||
|
118 | ... ('or', | |||
|
119 | ... ('symbol', '1'), | |||
|
120 | ... ('symbol', '2')), | |||
|
121 | ... ('symbol', '3'))) | |||
|
122 | (or | |||
|
123 | ('symbol', '1') | |||
|
124 | ('symbol', '2') | |||
|
125 | ('symbol', '3')) | |||
|
126 | >>> f(('func', | |||
|
127 | ... ('symbol', 'p1'), | |||
|
128 | ... ('or', | |||
|
129 | ... ('or', | |||
|
130 | ... ('func', | |||
|
131 | ... ('symbol', 'sort'), | |||
|
132 | ... ('list', | |||
|
133 | ... ('or', | |||
|
134 | ... ('or', | |||
|
135 | ... ('symbol', '1'), | |||
|
136 | ... ('symbol', '2')), | |||
|
137 | ... ('symbol', '3')), | |||
|
138 | ... ('negate', | |||
|
139 | ... ('symbol', 'rev')))), | |||
|
140 | ... ('and', | |||
|
141 | ... ('symbol', '4'), | |||
|
142 | ... ('group', | |||
|
143 | ... ('or', | |||
|
144 | ... ('or', | |||
|
145 | ... ('symbol', '5'), | |||
|
146 | ... ('symbol', '6')), | |||
|
147 | ... ('symbol', '7'))))), | |||
|
148 | ... ('symbol', '8')))) | |||
|
149 | (func | |||
|
150 | ('symbol', 'p1') | |||
|
151 | (or | |||
|
152 | (func | |||
|
153 | ('symbol', 'sort') | |||
|
154 | (list | |||
|
155 | (or | |||
|
156 | ('symbol', '1') | |||
|
157 | ('symbol', '2') | |||
|
158 | ('symbol', '3')) | |||
|
159 | (negate | |||
|
160 | ('symbol', 'rev')))) | |||
|
161 | (and | |||
|
162 | ('symbol', '4') | |||
|
163 | (group | |||
|
164 | (or | |||
|
165 | ('symbol', '5') | |||
|
166 | ('symbol', '6') | |||
|
167 | ('symbol', '7')))) | |||
|
168 | ('symbol', '8'))) | |||
|
169 | """ | |||
|
170 | if not isinstance(tree, tuple): | |||
|
171 | return tree | |||
|
172 | op = tree[0] | |||
|
173 | if op not in targetnodes: | |||
|
174 | return (op,) + tuple(simplifyinfixops(x, targetnodes) for x in tree[1:]) | |||
|
175 | ||||
|
176 | # walk down left nodes taking each right node. no recursion to left nodes | |||
|
177 | # because infix operators are left-associative, i.e. left tree is deep. | |||
|
178 | # e.g. '1 + 2 + 3' -> (+ (+ 1 2) 3) -> (+ 1 2 3) | |||
|
179 | simplified = [] | |||
|
180 | x = tree | |||
|
181 | while x[0] == op: | |||
|
182 | l, r = x[1:] | |||
|
183 | simplified.append(simplifyinfixops(r, targetnodes)) | |||
|
184 | x = l | |||
|
185 | simplified.append(simplifyinfixops(x, targetnodes)) | |||
|
186 | simplified.append(op) | |||
|
187 | return tuple(reversed(simplified)) |
@@ -21,6 +21,7 b" testmod('mercurial.match')" | |||||
21 | testmod('mercurial.minirst') |
|
21 | testmod('mercurial.minirst') | |
22 | testmod('mercurial.patch') |
|
22 | testmod('mercurial.patch') | |
23 | testmod('mercurial.pathutil') |
|
23 | testmod('mercurial.pathutil') | |
|
24 | testmod('mercurial.parser') | |||
24 | testmod('mercurial.revset') |
|
25 | testmod('mercurial.revset') | |
25 | testmod('mercurial.store') |
|
26 | testmod('mercurial.store') | |
26 | testmod('mercurial.subrepo') |
|
27 | testmod('mercurial.subrepo') |
General Comments 0
You need to be logged in to leave comments.
Login now