78
78
79
79
80
80
function LoopSet (q:: Expr , mod:: Symbol = :Main )
81
- contract_pass! (q)
82
81
ls = LoopSet (mod)
82
+ check_inputs! (q, ls. prepreamble)
83
+ contract_pass! (q)
83
84
copyto! (ls, q)
84
85
resize! (ls. loop_order, num_loops (ls))
85
86
ls
@@ -158,32 +159,32 @@ function process_args(
158
159
end
159
160
# check if the body of loop is a block, if not convert it to a block issue#395
160
161
# and check if the range of loop is an enumerate, if it is replace it, issue#393
161
- function check_inputs! (q)
162
+ function check_inputs! (q, prepreamble )
162
163
if Meta. isexpr (q, :for )
163
164
if ! Meta. isexpr (q. args[2 ], :block )
164
165
q. args[2 ] = Expr (:block , q. args[2 ])
165
- replace_enumerate! (q) # must after warp block
166
+ replace_enumerate! (q, prepreamble ) # must after warp block
166
167
else # maybe inner loops in block
167
- replace_enumerate! (q)
168
+ replace_enumerate! (q, prepreamble )
168
169
for arg in q. args[2 ]. args
169
- check_inputs! (arg) # check recursively for inner loop
170
+ check_inputs! (arg, prepreamble ) # check recursively for inner loop
170
171
end
171
172
end
172
173
end
173
174
return q
174
175
end
175
- function replace_enumerate! (q)
176
+ function replace_enumerate! (q, prepreamble )
176
177
looprange = q. args[1 ]
177
178
if Meta. isexpr (looprange, :block )
178
179
for i in 1 : length (looprange. args)
179
- convert_single_enumerate ! (q, i)
180
+ replace_single_enumerate ! (q, prepreamble , i)
180
181
end
181
182
else
182
- convert_single_enumerate ! (q)
183
+ replace_single_enumerate ! (q, prepreamble )
183
184
end
184
185
return q
185
186
end
186
- function convert_single_enumerate ! (q, i= nothing )
187
+ function replace_single_enumerate ! (q, prepreamble , i= nothing )
187
188
if isnothing (i) # not nest loop
188
189
looprange, body = q. args[1 ], q. args[2 ]
189
190
else # nest loop
@@ -192,7 +193,13 @@ function convert_single_enumerate!(q, i=nothing)
192
193
@assert Meta. isexpr (looprange, :(= ), 2 )
193
194
itersyms, r = looprange. args
194
195
if Meta. isexpr (r, :call , 2 ) && r. args[1 ] == :enumerate
195
- iter = r. args[2 ]
196
+ _iter = r. args[2 ]
197
+ if _iter isa Symbol
198
+ iter = _iter
199
+ else # name complex expr
200
+ iter = gensym (:iter )
201
+ push! (prepreamble. args, :($ iter = $ _iter))
202
+ end
196
203
if Meta. isexpr (itersyms, :tuple , 2 )
197
204
indsym, varsym = itersyms. args[1 ]:: Symbol , itersyms. args[2 ]:: Symbol
198
205
_replace_looprange! (q, i, indsym, iter)
@@ -201,14 +208,8 @@ function convert_single_enumerate!(q, i=nothing)
201
208
indsym = itersyms. args[1 ]:: Symbol
202
209
_replace_looprange! (q, i, indsym, iter)
203
210
elseif itersyms isa Symbol # if itersyms are not unbox in loop range
204
- # generate new symbols to avoid name conflict
205
- indsym = gensym (Symbol (itersyms, :_ind ))
206
- varsym = gensym (Symbol (itersyms, :_var ))
207
- _replace_looprange! (q, i, indsym, iter)
208
- pushfirst! (body. args,
209
- :($ varsym = $ iter[$ indsym + firstindex ($ iter) - 1 ]),
210
- :($ itersyms = ($ indsym, $ varsym)), # regroud the indsym and varsym for user
211
- )
211
+ throw (ArgumentError (" `for $itersyms in enumerate($r )` is not supported,
212
+ please use `for ($(itersyms) _i, $(itersyms) _v) in enumerate($r )` instead." ))
212
213
else
213
214
throw (ArgumentError (" Don't know how to handle expression `$itersyms `." ))
214
215
end
@@ -221,7 +222,6 @@ _replace_looprange!(q, i::Int, indsym, iter) = q.args[1].args[i] = :($indsym = B
221
222
function turbo_macro (mod, src, q, args... )
222
223
q = macroexpand (mod, q)
223
224
if q. head === :for
224
- check_inputs! (q)
225
225
ls = LoopSet (q, mod)
226
226
inline, check_empty, u₁, u₂, v, threads, warncheckarg = process_args (args)
227
227
esc (setup_call (ls, q, src, inline, check_empty, u₁, u₂, v, threads, warncheckarg))
0 commit comments