2
2
3
3
import llvmlite .ir as ll
4
4
5
- from artiq .py2llvm import values , base_types , fractions , arrays , iterators
5
+ from artiq .py2llvm import values , base_types , fractions , lists , iterators
6
6
from artiq .py2llvm .tools import is_terminated
7
7
8
8
@@ -177,14 +177,6 @@ def _visit_expr_Call(self, node):
177
177
denominator = self .visit_expression (node .args [1 ])
178
178
r .set_value_nd (self .builder , numerator , denominator )
179
179
return r
180
- elif fn == "array" :
181
- element = self .visit_expression (node .args [0 ])
182
- if (isinstance (node .args [1 ], ast .Num )
183
- and isinstance (node .args [1 ].n , int )):
184
- count = node .args [1 ].n
185
- else :
186
- raise ValueError ("Array size must be integer and constant" )
187
- return arrays .VArray (element , count )
188
180
elif fn == "range" :
189
181
return iterators .IRange (
190
182
self .builder ,
@@ -201,6 +193,56 @@ def _visit_expr_Attribute(self, node):
201
193
value = self .visit_expression (node .value )
202
194
return value .o_getattr (node .attr , self .builder )
203
195
196
+ def _visit_expr_List (self , node ):
197
+ elts = [self .visit_expression (elt ) for elt in node .elts ]
198
+ if elts :
199
+ el_type = elts [0 ].new ()
200
+ for elt in elts [1 :]:
201
+ el_type .merge (elt )
202
+ else :
203
+ el_type = VNone ()
204
+ count = len (elts )
205
+ r = lists .VList (el_type , count )
206
+ r .elts = elts
207
+ return r
208
+
209
+ def _visit_expr_ListComp (self , node ):
210
+ if len (node .generators ) != 1 :
211
+ raise NotImplementedError
212
+ generator = node .generators [0 ]
213
+ if not isinstance (generator , ast .comprehension ):
214
+ raise NotImplementedError
215
+ if not isinstance (generator .target , ast .Name ):
216
+ raise NotImplementedError
217
+ target = generator .target .id
218
+ if not isinstance (generator .iter , ast .Call ):
219
+ raise NotImplementedError
220
+ if not isinstance (generator .iter .func , ast .Name ):
221
+ raise NotImplementedError
222
+ if generator .iter .func .id != "range" :
223
+ raise NotImplementedError
224
+ if len (generator .iter .args ) != 1 :
225
+ raise NotImplementedError
226
+ if not isinstance (generator .iter .args [0 ], ast .Num ):
227
+ raise NotImplementedError
228
+ count = generator .iter .args [0 ].n
229
+
230
+ # Prevent incorrect use of the generator target, if it is defined in
231
+ # the local function namespace.
232
+ if target in self .ns :
233
+ old_target_val = self .ns [target ]
234
+ del self .ns [target ]
235
+ else :
236
+ old_target_val = None
237
+ elt = self .visit_expression (node .elt )
238
+ if old_target_val is not None :
239
+ self .ns [target ] = old_target_val
240
+
241
+ el_type = elt .new ()
242
+ r = lists .VList (el_type , count )
243
+ r .elt = elt
244
+ return r
245
+
204
246
def _visit_expr_Subscript (self , node ):
205
247
value = self .visit_expression (node .value )
206
248
if isinstance (node .slice , ast .Index ):
@@ -227,9 +269,47 @@ def _bb_terminated(self):
227
269
228
270
def _visit_stmt_Assign (self , node ):
229
271
val = self .visit_expression (node .value )
230
- for target in node .targets :
231
- target = self .visit_expression (target )
232
- target .set_value (self .builder , val )
272
+ if isinstance (node .value , ast .List ):
273
+ if len (node .targets ) > 1 :
274
+ raise NotImplementedError
275
+ target = self .visit_expression (node .targets [0 ])
276
+ target .set_count (self .builder , val .alloc_count )
277
+ for i , elt in enumerate (val .elts ):
278
+ idx = base_types .VInt ()
279
+ idx .set_const_value (self .builder , i )
280
+ target .o_subscript (idx , self .builder ).set_value (self .builder ,
281
+ elt )
282
+ elif isinstance (node .value , ast .ListComp ):
283
+ if len (node .targets ) > 1 :
284
+ raise NotImplementedError
285
+ target = self .visit_expression (node .targets [0 ])
286
+ target .set_count (self .builder , val .alloc_count )
287
+
288
+ i = base_types .VInt ()
289
+ i .alloca (self .builder )
290
+ i .auto_store (self .builder , ll .Constant (ll .IntType (32 ), 0 ))
291
+
292
+ function = self .builder .basic_block .function
293
+ copy_block = function .append_basic_block ("ai_copy" )
294
+ end_block = function .append_basic_block ("ai_end" )
295
+ self .builder .branch (copy_block )
296
+
297
+ self .builder .position_at_end (copy_block )
298
+ target .o_subscript (i , self .builder ).set_value (self .builder ,
299
+ val .elt )
300
+ i .auto_store (self .builder , self .builder .add (
301
+ i .auto_load (self .builder ),
302
+ ll .Constant (ll .IntType (32 ), 1 )))
303
+ cont = self .builder .icmp_signed (
304
+ "<" , i .auto_load (self .builder ),
305
+ ll .Constant (ll .IntType (32 ), val .alloc_count ))
306
+ self .builder .cbranch (cont , copy_block , end_block )
307
+
308
+ self .builder .position_at_end (end_block )
309
+ else :
310
+ for target in node .targets :
311
+ target = self .visit_expression (target )
312
+ target .set_value (self .builder , val )
233
313
234
314
def _visit_stmt_AugAssign (self , node ):
235
315
target = self .visit_expression (node .target )
0 commit comments