@@ -72,12 +72,14 @@ func genBracketExprOf(id: NimNode, len: int): seq[NimNode] =
72
72
for i in 0 ..< len:
73
73
result .add newTree (nnkBracketExpr, id, newIntLitNode i)
74
74
75
- func replacedIteratorIdents (expr: NimNode , aliases: seq [NimNode ]): NimNode =
75
+ func replacedIteratorIdents (expr: NimNode ,
76
+ aliases: seq [NimNode ], by: NimNode ): NimNode =
77
+
76
78
case aliases.len:
77
- of 0 : expr
78
- of 1 : expr.replacedIdent (aliases[0 ], ident " it " )
79
+ of 0 : expr. replacedIdent ( ident " it " , by)
80
+ of 1 : expr.replacedIdent (aliases[0 ], by )
79
81
else :
80
- expr.replacedIdents (aliases, genBracketExprOf (ident " it " , aliases.len))
82
+ expr.replacedIdents (aliases, genBracketExprOf (by , aliases.len))
81
83
82
84
func toIterrrPack (calls: seq [NimNode ]): IterrrPack =
83
85
var hasReducer = false
@@ -120,14 +122,14 @@ func toIterrrPack(calls: seq[NimNode]): IterrrPack =
120
122
121
123
assert hasReducer, " must set reducer"
122
124
123
- func detectTypeImpl (itrbl: NimNode , ttrfs: seq [TypeTransformer ]): NimNode =
125
+ func detectTypeImpl (itrbl, iterIdent : NimNode , ttrfs: seq [TypeTransformer ]): NimNode =
124
126
var cursor = inlineQuote default (typeof (`itrbl`))
125
127
126
128
for t in ttrfs:
127
129
cursor =
128
130
case t.kind:
129
131
of hoMap:
130
- replacedIdent (t.expr, ident " it " , cursor)
132
+ replacedIdent (t.expr, iterIdent , cursor)
131
133
132
134
of hoCustom:
133
135
newCall ident " default" :
@@ -137,8 +139,8 @@ func detectTypeImpl(itrbl: NimNode, ttrfs: seq[TypeTransformer]): NimNode =
137
139
138
140
inlineQuote typeof (`cursor`)
139
141
140
- func detectType (itrbl: NimNode , callChain: seq [HigherOrderCall ]): NimNode =
141
- detectTypeImpl itrbl:
142
+ func detectType (itrbl, iterIdent : NimNode , callChain: seq [HigherOrderCall ]): NimNode =
143
+ detectTypeImpl itrbl, iterIdent :
142
144
var temp: seq [TypeTransformer ]
143
145
for c in callChain:
144
146
case c.kind:
@@ -152,10 +154,10 @@ func detectType(itrbl: NimNode, callChain: seq[HigherOrderCall]): NimNode =
152
154
153
155
temp
154
156
155
- func resolveIteratorAliases (ipack: var IterrrPack ) =
157
+ func resolveIteratorAliases (ipack: var IterrrPack , iterIdent: NimNode ) =
156
158
for c in ipack.callChain.mitems:
157
159
if c.kind != hoCustom:
158
- c.expr = c.expr.replacedIteratorIdents (c.iteratorIdentAliases)
160
+ c.expr = c.expr.replacedIteratorIdents (c.iteratorIdentAliases, iterIdent )
159
161
160
162
proc resolveUniqIdents (node: NimNode , by: string ) =
161
163
# # appends `by` to every nnkAccQuote node recursively
@@ -168,17 +170,18 @@ proc resolveUniqIdents(node: NimNode, by: string) =
168
170
proc iterrrImpl (itrbl: NimNode , calls: seq [NimNode ],
169
171
code: NimNode = nil ): NimNode =
170
172
173
+ let uniqLoopIdent = ident " loopIdent_" & genUniqId ()
174
+
171
175
# var ipack = toIterrrPack inspect calls
172
176
var ipack = toIterrrPack calls
173
- resolveIteratorAliases ipack
177
+ resolveIteratorAliases ipack, uniqLoopIdent
174
178
175
179
let
176
180
hasCustomCode = code != nil
177
181
noAcc = hasCustomCode and eqident (ipack.reducer.caller, " each" )
178
182
hasInplaceReducer = eqident (ipack.reducer.caller, " reduce" )
179
183
180
184
accIdent = ident " acc"
181
- itIdent = ident " it"
182
185
mainLoopIdent = ident " mainLoop"
183
186
reducerStateUpdaterProcIdent = ipack.reducer.caller
184
187
reducerFinalizerProcIdent = ipack.reducer.caller &. " Finalizer"
@@ -193,7 +196,7 @@ proc iterrrImpl(itrbl: NimNode, calls: seq[NimNode],
193
196
194
197
else :
195
198
let
196
- dtype = detectType (itrbl, ipack.callChain)
199
+ dtype = detectType (itrbl, uniqLoopIdent, ipack.callChain)
197
200
reducerInitCall = newTree (nnkBracketExpr, reducerInitProcIdent,
198
201
dtype).newCall.add:
199
202
ipack.reducer.params
@@ -218,30 +221,36 @@ proc iterrrImpl(itrbl: NimNode, calls: seq[NimNode],
218
221
var
219
222
wrappers: seq [tuple [code: NimNode , dtype: NimNode , params: seq [NimNode ],
220
223
info: AdapterInfo ]]
224
+
221
225
loopBody =
222
226
if noAcc:
223
- code.replacedIteratorIdents (ipack.reducer.params)
227
+ code.replacedIteratorIdents (ipack.reducer.params, uniqLoopIdent )
224
228
225
229
elif hasInplaceReducer:
226
230
if ipack.reducer.idents.len == 2 :
227
231
let k = ipack.reducer.idents[1 ].kind
232
+
228
233
case k:
229
234
of nnkIdent:
230
- code.replacedIdents (ipack.reducer.idents, [accIdent, itIdent])
235
+ code.replacedIdents (ipack.reducer.idents, [accIdent, uniqLoopIdent])
236
+
231
237
of nnkTupleConstr:
232
238
let
233
239
customIdents = ipack.reducer.idents[1 ].toseq
234
- repls = genBracketExprOf (ident " it" , customIdents.len)
235
- code.replacedIdents (ipack.reducer.idents[0 ] & customIdents, @ [
236
- accIdent] & repls)
240
+ repls = genBracketExprOf (uniqLoopIdent, customIdents.len)
241
+
242
+ code.replacedIdents (
243
+ ipack.reducer.idents[0 ] & customIdents,
244
+ @ [accIdent] & repls)
245
+
237
246
else :
238
247
err " invalid inplace reducer custom ident type. got: " & $ k
239
248
else :
240
- code
249
+ code. replacedIdent ident " it " , uniqLoopIdent
241
250
242
251
else :
243
252
quote:
244
- if not `reducerStateUpdaterProcIdent` (`accIdent`, `itIdent `):
253
+ if not `reducerStateUpdaterProcIdent` (`accIdent`, `uniqLoopIdent `):
245
254
break `mainLoopIdent`
246
255
247
256
@@ -255,7 +264,7 @@ proc iterrrImpl(itrbl: NimNode, calls: seq[NimNode],
255
264
of hoMap:
256
265
quote:
257
266
block :
258
- let `itIdent ` = `p`
267
+ let `uniqLoopIdent ` = `p`
259
268
`loopBody`
260
269
261
270
of hoFilter:
@@ -275,7 +284,7 @@ proc iterrrImpl(itrbl: NimNode, calls: seq[NimNode],
275
284
276
285
of hoCustom:
277
286
let adptr = customAdapters[call.name.strval]
278
- var code = copy adptr.wrapperCode
287
+ var code = adptr.wrapperCode.copy. replacedIdent ( ident " it " , uniqLoopIdent)
279
288
280
289
code.resolveUniqIdents $ i
281
290
@@ -288,23 +297,23 @@ proc iterrrImpl(itrbl: NimNode, calls: seq[NimNode],
288
297
else :
289
298
quote:
290
299
block :
291
- let `itIdent ` = `yval`
300
+ let `uniqLoopIdent ` = `yval`
292
301
`loopBody`
293
302
294
303
wrappers.add:
295
304
let dtype = # speed optimzation for adptr who don't use generic type. like `cycle` and `flatten`
296
305
if adptr.iterTypePaths.len == 0 :
297
306
newEmptyNode ()
298
307
else :
299
- detectType (itrbl, ipack.callChain[0 .. i- 1 ])
308
+ detectType (itrbl, uniqLoopIdent, ipack.callChain[0 .. i- 1 ])
300
309
301
310
(code, dtype, call.params, adptr)
302
311
303
312
code.getNode (adptr.loopPath)[ForBody ]
304
313
305
314
306
315
result = quote:
307
- for `itIdent ` in `itrbl`:
316
+ for `uniqLoopIdent ` in `itrbl`:
308
317
`loopBody`
309
318
310
319
for w in wrappers.ritems:
0 commit comments