eac472378cd352bd1e96889c4430c66e3ab40187
[cython.git] / Cython / Compiler / ExprNodes.py
1 #
2 #   Pyrex - Parse tree nodes for expressions
3 #
4
5 import operator
6
7 from Errors import error, warning, InternalError
8 from Errors import hold_errors, release_errors, held_errors, report_error
9 from Cython.Utils import UtilityCode
10 import StringEncoding
11 import Naming
12 import Nodes
13 from Nodes import Node
14 import PyrexTypes
15 from PyrexTypes import py_object_type, c_long_type, typecast, error_type
16 from Builtin import list_type, tuple_type, set_type, dict_type, unicode_type, bytes_type
17 import Builtin
18 import Symtab
19 import Options
20 from Annotate import AnnotationItem
21
22 from Cython.Debugging import print_call_chain
23 from DebugFlags import debug_disposal_code, debug_temp_alloc, \
24     debug_coercion
25
26 try:
27     set
28 except NameError:
29     from sets import Set as set
30
31 class NotConstant(object): pass # just for the name
32 not_a_constant = NotConstant()
33 constant_value_not_set = object()
34
35 class ExprNode(Node):
36     #  subexprs     [string]     Class var holding names of subexpr node attrs
37     #  type         PyrexType    Type of the result
38     #  result_code  string       Code fragment
39     #  result_ctype string       C type of result_code if different from type
40     #  is_temp      boolean      Result is in a temporary variable
41     #  is_sequence_constructor  
42     #               boolean      Is a list or tuple constructor expression
43     #  saved_subexpr_nodes
44     #               [ExprNode or [ExprNode or None] or None]
45     #                            Cached result of subexpr_nodes()
46     
47     result_ctype = None
48     type = None
49
50     #  The Analyse Expressions phase for expressions is split
51     #  into two sub-phases:
52     #
53     #    Analyse Types
54     #      Determines the result type of the expression based
55     #      on the types of its sub-expressions, and inserts
56     #      coercion nodes into the expression tree where needed.
57     #      Marks nodes which will need to have temporary variables
58     #      allocated.
59     #
60     #    Allocate Temps
61     #      Allocates temporary variables where needed, and fills
62     #      in the result_code field of each node.
63     #
64     #  ExprNode provides some convenience routines which
65     #  perform both of the above phases. These should only
66     #  be called from statement nodes, and only when no
67     #  coercion nodes need to be added around the expression
68     #  being analysed. In that case, the above two phases
69     #  should be invoked separately.
70     #
71     #  Framework code in ExprNode provides much of the common
72     #  processing for the various phases. It makes use of the
73     #  'subexprs' class attribute of ExprNodes, which should
74     #  contain a list of the names of attributes which can
75     #  hold sub-nodes or sequences of sub-nodes.
76     #  
77     #  The framework makes use of a number of abstract methods. 
78     #  Their responsibilities are as follows.
79     #
80     #    Declaration Analysis phase
81     #
82     #      analyse_target_declaration
83     #        Called during the Analyse Declarations phase to analyse
84     #        the LHS of an assignment or argument of a del statement.
85     #        Nodes which cannot be the LHS of an assignment need not
86     #        implement it.
87     #
88     #    Expression Analysis phase
89     #
90     #      analyse_types
91     #        - Call analyse_types on all sub-expressions.
92     #        - Check operand types, and wrap coercion nodes around
93     #          sub-expressions where needed.
94     #        - Set the type of this node.
95     #        - If a temporary variable will be required for the
96     #          result, set the is_temp flag of this node.
97     #
98     #      analyse_target_types
99     #        Called during the Analyse Types phase to analyse
100     #        the LHS of an assignment or argument of a del 
101     #        statement. Similar responsibilities to analyse_types.
102     #
103     #      allocate_temps
104     #        - Call allocate_temps for all sub-nodes.
105     #        - Call allocate_temp for this node.
106     #        - If a temporary was allocated, call release_temp on 
107     #          all sub-expressions.
108     #
109     #      allocate_target_temps
110     #        - Call allocate_temps on sub-nodes and allocate any other
111     #          temps used during assignment.
112     #        - Fill in result_code with a C lvalue if needed.
113     #        - If a rhs node is supplied, call release_temp on it.
114     #        - Call release_temp on sub-nodes and release any other
115     #          temps used during assignment.
116     #
117     #      target_code
118     #        Called by the default implementation of allocate_target_temps.
119     #        Should return a C lvalue for assigning to the node. The default
120     #        implementation calls calculate_result_code.
121     #
122     #      check_const
123     #        - Check that this node and its subnodes form a
124     #          legal constant expression. If so, do nothing,
125     #          otherwise call not_const. 
126     #
127     #        The default implementation of check_const 
128     #        assumes that the expression is not constant.
129     #
130     #      check_const_addr
131     #        - Same as check_const, except check that the
132     #          expression is a C lvalue whose address is
133     #          constant. Otherwise, call addr_not_const.
134     #
135     #        The default implementation of calc_const_addr
136     #        assumes that the expression is not a constant 
137     #        lvalue.
138     #
139     #   Code Generation phase
140     #
141     #      generate_evaluation_code
142     #        - Call generate_evaluation_code for sub-expressions.
143     #        - Perform the functions of generate_result_code
144     #          (see below).
145     #        - If result is temporary, call generate_disposal_code
146     #          on all sub-expressions.
147     #
148     #        A default implementation of generate_evaluation_code
149     #        is provided which uses the following abstract methods:
150     #
151     #          generate_result_code
152     #            - Generate any C statements necessary to calculate
153     #              the result of this node from the results of its
154     #              sub-expressions.
155     #
156     #          calculate_result_code
157     #            - Should return a C code fragment evaluating to the 
158     #              result. This is only called when the result is not 
159     #              a temporary.
160     #
161     #      generate_assignment_code
162     #        Called on the LHS of an assignment.
163     #        - Call generate_evaluation_code for sub-expressions.
164     #        - Generate code to perform the assignment.
165     #        - If the assignment absorbed a reference, call
166     #          generate_post_assignment_code on the RHS,
167     #          otherwise call generate_disposal_code on it.
168     #
169     #      generate_deletion_code
170     #        Called on an argument of a del statement.
171     #        - Call generate_evaluation_code for sub-expressions.
172     #        - Generate code to perform the deletion.
173     #        - Call generate_disposal_code on all sub-expressions.
174     #
175     #
176     
177     is_sequence_constructor = 0
178     is_attribute = 0
179     
180     saved_subexpr_nodes = None
181     is_temp = 0
182     is_target = 0
183
184     constant_result = constant_value_not_set
185
186     try:
187         _get_child_attrs = operator.attrgetter('subexprs')
188     except AttributeError:
189         # Python 2.3
190         def _get_child_attrs(self):
191             return self.subexprs
192     child_attrs = property(fget=_get_child_attrs)
193         
194     def not_implemented(self, method_name):
195         print_call_chain(method_name, "not implemented") ###
196         raise InternalError(
197             "%s.%s not implemented" %
198                 (self.__class__.__name__, method_name))
199                 
200     def is_lvalue(self):
201         return 0
202     
203     def is_ephemeral(self):
204         #  An ephemeral node is one whose result is in
205         #  a Python temporary and we suspect there are no
206         #  other references to it. Certain operations are
207         #  disallowed on such values, since they are
208         #  likely to result in a dangling pointer.
209         return self.type.is_pyobject and self.is_temp
210
211     def subexpr_nodes(self):
212         #  Extract a list of subexpression nodes based
213         #  on the contents of the subexprs class attribute.
214         nodes = []
215         for name in self.subexprs:
216             item = getattr(self, name)
217             if item is not None:
218                 if type(item) is list:
219                     nodes.extend(item)
220                 else:
221                     nodes.append(item)
222         return nodes
223         
224     def result(self):
225         if not self.is_temp or self.is_target:
226             return self.calculate_result_code()
227         else: # i.e. self.is_temp:
228             return self.result_code
229     
230     def result_as(self, type = None):
231         #  Return the result code cast to the specified C type.
232         return typecast(type, self.ctype(), self.result())
233     
234     def py_result(self):
235         #  Return the result code cast to PyObject *.
236         return self.result_as(py_object_type)
237     
238     def ctype(self):
239         #  Return the native C type of the result (i.e. the
240         #  C type of the result_code expression).
241         return self.result_ctype or self.type
242
243     def calculate_constant_result(self):
244         # Calculate the constant result of this expression and store
245         # it in ``self.constant_result``.  Does nothing by default,
246         # thus leaving ``self.constant_result`` unknown.
247         #
248         # This must only be called when it is assured that all
249         # sub-expressions have a valid constant_result value.  The
250         # ConstantFolding transform will do this.
251         pass
252
253     def compile_time_value(self, denv):
254         #  Return value of compile-time expression, or report error.
255         error(self.pos, "Invalid compile-time expression")
256     
257     def compile_time_value_error(self, e):
258         error(self.pos, "Error in compile-time expression: %s: %s" % (
259             e.__class__.__name__, e))
260     
261     # ------------- Declaration Analysis ----------------
262     
263     def analyse_target_declaration(self, env):
264         error(self.pos, "Cannot assign to or delete this")
265     
266     # ------------- Expression Analysis ----------------
267     
268     def analyse_const_expression(self, env):
269         #  Called during the analyse_declarations phase of a
270         #  constant expression. Analyses the expression's type,
271         #  checks whether it is a legal const expression,
272         #  and determines its value.
273         self.analyse_types(env)
274         self.allocate_temps(env)
275         self.check_const()
276     
277     def analyse_expressions(self, env):
278         #  Convenience routine performing both the Type
279         #  Analysis and Temp Allocation phases for a whole 
280         #  expression.
281         self.analyse_types(env)
282         self.allocate_temps(env)
283     
284     def analyse_target_expression(self, env, rhs):
285         #  Convenience routine performing both the Type
286         #  Analysis and Temp Allocation phases for the LHS of
287         #  an assignment.
288         self.analyse_target_types(env)
289         self.allocate_target_temps(env, rhs)
290     
291     def analyse_boolean_expression(self, env):
292         #  Analyse expression and coerce to a boolean.
293         self.analyse_types(env)
294         bool = self.coerce_to_boolean(env)
295         bool.allocate_temps(env)
296         return bool
297     
298     def analyse_temp_boolean_expression(self, env):
299         #  Analyse boolean expression and coerce result into
300         #  a temporary. This is used when a branch is to be
301         #  performed on the result and we won't have an
302         #  opportunity to ensure disposal code is executed
303         #  afterwards. By forcing the result into a temporary,
304         #  we ensure that all disposal has been done by the
305         #  time we get the result.
306         self.analyse_types(env)
307         bool = self.coerce_to_boolean(env)
308         temp_bool = bool.coerce_to_temp(env)
309         temp_bool.allocate_temps(env)
310         return temp_bool
311     
312     # --------------- Type Analysis ------------------
313     
314     def analyse_as_module(self, env):
315         # If this node can be interpreted as a reference to a
316         # cimported module, return its scope, else None.
317         return None
318         
319     def analyse_as_type(self, env):
320         # If this node can be interpreted as a reference to a
321         # type, return that type, else None.
322         return None
323     
324     def analyse_as_extension_type(self, env):
325         # If this node can be interpreted as a reference to an
326         # extension type, return its type, else None.
327         return None
328     
329     def analyse_types(self, env):
330         self.not_implemented("analyse_types")
331     
332     def analyse_target_types(self, env):
333         self.analyse_types(env)
334
335     def gil_assignment_check(self, env):
336         if env.nogil and self.type.is_pyobject:
337             error(self.pos, "Assignment of Python object not allowed without gil")
338
339     def check_const(self):
340         self.not_const()
341     
342     def not_const(self):
343         error(self.pos, "Not allowed in a constant expression")
344     
345     def check_const_addr(self):
346         self.addr_not_const()
347     
348     def addr_not_const(self):
349         error(self.pos, "Address is not constant")
350
351     def gil_check(self, env):
352         if env is not None and env.nogil and self.type.is_pyobject:
353             self.gil_error()
354
355     # ----------------- Result Allocation -----------------
356     
357     def result_in_temp(self):
358         #  Return true if result is in a temporary owned by
359         #  this node or one of its subexpressions. Overridden
360         #  by certain nodes which can share the result of
361         #  a subnode.
362         return self.is_temp
363             
364     def allocate_target_temps(self, env, rhs):
365         #  Perform temp allocation for the LHS of an assignment.
366         if debug_temp_alloc:
367             print("%s Allocating target temps" % self)
368         self.allocate_subexpr_temps(env)
369         self.is_target = True
370         if rhs:
371             rhs.release_temp(env)
372         self.release_subexpr_temps(env)
373     
374     def allocate_temps(self, env, result = None):
375         #  Allocate temporary variables for this node and
376         #  all its sub-expressions. If a result is specified,
377         #  this must be a temp node and the specified variable
378         #  is used as the result instead of allocating a new
379         #  one.
380         assert result is None, "deprecated, contact dagss if this triggers"
381         if debug_temp_alloc:
382             print("%s Allocating temps" % self)
383         self.allocate_subexpr_temps(env)
384         self.allocate_temp(env, result)
385         if self.is_temp:
386             self.release_subexpr_temps(env)
387     
388     def allocate_subexpr_temps(self, env):
389         #  Allocate temporary variables for all sub-expressions
390         #  of this node.
391         if debug_temp_alloc:
392             print("%s Allocating temps for: %s" % (self, self.subexprs))
393         for node in self.subexpr_nodes():
394             if node:
395                 if debug_temp_alloc:
396                     print("%s Allocating temps for %s" % (self, node))
397                 node.allocate_temps(env)
398     
399     def allocate_temp(self, env, result = None):
400         #  If this node requires a temporary variable for its
401         #  result, allocate one, otherwise set the result to
402         #  a C code fragment. If a result is specified,
403         #  this must be a temp node and the specified variable
404         #  is used as the result instead of allocating a new
405         #  one.
406         if debug_temp_alloc:
407             print("%s Allocating temp" % self)
408         if result:
409             if not self.is_temp:
410                 raise InternalError("Result forced on non-temp node")
411             self.result_code = result
412         elif self.is_temp:
413             type = self.type
414             if not type.is_void:
415                 if type.is_pyobject:
416                     type = PyrexTypes.py_object_type
417                 self.result_code = env.allocate_temp(type)
418             else:
419                 self.result_code = None
420             if debug_temp_alloc:
421                 print("%s Allocated result %s" % (self, self.result_code))
422                 
423     def target_code(self):
424         #  Return code fragment for use as LHS of a C assignment.
425         return self.calculate_result_code()
426     
427     def calculate_result_code(self):
428         self.not_implemented("calculate_result_code")
429     
430 #    def release_target_temp(self, env):
431 #        #  Release temporaries used by LHS of an assignment.
432 #        self.release_subexpr_temps(env)
433
434     def release_temp(self, env):
435         #  If this node owns a temporary result, release it,
436         #  otherwise release results of its sub-expressions.
437         if self.is_temp:
438             if debug_temp_alloc:
439                 print("%s Releasing result %s" % (self, self.result_code))
440             env.release_temp(self.result_code)
441         else:
442             self.release_subexpr_temps(env)
443     
444     def release_subexpr_temps(self, env):
445         #  Release the results of all sub-expressions of
446         #  this node.
447         for node in self.subexpr_nodes():
448             if node:
449                 node.release_temp(env)
450     
451     # ---------------- Code Generation -----------------
452     
453     def make_owned_reference(self, code):
454         #  If result is a pyobject, make sure we own
455         #  a reference to it.
456         if self.type.is_pyobject and not self.result_in_temp():
457             code.put_incref(self.result(), self.ctype())
458     
459     def generate_evaluation_code(self, code):
460         code.mark_pos(self.pos)
461         #  Generate code to evaluate this node and
462         #  its sub-expressions, and dispose of any
463         #  temporary results of its sub-expressions.
464         self.generate_subexpr_evaluation_code(code)
465         self.generate_result_code(code)
466         if self.is_temp:
467             self.generate_subexpr_disposal_code(code)
468             self.free_subexpr_temps(code)
469
470     def generate_subexpr_evaluation_code(self, code):
471         for node in self.subexpr_nodes():
472             node.generate_evaluation_code(code)
473     
474     def generate_result_code(self, code):
475         self.not_implemented("generate_result_code")
476     
477     def generate_disposal_code(self, code):
478         # If necessary, generate code to dispose of 
479         # temporary Python reference.
480         if self.is_temp:
481             if self.type.is_pyobject:
482                 code.put_decref_clear(self.result(), self.ctype())
483         else:
484             self.generate_subexpr_disposal_code(code)
485     
486     def generate_subexpr_disposal_code(self, code):
487         #  Generate code to dispose of temporary results
488         #  of all sub-expressions.
489         for node in self.subexpr_nodes():
490             node.generate_disposal_code(code)
491     
492     def generate_post_assignment_code(self, code):
493         # Same as generate_disposal_code except that
494         # assignment will have absorbed a reference to
495         # the result if it is a Python object.
496         if self.is_temp:
497             if self.type.is_pyobject:
498                 code.putln("%s = 0;" % self.result())
499         else:
500             self.generate_subexpr_disposal_code(code)
501     
502     def generate_assignment_code(self, rhs, code):
503         #  Stub method for nodes which are not legal as
504         #  the LHS of an assignment. An error will have 
505         #  been reported earlier.
506         pass
507     
508     def generate_deletion_code(self, code):
509         #  Stub method for nodes that are not legal as
510         #  the argument of a del statement. An error
511         #  will have been reported earlier.
512         pass
513
514     def free_temps(self, code):
515         if not self.is_temp:
516             self.free_subexpr_temps(code)
517         # otherwise, already freed in generate_evaluation_code
518     
519     def free_subexpr_temps(self, code):
520         for sub in self.subexpr_nodes():
521             sub.free_temps(code)
522
523     # ---------------- Annotation ---------------------
524     
525     def annotate(self, code):
526         for node in self.subexpr_nodes():
527             node.annotate(code)
528     
529     # ----------------- Coercion ----------------------
530     
531     def coerce_to(self, dst_type, env):
532         #   Coerce the result so that it can be assigned to
533         #   something of type dst_type. If processing is necessary,
534         #   wraps this node in a coercion node and returns that.
535         #   Otherwise, returns this node unchanged.
536         #
537         #   This method is called during the analyse_expressions
538         #   phase of the src_node's processing.
539         src = self
540         src_type = self.type
541         src_is_py_type = src_type.is_pyobject
542         dst_is_py_type = dst_type.is_pyobject
543         
544         if dst_type.is_pyobject:
545             if not src.type.is_pyobject:
546                 src = CoerceToPyTypeNode(src, env)
547             if not src.type.subtype_of(dst_type):
548                 if not isinstance(src, NoneNode):
549                     src = PyTypeTestNode(src, dst_type, env)
550         elif src.type.is_pyobject:
551             src = CoerceFromPyTypeNode(dst_type, src, env)
552         elif (dst_type.is_complex 
553                 and src_type != dst_type
554                 and dst_type.assignable_from(src_type) 
555                 and not env.directives['c99_complex']):
556             src = CoerceToComplexNode(src, dst_type, env)
557         else: # neither src nor dst are py types
558             # Added the string comparison, since for c types that
559             # is enough, but Cython gets confused when the types are
560             # in different pxi files.
561             if not (str(src.type) == str(dst_type) or dst_type.assignable_from(src_type)):
562                 error(self.pos, "Cannot assign type '%s' to '%s'" %
563                     (src.type, dst_type))
564         return src
565
566     def coerce_to_pyobject(self, env):
567         return self.coerce_to(PyrexTypes.py_object_type, env)
568
569     def coerce_to_boolean(self, env):
570         #  Coerce result to something acceptable as
571         #  a boolean value.
572         type = self.type
573         if type.is_pyobject or type.is_ptr or type.is_float:
574             return CoerceToBooleanNode(self, env)
575         else:
576             if not type.is_int and not type.is_error:
577                 error(self.pos, 
578                     "Type '%s' not acceptable as a boolean" % type)
579             return self
580     
581     def coerce_to_integer(self, env):
582         # If not already some C integer type, coerce to longint.
583         if self.type.is_int:
584             return self
585         else:
586             return self.coerce_to(PyrexTypes.c_long_type, env)
587     
588     def coerce_to_temp(self, env):
589         #  Ensure that the result is in a temporary.
590         if self.result_in_temp():
591             return self
592         else:
593             return CoerceToTempNode(self, env)
594     
595     def coerce_to_simple(self, env):
596         #  Ensure that the result is simple (see is_simple).
597         if self.is_simple():
598             return self
599         else:
600             return self.coerce_to_temp(env)
601     
602     def is_simple(self):
603         #  A node is simple if its result is something that can
604         #  be referred to without performing any operations, e.g.
605         #  a constant, local var, C global var, struct member
606         #  reference, or temporary.
607         return self.result_in_temp()
608         
609     def as_cython_attribute(self):
610         return None
611
612
613 class RemoveAllocateTemps(type):
614     def __init__(cls, name, bases, dct):
615         super(RemoveAllocateTemps, cls).__init__(name, bases, dct)
616         def noop(self, env): pass
617         setattr(cls, 'allocate_temps', noop)
618         setattr(cls, 'allocate_temp', noop)
619         setattr(cls, 'release_temp', noop)
620
621 class NewTempExprNode(ExprNode):
622     temp_code = None
623     old_temp = None # error checker for multiple frees etc.
624
625 #   Do not enable this unless you are trying to make all ExprNodes
626 #   NewTempExprNodes (child nodes reached via recursion may not have
627 #   transferred).
628 #    __metaclass__ = RemoveAllocateTemps
629
630     def result(self):
631         if self.is_temp:
632             return self.temp_code
633         else:
634             return self.calculate_result_code()
635
636     def allocate_target_temps(self, env, rhs):
637         self.allocate_subexpr_temps(env)
638         self.is_target = True
639         if rhs:
640             rhs.release_temp(env)
641         self.release_subexpr_temps(env)
642
643     def allocate_temps(self, env, result = None):
644         assert result is None, "deprecated, contact dagss if this triggers"
645         self.allocate_subexpr_temps(env)
646         if self.is_temp:
647             self.release_subexpr_temps(env)
648
649     def allocate_temp(self, env, result = None):
650         assert result is None
651
652     def release_temp(self, env):
653         if self.is_temp:
654             pass
655         else:
656             self.release_subexpr_temps(env)
657
658     def allocate_temp_result(self, code):
659         if self.temp_code:
660             raise RuntimeError("Temp allocated multiple times")
661         type = self.type
662         if not type.is_void:
663             if type.is_pyobject:
664                 type = PyrexTypes.py_object_type
665             self.temp_code = code.funcstate.allocate_temp(
666                 type, manage_ref=True)
667         else:
668             self.temp_code = None
669
670     def release_temp_result(self, code):
671         if not self.temp_code:
672             if self.old_temp:
673                 raise RuntimeError("temp %s released multiple times in %s" % (
674                         self.old_temp, self.__class__.__name__))
675             else:
676                 raise RuntimeError("no temp, but release requested in %s" % (
677                         self.__class__.__name__))
678         code.funcstate.release_temp(self.temp_code)
679         self.old_temp = self.temp_code
680         self.temp_code = None
681
682     def generate_evaluation_code(self, code):
683         code.mark_pos(self.pos)
684         
685         #  Generate code to evaluate this node and
686         #  its sub-expressions, and dispose of any
687         #  temporary results of its sub-expressions.
688         self.generate_subexpr_evaluation_code(code)
689
690         if self.is_temp:
691             self.allocate_temp_result(code)
692
693         self.generate_result_code(code)
694         if self.is_temp:
695             # If we are temp we do not need to wait until this node is disposed
696             # before disposing children.
697             self.generate_subexpr_disposal_code(code)
698             self.free_subexpr_temps(code)
699
700     def generate_disposal_code(self, code):
701         if self.is_temp:
702             if self.type.is_pyobject:
703                 code.put_decref_clear(self.result(), self.ctype())
704         else:
705             # Already done if self.is_temp
706             self.generate_subexpr_disposal_code(code)
707
708     def generate_post_assignment_code(self, code):
709         if self.is_temp:
710             if self.type.is_pyobject:
711                 code.putln("%s = 0;" % self.result())
712         else:
713             self.generate_subexpr_disposal_code(code)
714
715     def free_temps(self, code):
716         if self.is_temp:
717             if not self.type.is_void:
718                 self.release_temp_result(code)
719         else:
720             self.free_subexpr_temps(code)
721         
722 # ExprNode = NewTempExprNode     
723
724 class AtomicExprNode(ExprNode):
725     #  Abstract base class for expression nodes which have
726     #  no sub-expressions.
727     
728     subexprs = []
729
730 class AtomicNewTempExprNode(NewTempExprNode):
731     # I do not dare to convert NameNode yet. This is now
732     # ancestor of all former AtomicExprNode except
733     # NameNode. Should be renamed to AtomicExprNode
734     # when done.
735     
736     #  Abstract base class for expression nodes which have
737     #  no sub-expressions.
738     
739     subexprs = []
740
741     # Override to optimize -- we know we have no children
742     def generate_subexpr_evaluation_code(self, code):
743         pass
744     def generate_subexpr_disposal_code(self, code):
745         pass
746
747 class PyConstNode(AtomicNewTempExprNode):
748     #  Abstract base class for constant Python values.
749     
750     is_literal = 1
751     
752     def is_simple(self):
753         return 1
754     
755     def analyse_types(self, env):
756         self.type = py_object_type
757     
758     def calculate_result_code(self):
759         return self.value
760
761     def generate_result_code(self, code):
762         pass
763
764
765 class NoneNode(PyConstNode):
766     #  The constant value None
767     
768     value = "Py_None"
769
770     constant_result = None
771
772     def compile_time_value(self, denv):
773         return None
774     
775 class EllipsisNode(PyConstNode):
776     #  '...' in a subscript list.
777     
778     value = "Py_Ellipsis"
779
780     constant_result = Ellipsis
781
782     def compile_time_value(self, denv):
783         return Ellipsis
784
785
786 class ConstNode(AtomicNewTempExprNode):
787     # Abstract base type for literal constant nodes.
788     #
789     # value     string      C code fragment
790     
791     is_literal = 1
792     
793     def is_simple(self):
794         return 1
795     
796     def analyse_types(self, env):
797         pass # Types are held in class variables
798     
799     def check_const(self):
800         pass
801     
802     def calculate_result_code(self):
803         return str(self.value)
804
805     def generate_result_code(self, code):
806         pass
807
808
809 class BoolNode(ConstNode):
810     type = PyrexTypes.c_bint_type
811     #  The constant value True or False
812
813     def calculate_constant_result(self):
814         self.constant_result = self.value
815
816     def compile_time_value(self, denv):
817         return self.value
818     
819     def calculate_result_code(self):
820         return str(int(self.value))
821
822 class NullNode(ConstNode):
823     type = PyrexTypes.c_null_ptr_type
824     value = "NULL"
825     constant_result = 0
826
827
828 class CharNode(ConstNode):
829     type = PyrexTypes.c_char_type
830
831     def calculate_constant_result(self):
832         self.constant_result = ord(self.value)
833     
834     def compile_time_value(self, denv):
835         return ord(self.value)
836     
837     def calculate_result_code(self):
838         return "'%s'" % StringEncoding.escape_character(self.value)
839
840
841 class IntNode(ConstNode):
842
843     # unsigned     "" or "U"
844     # longness     "" or "L" or "LL"
845
846     unsigned = ""
847     longness = ""
848     type = PyrexTypes.c_long_type
849
850     def coerce_to(self, dst_type, env):
851         if dst_type.is_numeric and not dst_type.is_complex:
852             self.type = PyrexTypes.c_long_type
853             return self
854         # Arrange for a Python version of the number to be pre-allocated
855         # when coercing to a Python type.
856         if dst_type.is_pyobject:
857             self.entry = env.get_py_num(self.value, self.longness)
858             self.type = PyrexTypes.py_object_type
859         # We still need to perform normal coerce_to processing on the
860         # result, because we might be coercing to an extension type,
861         # in which case a type test node will be needed.
862         return ConstNode.coerce_to(self, dst_type, env)
863         
864     def coerce_to_boolean(self, env):
865         self.type = PyrexTypes.c_bint_type
866         return self
867
868     def calculate_result_code(self):
869         if self.type.is_pyobject:
870             return self.entry.cname
871         else:
872             return str(self.value) + self.unsigned + self.longness
873
874     def calculate_constant_result(self):
875         self.constant_result = int(self.value, 0)
876
877     def compile_time_value(self, denv):
878         return int(self.value, 0)
879
880
881 class FloatNode(ConstNode):
882     type = PyrexTypes.c_double_type
883
884     def calculate_constant_result(self):
885         # calculating float values is usually not a good idea
886         #self.constant_result = float(self.value)
887         pass
888
889     def compile_time_value(self, denv):
890         return float(self.value)
891     
892     def calculate_result_code(self):
893         strval = repr(float(self.value))
894         if strval == 'nan':
895             return "(Py_HUGE_VAL * 0)"
896         elif strval == 'inf':
897             return "Py_HUGE_VAL"
898         elif strval == '-inf':
899             return "(-Py_HUGE_VAL)"
900         else:
901             return strval
902
903
904 class StringNode(ConstNode):
905     #  entry   Symtab.Entry
906     
907     type = PyrexTypes.c_char_ptr_type
908
909     def compile_time_value(self, denv):
910         return self.value
911     
912     def analyse_types(self, env):
913         self.entry = env.add_string_const(self.value)
914         
915     def analyse_as_type(self, env):
916         type = PyrexTypes.parse_basic_type(self.value)
917         if type is not None:    
918             return type
919         from TreeFragment import TreeFragment
920         pos = (self.pos[0], self.pos[1], self.pos[2]-7)
921         declaration = TreeFragment(u"sizeof(%s)" % self.value, name=pos[0].filename, initial_pos=pos)
922         sizeof_node = declaration.root.stats[0].expr
923         sizeof_node.analyse_types(env)
924         if isinstance(sizeof_node, SizeofTypeNode):
925             return sizeof_node.arg_type
926     
927     def coerce_to(self, dst_type, env):
928         if dst_type == PyrexTypes.c_char_ptr_type:
929             self.type = PyrexTypes.c_char_ptr_type
930             return self
931             
932         if dst_type.is_int:
933             if not self.type.is_pyobject and len(self.entry.init) == 1:
934                 return CharNode(self.pos, value=self.value)
935             else:
936                 error(self.pos, "Only coerce single-character ascii strings can be used as ints.")
937                 return self
938         # Arrange for a Python version of the string to be pre-allocated
939         # when coercing to a Python type.
940         if dst_type.is_pyobject and not self.type.is_pyobject:
941             node = self.as_py_string_node(env)
942         else:
943             node = self
944         # We still need to perform normal coerce_to processing on the
945         # result, because we might be coercing to an extension type,
946         # in which case a type test node will be needed.
947         return ConstNode.coerce_to(node, dst_type, env)
948
949     def as_py_string_node(self, env):
950         # Return a new StringNode with the same entry as this node
951         # but whose type is a Python type instead of a C type.
952         entry = self.entry
953         env.add_py_string(entry)
954         return StringNode(self.pos, value = self.value, entry = entry, type = py_object_type)
955             
956     def calculate_result_code(self):
957         if self.type.is_pyobject:
958             return self.entry.pystring_cname
959         else:
960             return self.entry.cname
961
962
963 class UnicodeNode(PyConstNode):
964     #  entry   Symtab.Entry
965
966     type = unicode_type
967
968     def analyse_types(self, env):
969         self.entry = env.add_string_const(self.value)
970         env.add_py_string(self.entry)
971
972     def calculate_result_code(self):
973         return self.entry.pystring_cname
974     
975     def _coerce_to(self, dst_type, env):
976         if not dst_type.is_pyobject:
977             node = StringNode(self.pos, entry = entry, type = py_object_type)
978             return ConstNode.coerce_to(node, dst_type, env)
979         else:
980             return self
981         # We still need to perform normal coerce_to processing on the
982         # result, because we might be coercing to an extension type,
983         # in which case a type test node will be needed.
984         
985     def compile_time_value(self, env):
986         return self.value
987
988
989 class IdentifierStringNode(ConstNode):
990     # A Python string that behaves like an identifier, e.g. for
991     # keyword arguments in a call, or for imported names
992     type = PyrexTypes.py_object_type
993
994     def analyse_types(self, env):
995         self.cname = env.intern_identifier(self.value)
996
997     def calculate_result_code(self):
998         return self.cname
999
1000
1001 class LongNode(AtomicNewTempExprNode):
1002     #  Python long integer literal
1003     #
1004     #  value   string
1005
1006     def calculate_constant_result(self):
1007         self.constant_result = long(self.value)
1008     
1009     def compile_time_value(self, denv):
1010         return long(self.value)
1011
1012     gil_message = "Constructing Python long int"
1013     
1014     def analyse_types(self, env):
1015         self.type = py_object_type
1016         self.gil_check(env)
1017         self.is_temp = 1
1018
1019     gil_message = "Constructing Python long int"
1020
1021     def generate_result_code(self, code):
1022         code.putln(
1023             '%s = PyLong_FromString((char *)"%s", 0, 0); %s' % (
1024                 self.result(),
1025                 self.value,
1026                 code.error_goto_if_null(self.result(), self.pos)))
1027         code.put_gotref(self.py_result())
1028
1029
1030 class ImagNode(AtomicNewTempExprNode):
1031     #  Imaginary number literal
1032     #
1033     #  value   float    imaginary part
1034     
1035     type = PyrexTypes.c_double_complex_type
1036
1037     def calculate_constant_result(self):
1038         self.constant_result = complex(0.0, self.value)
1039     
1040     def compile_time_value(self, denv):
1041         return complex(0.0, self.value)
1042     
1043     def analyse_types(self, env):
1044         self.type.create_declaration_utility_code(env)
1045
1046     def coerce_to(self, dst_type, env):
1047         # Arrange for a Python version of the number to be pre-allocated
1048         # when coercing to a Python type.
1049         if dst_type.is_pyobject:
1050             self.is_temp = 1
1051             self.type = PyrexTypes.py_object_type
1052             self.gil_check(env)
1053         # We still need to perform normal coerce_to processing on the
1054         # result, because we might be coercing to an extension type,
1055         # in which case a type test node will be needed.
1056         return AtomicNewTempExprNode.coerce_to(self, dst_type, env)
1057
1058     gil_message = "Constructing complex number"
1059
1060     def calculate_result_code(self):
1061         if self.type.is_pyobject:
1062             return self.result()
1063         elif self.c99_complex:
1064             return "%rj" % float(self.value)
1065         else:
1066             return "%s(0, %r)" % (self.type.from_parts, float(self.value))
1067
1068     def generate_result_code(self, code):
1069         if self.type.is_pyobject:
1070             code.putln(
1071                 "%s = PyComplex_FromDoubles(0.0, %r); %s" % (
1072                     self.result(),
1073                     float(self.value),
1074                     code.error_goto_if_null(self.result(), self.pos)))
1075             code.put_gotref(self.py_result())
1076         else:
1077             self.c99_complex = code.globalstate.directives['c99_complex']
1078         
1079
1080 class NewExprNode(AtomicExprNode):
1081
1082     # C++ new statement
1083     #
1084     # cppclass              string               c++ class to create
1085     # template_parameters   None or [ExprNode]   temlate parameters, if any
1086     
1087     def analyse_types(self, env):
1088         entry = env.lookup(self.cppclass)
1089         if entry is None or not entry.is_cpp_class:
1090             error(self.pos, "new operator can only be applied to a C++ class")
1091             return
1092         self.cpp_check(env)
1093         if self.template_parameters is not None:
1094             template_types = [v.analyse_as_type(env) for v in self.template_parameters]
1095             type = entry.type.specialize_here(self.pos, template_types)
1096         else:
1097             type = entry.type
1098         constructor = type.scope.lookup(u'<init>')
1099         if constructor is None:
1100             return_type = PyrexTypes.CFuncType(type, [])
1101             return_type = PyrexTypes.CPtrType(return_type)
1102             type.scope.declare_cfunction(u'<init>', return_type, self.pos)
1103             constructor = type.scope.lookup(u'<init>')
1104         self.class_type = type
1105         self.entry = constructor
1106         self.type = constructor.type
1107    
1108     def generate_result_code(self, code):
1109         pass
1110    
1111     def calculate_result_code(self):
1112         return "new " + self.class_type.declaration_code("")
1113
1114
1115 class NameNode(AtomicExprNode):
1116     #  Reference to a local or global variable name.
1117     #
1118     #  name            string    Python name of the variable
1119     #
1120     #  entry           Entry     Symbol table entry
1121     #  interned_cname  string
1122     
1123     is_name = True
1124     is_cython_module = False
1125     cython_attribute = None
1126     lhs_of_first_assignment = False
1127     entry = None
1128
1129     def create_analysed_rvalue(pos, env, entry):
1130         node = NameNode(pos)
1131         node.analyse_types(env, entry=entry)
1132         return node
1133         
1134     def as_cython_attribute(self):
1135         return self.cython_attribute
1136     
1137     create_analysed_rvalue = staticmethod(create_analysed_rvalue)
1138     
1139     def compile_time_value(self, denv):
1140         try:
1141             return denv.lookup(self.name)
1142         except KeyError:
1143             error(self.pos, "Compile-time name '%s' not defined" % self.name)
1144     
1145     def coerce_to(self, dst_type, env):
1146         #  If coercing to a generic pyobject and this is a builtin
1147         #  C function with a Python equivalent, manufacture a NameNode
1148         #  referring to the Python builtin.
1149         #print "NameNode.coerce_to:", self.name, dst_type ###
1150         if dst_type is py_object_type:
1151             entry = self.entry
1152             if entry and entry.is_cfunction:
1153                 var_entry = entry.as_variable
1154                 if var_entry:
1155                     if var_entry.is_builtin and Options.cache_builtins:
1156                         var_entry = env.declare_builtin(var_entry.name, self.pos)
1157                     node = NameNode(self.pos, name = self.name)
1158                     node.entry = var_entry
1159                     node.analyse_rvalue_entry(env)
1160                     return node
1161         return AtomicExprNode.coerce_to(self, dst_type, env)
1162     
1163     def analyse_as_module(self, env):
1164         # Try to interpret this as a reference to a cimported module.
1165         # Returns the module scope, or None.
1166         entry = self.entry
1167         if not entry:
1168             entry = env.lookup(self.name)
1169         if entry and entry.as_module:
1170             return entry.as_module
1171         return None
1172         
1173     def analyse_as_type(self, env):
1174         if self.cython_attribute:
1175             type = PyrexTypes.parse_basic_type(self.cython_attribute)
1176         else:
1177             type = PyrexTypes.parse_basic_type(self.name)
1178         if type:
1179             return type
1180         entry = self.entry
1181         if not entry:
1182             entry = env.lookup(self.name)
1183         if entry and entry.is_type:
1184             return entry.type
1185         else:
1186             return None
1187     
1188     def analyse_as_extension_type(self, env):
1189         # Try to interpret this as a reference to an extension type.
1190         # Returns the extension type, or None.
1191         entry = self.entry
1192         if not entry:
1193             entry = env.lookup(self.name)
1194         if entry and entry.is_type and entry.type.is_extension_type:
1195             return entry.type
1196         else:
1197             return None
1198     
1199     def analyse_target_declaration(self, env):
1200         if not self.entry:
1201             self.entry = env.lookup_here(self.name)
1202         if not self.entry:
1203             self.entry = env.declare_var(self.name, py_object_type, self.pos)
1204         env.control_flow.set_state(self.pos, (self.name, 'initalized'), True)
1205         env.control_flow.set_state(self.pos, (self.name, 'source'), 'assignment')
1206         if self.entry.is_declared_generic:
1207             self.result_ctype = py_object_type
1208     
1209     def analyse_types(self, env):
1210         if self.entry is None:
1211             self.entry = env.lookup(self.name)
1212         if not self.entry:
1213             self.entry = env.declare_builtin(self.name, self.pos)
1214         if not self.entry:
1215             self.type = PyrexTypes.error_type
1216             return
1217         self.analyse_rvalue_entry(env)
1218         
1219     def analyse_target_types(self, env):
1220         self.analyse_entry(env)
1221         if not self.is_lvalue():
1222             error(self.pos, "Assignment to non-lvalue '%s'"
1223                 % self.name)
1224             self.type = PyrexTypes.error_type
1225         self.entry.used = 1
1226         if self.entry.type.is_buffer:
1227             import Buffer
1228             Buffer.used_buffer_aux_vars(self.entry)
1229                 
1230     def analyse_rvalue_entry(self, env):
1231         #print "NameNode.analyse_rvalue_entry:", self.name ###
1232         #print "Entry:", self.entry.__dict__ ###
1233         self.analyse_entry(env)
1234         entry = self.entry
1235         if entry.is_declared_generic:
1236             self.result_ctype = py_object_type
1237         if entry.is_pyglobal or entry.is_builtin:
1238             if Options.cache_builtins and entry.is_builtin:
1239                 self.is_temp = 0
1240             else:
1241                 self.is_temp = 1
1242             env.use_utility_code(get_name_interned_utility_code)
1243             self.gil_check(env)
1244
1245     gil_message = "Accessing Python global or builtin"
1246
1247     def analyse_entry(self, env):
1248         #print "NameNode.analyse_entry:", self.name ###
1249         self.check_identifier_kind()
1250         entry = self.entry
1251         type = entry.type
1252         self.type = type
1253         if entry.is_pyglobal or entry.is_builtin:
1254             assert type.is_pyobject, "Python global or builtin not a Python object"
1255             self.interned_cname = self.entry.interned_cname = \
1256                 env.intern_identifier(self.entry.name)
1257
1258     def check_identifier_kind(self):
1259         #print "NameNode.check_identifier_kind:", self.entry.name ###
1260         #print self.entry.__dict__ ###
1261         entry = self.entry
1262         #entry.used = 1
1263         if not (entry.is_const or entry.is_variable 
1264             or entry.is_builtin or entry.is_cfunction
1265             or entry.is_cpp_class):
1266                 if self.entry.as_variable:
1267                     self.entry = self.entry.as_variable
1268                 else:
1269                     error(self.pos, 
1270                         "'%s' is not a constant, variable or function identifier" % self.name)
1271     
1272     def is_simple(self):
1273         #  If it's not a C variable, it'll be in a temp.
1274         return 1
1275     
1276     def calculate_target_results(self, env):
1277         pass
1278     
1279     def check_const(self):
1280         entry = self.entry
1281         if entry is not None and not (entry.is_const or entry.is_cfunction or entry.is_builtin):
1282             self.not_const()
1283     
1284     def check_const_addr(self):
1285         entry = self.entry
1286         if not (entry.is_cglobal or entry.is_cfunction or entry.is_builtin):
1287             self.addr_not_const()
1288
1289     def is_lvalue(self):
1290         return self.entry.is_variable and \
1291             not self.entry.type.is_array and \
1292             not self.entry.is_readonly
1293     
1294     def is_ephemeral(self):
1295         #  Name nodes are never ephemeral, even if the
1296         #  result is in a temporary.
1297         return 0
1298     
1299     def allocate_temp(self, env, result = None):
1300         AtomicExprNode.allocate_temp(self, env, result)
1301         entry = self.entry
1302         if entry:
1303             entry.used = 1
1304             if entry.type.is_buffer:
1305                 import Buffer
1306                 Buffer.used_buffer_aux_vars(entry)
1307             if entry.utility_code:
1308                 env.use_utility_code(entry.utility_code)
1309         
1310     def calculate_result_code(self):
1311         entry = self.entry
1312         if not entry:
1313             return "<error>" # There was an error earlier
1314         return entry.cname
1315     
1316     def generate_result_code(self, code):
1317         assert hasattr(self, 'entry')
1318         entry = self.entry
1319         if entry is None:
1320             return # There was an error earlier
1321         if entry.is_builtin and Options.cache_builtins:
1322             return # Lookup already cached
1323         elif entry.is_pyglobal or entry.is_builtin:
1324             if entry.is_builtin:
1325                 namespace = Naming.builtins_cname
1326             else: # entry.is_pyglobal
1327                 namespace = entry.scope.namespace_cname
1328             code.putln(
1329                 '%s = __Pyx_GetName(%s, %s); %s' % (
1330                 self.result(),
1331                 namespace, 
1332                 self.interned_cname,
1333                 code.error_goto_if_null(self.result(), self.pos)))
1334             code.put_gotref(self.py_result())
1335             
1336         elif entry.is_local and False:
1337             # control flow not good enough yet
1338             assigned = entry.scope.control_flow.get_state((entry.name, 'initalized'), self.pos)
1339             if assigned is False:
1340                 error(self.pos, "local variable '%s' referenced before assignment" % entry.name)
1341             elif not Options.init_local_none and assigned is None:
1342                 code.putln('if (%s == 0) { PyErr_SetString(PyExc_UnboundLocalError, "%s"); %s }' %
1343                            (entry.cname, entry.name, code.error_goto(self.pos)))
1344                 entry.scope.control_flow.set_state(self.pos, (entry.name, 'initalized'), True)
1345
1346     def generate_assignment_code(self, rhs, code):
1347         #print "NameNode.generate_assignment_code:", self.name ###
1348         entry = self.entry
1349         if entry is None:
1350             return # There was an error earlier
1351
1352         if (self.entry.type.is_ptr and isinstance(rhs, ListNode)
1353             and not self.lhs_of_first_assignment):
1354             error(self.pos, "Literal list must be assigned to pointer at time of declaration")
1355         
1356         # is_pyglobal seems to be True for module level-globals only.
1357         # We use this to access class->tp_dict if necessary.
1358         if entry.is_pyglobal:
1359             namespace = self.entry.scope.namespace_cname
1360             if entry.is_member:
1361                 # if the entry is a member we have to cheat: SetAttr does not work
1362                 # on types, so we create a descriptor which is then added to tp_dict
1363                 code.put_error_if_neg(self.pos,
1364                     'PyDict_SetItem(%s->tp_dict, %s, %s)' % (
1365                         namespace,
1366                         self.interned_cname,
1367                         rhs.py_result()))
1368                 rhs.generate_disposal_code(code)
1369                 rhs.free_temps(code)
1370                 # in Py2.6+, we need to invalidate the method cache
1371                 code.putln("PyType_Modified(%s);" %
1372                            entry.scope.parent_type.typeptr_cname)
1373             else: 
1374                 code.put_error_if_neg(self.pos,
1375                     'PyObject_SetAttr(%s, %s, %s)' % (
1376                         namespace,
1377                         self.interned_cname,
1378                         rhs.py_result()))
1379                 if debug_disposal_code:
1380                     print("NameNode.generate_assignment_code:")
1381                     print("...generating disposal code for %s" % rhs)
1382                 rhs.generate_disposal_code(code)
1383                 rhs.free_temps(code)
1384         else:
1385             if self.type.is_buffer:
1386                 # Generate code for doing the buffer release/acquisition.
1387                 # This might raise an exception in which case the assignment (done
1388                 # below) will not happen.
1389                 #
1390                 # The reason this is not in a typetest-like node is because the
1391                 # variables that the acquired buffer info is stored to is allocated
1392                 # per entry and coupled with it.
1393                 self.generate_acquire_buffer(rhs, code)
1394
1395             if self.type.is_pyobject:
1396                 rhs.make_owned_reference(code)
1397                 #print "NameNode.generate_assignment_code: to", self.name ###
1398                 #print "...from", rhs ###
1399                 #print "...LHS type", self.type, "ctype", self.ctype() ###
1400                 #print "...RHS type", rhs.type, "ctype", rhs.ctype() ###
1401                 if entry.is_cglobal:
1402                     code.put_gotref(self.py_result())
1403                 if not self.lhs_of_first_assignment:
1404                     if entry.is_local and not Options.init_local_none:
1405                         initalized = entry.scope.control_flow.get_state((entry.name, 'initalized'), self.pos)
1406                         if initalized is True:
1407                             code.put_decref(self.result(), self.ctype())
1408                         elif initalized is None:
1409                             code.put_xdecref(self.result(), self.ctype())
1410                     else:
1411                         code.put_decref(self.result(), self.ctype())
1412                 if entry.is_cglobal:
1413                     code.put_giveref(rhs.py_result())
1414             code.putln('%s = %s;' % (self.result(), rhs.result_as(self.ctype())))
1415             if debug_disposal_code:
1416                 print("NameNode.generate_assignment_code:")
1417                 print("...generating post-assignment code for %s" % rhs)
1418             rhs.generate_post_assignment_code(code)
1419             rhs.free_temps(code)
1420
1421     def generate_acquire_buffer(self, rhs, code):
1422         # rhstmp is only used in case the rhs is a complicated expression leading to
1423         # the object, to avoid repeating the same C expression for every reference
1424         # to the rhs. It does NOT hold a reference.
1425         pretty_rhs = isinstance(rhs, NameNode) or rhs.is_temp
1426         if pretty_rhs:
1427             rhstmp = rhs.result_as(self.ctype())
1428         else:
1429             rhstmp = code.funcstate.allocate_temp(self.entry.type, manage_ref=False)
1430             code.putln('%s = %s;' % (rhstmp, rhs.result_as(self.ctype())))
1431
1432         buffer_aux = self.entry.buffer_aux
1433         bufstruct = buffer_aux.buffer_info_var.cname
1434         import Buffer
1435         Buffer.put_assign_to_buffer(self.result(), rhstmp, buffer_aux, self.entry.type,
1436                                     is_initialized=not self.lhs_of_first_assignment,
1437                                     pos=self.pos, code=code)
1438         
1439         if not pretty_rhs:
1440             code.putln("%s = 0;" % rhstmp)
1441             code.funcstate.release_temp(rhstmp)
1442     
1443     def generate_deletion_code(self, code):
1444         if self.entry is None:
1445             return # There was an error earlier
1446         if not self.entry.is_pyglobal:
1447             error(self.pos, "Deletion of local or C global name not supported")
1448             return
1449         code.put_error_if_neg(self.pos, 
1450             '__Pyx_DelAttrString(%s, "%s")' % (
1451                 Naming.module_cname,
1452                 self.entry.name))
1453                 
1454     def annotate(self, code):
1455         if hasattr(self, 'is_called') and self.is_called:
1456             pos = (self.pos[0], self.pos[1], self.pos[2] - len(self.name) - 1)
1457             if self.type.is_pyobject:
1458                 code.annotate(pos, AnnotationItem('py_call', 'python function', size=len(self.name)))
1459             else:
1460                 code.annotate(pos, AnnotationItem('c_call', 'c function', size=len(self.name)))
1461             
1462 class BackquoteNode(ExprNode):
1463     #  `expr`
1464     #
1465     #  arg    ExprNode
1466     
1467     subexprs = ['arg']
1468     
1469     def analyse_types(self, env):
1470         self.arg.analyse_types(env)
1471         self.arg = self.arg.coerce_to_pyobject(env)
1472         self.type = py_object_type
1473         self.gil_check(env)
1474         self.is_temp = 1
1475
1476     gil_message = "Backquote expression"
1477
1478     def calculate_constant_result(self):
1479         self.constant_result = repr(self.arg.constant_result)
1480
1481     def generate_result_code(self, code):
1482         code.putln(
1483             "%s = PyObject_Repr(%s); %s" % (
1484                 self.result(),
1485                 self.arg.py_result(),
1486                 code.error_goto_if_null(self.result(), self.pos)))
1487         code.put_gotref(self.py_result())
1488         
1489
1490
1491 class ImportNode(ExprNode):
1492     #  Used as part of import statement implementation.
1493     #  Implements result = 
1494     #    __import__(module_name, globals(), None, name_list)
1495     #
1496     #  module_name   IdentifierStringNode     dotted name of module
1497     #  name_list     ListNode or None         list of names to be imported
1498     
1499     subexprs = ['module_name', 'name_list']
1500
1501     def analyse_types(self, env):
1502         self.module_name.analyse_types(env)
1503         self.module_name = self.module_name.coerce_to_pyobject(env)
1504         if self.name_list:
1505             self.name_list.analyse_types(env)
1506             self.name_list.coerce_to_pyobject(env)
1507         self.type = py_object_type
1508         self.gil_check(env)
1509         self.is_temp = 1
1510         env.use_utility_code(import_utility_code)
1511
1512     gil_message = "Python import"
1513
1514     def generate_result_code(self, code):
1515         if self.name_list:
1516             name_list_code = self.name_list.py_result()
1517         else:
1518             name_list_code = "0"
1519         code.putln(
1520             "%s = __Pyx_Import(%s, %s); %s" % (
1521                 self.result(),
1522                 self.module_name.py_result(),
1523                 name_list_code,
1524                 code.error_goto_if_null(self.result(), self.pos)))
1525         code.put_gotref(self.py_result())
1526
1527
1528 class IteratorNode(NewTempExprNode):
1529     #  Used as part of for statement implementation.
1530     #
1531     #  allocate_counter_temp/release_counter_temp needs to be called
1532     #  by parent (ForInStatNode)
1533     #
1534     #  Implements result = iter(sequence)
1535     #
1536     #  sequence   ExprNode
1537     
1538     subexprs = ['sequence']
1539     
1540     def analyse_types(self, env):
1541         self.sequence.analyse_types(env)
1542         self.sequence = self.sequence.coerce_to_pyobject(env)
1543         self.type = py_object_type
1544         self.gil_check(env)
1545         self.is_temp = 1
1546
1547     gil_message = "Iterating over Python object"
1548
1549     def allocate_counter_temp(self, code):
1550         self.counter_cname = code.funcstate.allocate_temp(
1551             PyrexTypes.c_py_ssize_t_type, manage_ref=False)
1552
1553     def release_counter_temp(self, code):
1554         code.funcstate.release_temp(self.counter_cname)
1555
1556     def generate_result_code(self, code):
1557         is_builtin_sequence = self.sequence.type is list_type or \
1558             self.sequence.type is tuple_type
1559         if is_builtin_sequence:
1560             code.putln(
1561                 "if (likely(%s != Py_None)) {" % self.sequence.py_result())
1562         else:
1563             code.putln(
1564                 "if (PyList_CheckExact(%s) || PyTuple_CheckExact(%s)) {" % (
1565                     self.sequence.py_result(),
1566                     self.sequence.py_result()))
1567         code.putln(
1568             "%s = 0; %s = %s; __Pyx_INCREF(%s);" % (
1569                 self.counter_cname,
1570                 self.result(),
1571                 self.sequence.py_result(),
1572                 self.result()))
1573         code.putln("} else {")
1574         if is_builtin_sequence:
1575             code.putln(
1576                 'PyErr_SetString(PyExc_TypeError, "\'NoneType\' object is not iterable"); %s' %
1577                 code.error_goto(self.pos))
1578         else:
1579             code.putln("%s = -1; %s = PyObject_GetIter(%s); %s" % (
1580                     self.counter_cname,
1581                     self.result(),
1582                     self.sequence.py_result(),
1583                     code.error_goto_if_null(self.result(), self.pos)))
1584             code.put_gotref(self.py_result())
1585         code.putln("}")
1586
1587
1588 class NextNode(AtomicNewTempExprNode):
1589     #  Used as part of for statement implementation.
1590     #  Implements result = iterator.next()
1591     #  Created during analyse_types phase.
1592     #  The iterator is not owned by this node.
1593     #
1594     #  iterator   ExprNode
1595     
1596     def __init__(self, iterator, env):
1597         self.pos = iterator.pos
1598         self.iterator = iterator
1599         self.type = py_object_type
1600         self.is_temp = 1
1601     
1602     def generate_result_code(self, code):
1603         if self.iterator.sequence.type is list_type:
1604             type_checks = [(list_type, "List")]
1605         elif self.iterator.sequence.type is tuple_type:
1606             type_checks = [(tuple_type, "Tuple")]
1607         else:
1608             type_checks = [(list_type, "List"), (tuple_type, "Tuple")]
1609
1610         for py_type, prefix in type_checks:
1611             if len(type_checks) > 1:
1612                 code.putln(
1613                     "if (likely(Py%s_CheckExact(%s))) {" % (
1614                         prefix, self.iterator.py_result()))
1615             code.putln(
1616                 "if (%s >= Py%s_GET_SIZE(%s)) break;" % (
1617                     self.iterator.counter_cname,
1618                     prefix,
1619                     self.iterator.py_result()))
1620             code.putln(
1621                 "%s = Py%s_GET_ITEM(%s, %s); __Pyx_INCREF(%s); %s++;" % (
1622                     self.result(),
1623                     prefix,
1624                     self.iterator.py_result(),
1625                     self.iterator.counter_cname,
1626                     self.result(),
1627                     self.iterator.counter_cname))
1628             if len(type_checks) > 1:
1629                 code.put("} else ")
1630         if len(type_checks) == 1:
1631             return
1632         code.putln("{")
1633         code.putln(
1634             "%s = PyIter_Next(%s);" % (
1635                 self.result(),
1636                 self.iterator.py_result()))
1637         code.putln(
1638             "if (!%s) {" %
1639                 self.result())
1640         code.putln(code.error_goto_if_PyErr(self.pos))
1641         code.putln("break;")
1642         code.putln("}")
1643         code.put_gotref(self.py_result())
1644         code.putln("}")
1645
1646
1647 class ExcValueNode(AtomicNewTempExprNode):
1648     #  Node created during analyse_types phase
1649     #  of an ExceptClauseNode to fetch the current
1650     #  exception value.
1651     
1652     def __init__(self, pos, env, var):
1653         ExprNode.__init__(self, pos)
1654         self.type = py_object_type
1655         self.var = var
1656     
1657     def calculate_result_code(self):
1658         return self.var
1659
1660     def generate_result_code(self, code):
1661         pass
1662
1663     def analyse_types(self, env):
1664         pass
1665
1666
1667 class TempNode(ExprNode):
1668     #  Node created during analyse_types phase
1669     #  of some nodes to hold a temporary value.
1670
1671     subexprs = []
1672     
1673     def __init__(self, pos, type, env):
1674         ExprNode.__init__(self, pos)
1675         self.type = type
1676         if type.is_pyobject:
1677             self.result_ctype = py_object_type
1678         self.is_temp = 1
1679         
1680     def analyse_types(self, env):
1681         return self.type
1682     
1683     def generate_result_code(self, code):
1684         pass
1685
1686
1687 class PyTempNode(TempNode):
1688     #  TempNode holding a Python value.
1689     
1690     def __init__(self, pos, env):
1691         TempNode.__init__(self, pos, PyrexTypes.py_object_type, env)
1692
1693
1694 #-------------------------------------------------------------------
1695 #
1696 #  Trailer nodes
1697 #
1698 #-------------------------------------------------------------------
1699
1700 class IndexNode(ExprNode):
1701     #  Sequence indexing.
1702     #
1703     #  base     ExprNode
1704     #  index    ExprNode
1705     #  indices  [ExprNode]
1706     #  is_buffer_access boolean Whether this is a buffer access.
1707     #
1708     #  indices is used on buffer access, index on non-buffer access.
1709     #  The former contains a clean list of index parameters, the
1710     #  latter whatever Python object is needed for index access.
1711     
1712     subexprs = ['base', 'index', 'indices']
1713     indices = None
1714
1715     def __init__(self, pos, index, *args, **kw):
1716         ExprNode.__init__(self, pos, index=index, *args, **kw)
1717         self._index = index
1718
1719     def calculate_constant_result(self):
1720         self.constant_result = \
1721             self.base.constant_result[self.index.constant_result]
1722
1723     def compile_time_value(self, denv):
1724         base = self.base.compile_time_value(denv)
1725         index = self.index.compile_time_value(denv)
1726         try:
1727             return base[index]
1728         except Exception, e:
1729             self.compile_time_value_error(e)
1730     
1731     def is_ephemeral(self):
1732         return self.base.is_ephemeral()
1733     
1734     def analyse_target_declaration(self, env):
1735         pass
1736         
1737     def analyse_as_type(self, env):
1738         base_type = self.base.analyse_as_type(env)
1739         if base_type and not base_type.is_pyobject:
1740             if base_type.is_cpp_class:
1741                 if isinstance(self.index, TupleExprNode):
1742                     template_values = self.index.args
1743                 else:
1744                     template_values = [self.index]
1745                 import Nodes
1746                 type_node = Nodes.TemplatedTypeNode(
1747                     pos = self.pos, 
1748                     positional_args = template_values, 
1749                     keyword_args = None)
1750                 return type_node.analyse(env, base_type = base_type)
1751             else:
1752                 return PyrexTypes.CArrayType(base_type, int(self.index.compile_time_value(env)))
1753         return None
1754     
1755     def analyse_types(self, env):
1756         self.analyse_base_and_index_types(env, getting = 1)
1757     
1758     def analyse_target_types(self, env):
1759         self.analyse_base_and_index_types(env, setting = 1)
1760
1761     def analyse_base_and_index_types(self, env, getting = 0, setting = 0):
1762         # Note: This might be cleaned up by having IndexNode
1763         # parsed in a saner way and only construct the tuple if
1764         # needed.
1765
1766         # Note that this function must leave IndexNode in a cloneable state.
1767         # For buffers, self.index is packed out on the initial analysis, and
1768         # when cloning self.indices is copied.
1769         self.is_buffer_access = False
1770
1771         self.base.analyse_types(env)
1772         # Handle the case where base is a literal char* (and we expect a string, not an int)
1773         if isinstance(self.base, StringNode):
1774             self.base = self.base.coerce_to_pyobject(env)
1775
1776         skip_child_analysis = False
1777         buffer_access = False
1778         if self.base.type.is_buffer:
1779             assert hasattr(self.base, "entry") # Must be a NameNode-like node
1780             if self.indices:
1781                 indices = self.indices
1782             else:
1783                 if isinstance(self.index, TupleNode):
1784                     indices = self.index.args
1785                 else:
1786                     indices = [self.index]
1787             if len(indices) == self.base.type.ndim:
1788                 buffer_access = True
1789                 skip_child_analysis = True
1790                 for x in indices:
1791                     x.analyse_types(env)
1792                     if not x.type.is_int:
1793                         buffer_access = False
1794
1795         # On cloning, indices is cloned. Otherwise, unpack index into indices
1796         assert not (buffer_access and isinstance(self.index, CloneNode))
1797
1798         if buffer_access:
1799             self.indices = indices
1800             self.index = None
1801             self.type = self.base.type.dtype
1802             self.is_buffer_access = True
1803             self.buffer_type = self.base.entry.type
1804
1805             if getting and self.type.is_pyobject:
1806                 self.is_temp = True
1807             if setting:
1808                 if not self.base.entry.type.writable:
1809                     error(self.pos, "Writing to readonly buffer")
1810                 else:
1811                     self.base.entry.buffer_aux.writable_needed = True
1812         else:
1813             if isinstance(self.index, TupleNode):
1814                 self.index.analyse_types(env, skip_children=skip_child_analysis)
1815             elif not skip_child_analysis:
1816                 self.index.analyse_types(env)
1817             self.original_index_type = self.index.type
1818             if self.base.type.is_pyobject:
1819                 if self.index.type.is_int:
1820                     self.index = self.index.coerce_to(PyrexTypes.c_py_ssize_t_type, env).coerce_to_simple(env)
1821                 else:
1822                     self.index = self.index.coerce_to_pyobject(env)
1823                 self.type = py_object_type
1824                 self.is_temp = 1
1825             else:
1826                 if self.base.type.is_ptr or self.base.type.is_array:
1827                     self.type = self.base.type.base_type
1828                 else:
1829                     error(self.pos,
1830                         "Attempting to index non-array type '%s'" %
1831                             self.base.type)
1832                     self.type = PyrexTypes.error_type
1833                 if self.index.type.is_pyobject:
1834                     self.index = self.index.coerce_to(
1835                         PyrexTypes.c_py_ssize_t_type, env)
1836                 if not self.index.type.is_int:
1837                     error(self.pos,
1838                         "Invalid index type '%s'" %
1839                             self.index.type)
1840         self.gil_check(env)
1841
1842     gil_message = "Indexing Python object"
1843
1844     def gil_check(self, env):
1845         if self.is_buffer_access and env.nogil:
1846             if env.directives['boundscheck']:
1847                 error(self.pos, "Cannot check buffer index bounds without gil; use boundscheck(False) directive")
1848                 return
1849             elif self.type.is_pyobject:
1850                 error(self.pos, "Cannot access buffer with object dtype without gil")
1851                 return
1852         super(IndexNode, self).gil_check(env)
1853
1854
1855     def check_const_addr(self):
1856         self.base.check_const_addr()
1857         self.index.check_const()
1858     
1859     def is_lvalue(self):
1860         return 1
1861
1862     def calculate_result_code(self):
1863         if self.is_buffer_access:
1864             return "(*%s)" % self.buffer_ptr_code
1865         else:
1866             return "(%s[%s])" % (
1867                 self.base.result(), self.index.result())
1868             
1869     def extra_index_params(self):
1870         if self.index.type.is_int:
1871             if self.original_index_type.signed:
1872                 size_adjustment = ""
1873             else:
1874                 size_adjustment = "+1"
1875             return ", sizeof(%s)%s, %s" % (self.original_index_type.declaration_code(""), size_adjustment, self.original_index_type.to_py_function)
1876         else:
1877             return ""
1878
1879     def generate_subexpr_evaluation_code(self, code):
1880         self.base.generate_evaluation_code(code)
1881         if not self.indices:
1882             self.index.generate_evaluation_code(code)
1883         else:
1884             for i in self.indices:
1885                 i.generate_evaluation_code(code)
1886         
1887     def generate_subexpr_disposal_code(self, code):
1888         self.base.generate_disposal_code(code)
1889         if not self.indices:
1890             self.index.generate_disposal_code(code)
1891         else:
1892             for i in self.indices:
1893                 i.generate_disposal_code(code)
1894
1895     def free_subexpr_temps(self, code):
1896         self.base.free_temps(code)
1897         if not self.indices:
1898             self.index.free_temps(code)
1899         else:
1900             for i in self.indices:
1901                 i.free_temps(code)
1902
1903     def generate_result_code(self, code):
1904         if self.is_buffer_access:
1905             if code.globalstate.directives['nonecheck']:
1906                 self.put_nonecheck(code)
1907             self.buffer_ptr_code = self.buffer_lookup_code(code)
1908             if self.type.is_pyobject:
1909                 # is_temp is True, so must pull out value and incref it.
1910                 code.putln("%s = *%s;" % (self.result(), self.buffer_ptr_code))
1911                 code.putln("__Pyx_INCREF((PyObject*)%s);" % self.result())
1912         elif self.type.is_pyobject:
1913             if self.index.type.is_int:
1914                 index_code = self.index.result()
1915                 if self.base.type is list_type:
1916                     function = "__Pyx_GetItemInt_List"
1917                 elif self.base.type is tuple_type:
1918                     function = "__Pyx_GetItemInt_Tuple"
1919                 else:
1920                     function = "__Pyx_GetItemInt"
1921                 code.globalstate.use_utility_code(getitem_int_utility_code)
1922             else:
1923                 function = "PyObject_GetItem"
1924                 index_code = self.index.py_result()
1925                 sign_code = ""
1926             code.putln(
1927                 "%s = %s(%s, %s%s); if (!%s) %s" % (
1928                     self.result(),
1929                     function,
1930                     self.base.py_result(),
1931                     index_code,
1932                     self.extra_index_params(),
1933                     self.result(),
1934                     code.error_goto(self.pos)))
1935             code.put_gotref(self.py_result())
1936             
1937     def generate_setitem_code(self, value_code, code):
1938         if self.index.type.is_int:
1939             function = "__Pyx_SetItemInt"
1940             index_code = self.index.result()
1941             code.globalstate.use_utility_code(setitem_int_utility_code)
1942         else:
1943             index_code = self.index.py_result()
1944             if self.base.type is dict_type:
1945                 function = "PyDict_SetItem"
1946             # It would seem that we could specalized lists/tuples, but that
1947             # shouldn't happen here. 
1948             # Both PyList_SetItem PyTuple_SetItem and a Py_ssize_t as input, 
1949             # not a PyObject*, and bad conversion here would give the wrong 
1950             # exception. Also, tuples are supposed to be immutable, and raise 
1951             # TypeErrors when trying to set their entries (PyTuple_SetItem 
1952             # is for creating new tuples from). 
1953             else:
1954                 function = "PyObject_SetItem"
1955         code.putln(
1956             "if (%s(%s, %s, %s%s) < 0) %s" % (
1957                 function,
1958                 self.base.py_result(),
1959                 index_code,
1960                 value_code,
1961                 self.extra_index_params(),
1962                 code.error_goto(self.pos)))
1963
1964     def generate_buffer_setitem_code(self, rhs, code, op=""):
1965         # Used from generate_assignment_code and InPlaceAssignmentNode
1966         if code.globalstate.directives['nonecheck']:
1967             self.put_nonecheck(code)
1968         ptrexpr = self.buffer_lookup_code(code)
1969         if self.buffer_type.dtype.is_pyobject:
1970             # Must manage refcounts. Decref what is already there
1971             # and incref what we put in.
1972             ptr = code.funcstate.allocate_temp(self.buffer_type.buffer_ptr_type, manage_ref=False)
1973             rhs_code = rhs.result()
1974             code.putln("%s = %s;" % (ptr, ptrexpr))
1975             code.put_gotref("*%s" % ptr)
1976             code.putln("__Pyx_DECREF(*%s); __Pyx_INCREF(%s);" % (
1977                 ptr, rhs_code
1978                 ))
1979             code.putln("*%s %s= %s;" % (ptr, op, rhs_code))
1980             code.put_giveref("*%s" % ptr)
1981             code.funcstate.release_temp(ptr)
1982         else: 
1983             # Simple case
1984             code.putln("*%s %s= %s;" % (ptrexpr, op, rhs.result()))
1985
1986     def generate_assignment_code(self, rhs, code):
1987         self.generate_subexpr_evaluation_code(code)
1988         if self.is_buffer_access:
1989             self.generate_buffer_setitem_code(rhs, code)
1990         elif self.type.is_pyobject:
1991             self.generate_setitem_code(rhs.py_result(), code)
1992         else:
1993             code.putln(
1994                 "%s = %s;" % (
1995                     self.result(), rhs.result()))
1996         self.generate_subexpr_disposal_code(code)
1997         self.free_subexpr_temps(code)
1998         rhs.generate_disposal_code(code)
1999         rhs.free_temps(code)
2000     
2001     def generate_deletion_code(self, code):
2002         self.generate_subexpr_evaluation_code(code)
2003         #if self.type.is_pyobject:
2004         if self.index.type.is_int:
2005             function = "__Pyx_DelItemInt"
2006             index_code = self.index.result()
2007             code.globalstate.use_utility_code(delitem_int_utility_code)
2008         else:
2009             index_code = self.index.py_result()
2010             if self.base.type is dict_type:
2011                 function = "PyDict_DelItem"
2012             else:
2013                 function = "PyObject_DelItem"
2014         code.putln(
2015             "if (%s(%s, %s%s) < 0) %s" % (
2016                 function,
2017                 self.base.py_result(),
2018                 index_code,
2019                 self.extra_index_params(),
2020                 code.error_goto(self.pos)))
2021         self.generate_subexpr_disposal_code(code)
2022         self.free_subexpr_temps(code)
2023
2024     def buffer_lookup_code(self, code):
2025         # Assign indices to temps
2026         index_temps = [code.funcstate.allocate_temp(i.type, manage_ref=False) for i in self.indices]
2027         for temp, index in zip(index_temps, self.indices):
2028             code.putln("%s = %s;" % (temp, index.result()))
2029         # Generate buffer access code using these temps
2030         import Buffer
2031         # The above could happen because child_attrs is wrong somewhere so that
2032         # options are not propagated.
2033         return Buffer.put_buffer_lookup_code(entry=self.base.entry,
2034                                              index_signeds=[i.type.signed for i in self.indices],
2035                                              index_cnames=index_temps,
2036                                              directives=code.globalstate.directives,
2037                                              pos=self.pos, code=code)
2038
2039     def put_nonecheck(self, code):
2040         code.globalstate.use_utility_code(raise_noneindex_error_utility_code)
2041         code.putln("if (%s) {" % code.unlikely("%s == Py_None") % self.base.result_as(PyrexTypes.py_object_type))
2042         code.putln("__Pyx_RaiseNoneIndexingError();")
2043         code.putln(code.error_goto(self.pos))
2044         code.putln("}")
2045
2046 class SliceIndexNode(ExprNode):
2047     #  2-element slice indexing
2048     #
2049     #  base      ExprNode
2050     #  start     ExprNode or None
2051     #  stop      ExprNode or None
2052     
2053     subexprs = ['base', 'start', 'stop']
2054
2055     def calculate_constant_result(self):
2056         self.constant_result = self.base.constant_result[
2057             self.start.constant_result : self.stop.constant_result]
2058
2059     def compile_time_value(self, denv):
2060         base = self.base.compile_time_value(denv)
2061         if self.start is None:
2062             start = 0
2063         else:
2064             start = self.start.compile_time_value(denv)
2065         if self.stop is None:
2066             stop = None
2067         else:
2068             stop = self.stop.compile_time_value(denv)
2069         try:
2070             return base[start:stop]
2071         except Exception, e:
2072             self.compile_time_value_error(e)
2073     
2074     def analyse_target_declaration(self, env):
2075         pass
2076     
2077     def analyse_target_types(self, env):
2078         self.analyse_types(env)
2079         # when assigning, we must accept any Python type
2080         if self.type.is_pyobject:
2081             self.type = py_object_type
2082
2083     def analyse_types(self, env):
2084         self.base.analyse_types(env)
2085         if self.start:
2086             self.start.analyse_types(env)
2087         if self.stop:
2088             self.stop.analyse_types(env)
2089         base_type = self.base.type
2090         if base_type.is_string:
2091             self.type = bytes_type
2092         elif base_type.is_array or base_type.is_ptr:
2093             # we need a ptr type here instead of an array type, as
2094             # array types can result in invalid type casts in the C
2095             # code
2096             self.type = PyrexTypes.CPtrType(base_type.base_type)
2097         else:
2098             self.base = self.base.coerce_to_pyobject(env)
2099             self.type = py_object_type
2100         if base_type.is_builtin_type:
2101             # slicing builtin types returns something of the same type
2102             self.type = base_type
2103         c_int = PyrexTypes.c_py_ssize_t_type
2104         if self.start:
2105             self.start = self.start.coerce_to(c_int, env)
2106         if self.stop:
2107             self.stop = self.stop.coerce_to(c_int, env)
2108         self.gil_check(env)
2109         self.is_temp = 1
2110
2111     gil_message = "Slicing Python object"
2112
2113     def generate_result_code(self, code):
2114         if not self.type.is_pyobject:
2115             error(self.pos,
2116                   "Slicing is not currently supported for '%s'." % self.type)
2117             return
2118         if self.base.type.is_string:
2119             if self.stop is None:
2120                 code.putln(
2121                     "%s = __Pyx_PyBytes_FromString(%s + %s); %s" % (
2122                         self.result(),
2123                         self.base.result(),
2124                         self.start_code(),
2125                         code.error_goto_if_null(self.result(), self.pos)))
2126             else:
2127                 code.putln(
2128                     "%s = __Pyx_PyBytes_FromStringAndSize(%s + %s, %s - %s); %s" % (
2129                         self.result(),
2130                         self.base.result(),
2131                         self.start_code(),
2132                         self.stop_code(),
2133                         self.start_code(),
2134                         code.error_goto_if_null(self.result(), self.pos)))
2135         else:
2136             code.putln(
2137                 "%s = PySequence_GetSlice(%s, %s, %s); %s" % (
2138                     self.result(),
2139                     self.base.py_result(),
2140                     self.start_code(),
2141                     self.stop_code(),
2142                     code.error_goto_if_null(self.result(), self.pos)))
2143         code.put_gotref(self.py_result())
2144     
2145     def generate_assignment_code(self, rhs, code):
2146         self.generate_subexpr_evaluation_code(code)
2147         if self.type.is_pyobject:
2148             code.put_error_if_neg(self.pos, 
2149                 "PySequence_SetSlice(%s, %s, %s, %s)" % (
2150                     self.base.py_result(),
2151                     self.start_code(),
2152                     self.stop_code(),
2153                     rhs.result()))
2154         else:
2155             start_offset = ''
2156             if self.start:
2157                 start_offset = self.start_code()
2158                 if start_offset == '0':
2159                     start_offset = ''
2160                 else:
2161                     start_offset += '+'
2162             if rhs.type.is_array:
2163                 array_length = rhs.type.size
2164                 self.generate_slice_guard_code(code, array_length)
2165             else:
2166                 error(self.pos,
2167                       "Slice assignments from pointers are not yet supported.")
2168                 # FIXME: fix the array size according to start/stop
2169                 array_length = self.base.type.size
2170             for i in range(array_length):
2171                 code.putln("%s[%s%s] = %s[%d];" % (
2172                         self.base.result(), start_offset, i,
2173                         rhs.result(), i))
2174         self.generate_subexpr_disposal_code(code)
2175         self.free_subexpr_temps(code)
2176         rhs.generate_disposal_code(code)
2177         rhs.free_temps(code)
2178
2179     def generate_deletion_code(self, code):
2180         if not self.base.type.is_pyobject:
2181             error(self.pos,
2182                   "Deleting slices is only supported for Python types, not '%s'." % self.type)
2183             return
2184         self.generate_subexpr_evaluation_code(code)
2185         code.put_error_if_neg(self.pos,
2186             "PySequence_DelSlice(%s, %s, %s)" % (
2187                 self.base.py_result(),
2188                 self.start_code(),
2189                 self.stop_code()))
2190         self.generate_subexpr_disposal_code(code)
2191
2192     def generate_slice_guard_code(self, code, target_size):
2193         if not self.base.type.is_array:
2194             return
2195         slice_size = self.base.type.size
2196         start = stop = None
2197         if self.stop:
2198             stop = self.stop.result()
2199             try:
2200                 stop = int(stop)
2201                 if stop < 0:
2202                     slice_size = self.base.type.size + stop
2203                 else:
2204                     slice_size = stop
2205                 stop = None
2206             except ValueError:
2207                 pass
2208         if self.start:
2209             start = self.start.result()
2210             try:
2211                 start = int(start)
2212                 if start < 0:
2213                     start = self.base.type.size + start
2214                 slice_size -= start
2215                 start = None
2216             except ValueError:
2217                 pass
2218         check = None
2219         if slice_size < 0:
2220             if target_size > 0:
2221                 error(self.pos, "Assignment to empty slice.")
2222         elif start is None and stop is None:
2223             # we know the exact slice length
2224             if target_size != slice_size:
2225                 error(self.pos, "Assignment to slice of wrong length, expected %d, got %d" % (
2226                         slice_size, target_size))
2227         elif start is not None:
2228             if stop is None:
2229                 stop = slice_size
2230             check = "(%s)-(%s)" % (stop, start)
2231         else: # stop is not None:
2232             check = stop
2233         if check:
2234             code.putln("if (unlikely((%s) != %d)) {" % (check, target_size))
2235             code.putln('PyErr_Format(PyExc_ValueError, "Assignment to slice of wrong length, expected %%"PY_FORMAT_SIZE_T"d, got %%"PY_FORMAT_SIZE_T"d", (Py_ssize_t)%d, (Py_ssize_t)(%s));' % (
2236                         target_size, check))
2237             code.putln(code.error_goto(self.pos))
2238             code.putln("}")
2239     
2240     def start_code(self):
2241         if self.start:
2242             return self.start.result()
2243         else:
2244             return "0"
2245     
2246     def stop_code(self):
2247         if self.stop:
2248             return self.stop.result()
2249         elif self.base.type.is_array:
2250             return self.base.type.size
2251         else:
2252             return "PY_SSIZE_T_MAX"
2253     
2254     def calculate_result_code(self):
2255         # self.result() is not used, but this method must exist
2256         return "<unused>"
2257     
2258
2259 class SliceNode(ExprNode):
2260     #  start:stop:step in subscript list
2261     #
2262     #  start     ExprNode
2263     #  stop      ExprNode
2264     #  step      ExprNode
2265
2266     def calculate_constant_result(self):
2267         self.constant_result = self.base.constant_result[
2268             self.start.constant_result : \
2269                 self.stop.constant_result : \
2270                 self.step.constant_result]
2271
2272     def compile_time_value(self, denv):
2273         start = self.start.compile_time_value(denv)
2274         if self.stop is None:
2275             stop = None
2276         else:
2277             stop = self.stop.compile_time_value(denv)
2278         if self.step is None:
2279             step = None
2280         else:
2281             step = self.step.compile_time_value(denv)
2282         try:
2283             return slice(start, stop, step)
2284         except Exception, e:
2285             self.compile_time_value_error(e)
2286
2287     subexprs = ['start', 'stop', 'step']
2288     
2289     def analyse_types(self, env):
2290         self.start.analyse_types(env)
2291         self.stop.analyse_types(env)
2292         self.step.analyse_types(env)
2293         self.start = self.start.coerce_to_pyobject(env)
2294         self.stop = self.stop.coerce_to_pyobject(env)
2295         self.step = self.step.coerce_to_pyobject(env)
2296         self.type = py_object_type
2297         self.gil_check(env)
2298         self.is_temp = 1
2299
2300     gil_message = "Constructing Python slice object"
2301
2302     def generate_result_code(self, code):
2303         code.putln(
2304             "%s = PySlice_New(%s, %s, %s); %s" % (
2305                 self.result(),
2306                 self.start.py_result(), 
2307                 self.stop.py_result(), 
2308                 self.step.py_result(),
2309                 code.error_goto_if_null(self.result(), self.pos)))
2310         code.put_gotref(self.py_result())
2311
2312
2313 class CallNode(NewTempExprNode):
2314     def gil_check(self, env):
2315         # Make sure we're not in a nogil environment
2316         if env.nogil:
2317             error(self.pos, "Calling gil-requiring function without gil")
2318     
2319     def analyse_as_type_constructor(self, env):
2320         type = self.function.analyse_as_type(env)
2321         if type and type.is_struct_or_union:
2322             args, kwds = self.explicit_args_kwds()
2323             items = []
2324             for arg, member in zip(args, type.scope.var_entries):
2325                 items.append(DictItemNode(pos=arg.pos, key=IdentifierStringNode(pos=arg.pos, value=member.name), value=arg))
2326             if kwds:
2327                 items += kwds.key_value_pairs
2328             self.key_value_pairs = items
2329             self.__class__ = DictNode
2330             self.analyse_types(env)
2331             self.coerce_to(type, env)
2332             return True
2333
2334
2335 class SimpleCallNode(CallNode):
2336     #  Function call without keyword, * or ** args.
2337     #
2338     #  function       ExprNode
2339     #  args           [ExprNode]
2340     #  arg_tuple      ExprNode or None     used internally
2341     #  self           ExprNode or None     used internally
2342     #  coerced_self   ExprNode or None     used internally
2343     #  wrapper_call   bool                 used internally
2344     #  has_optional_args   bool            used internally
2345     
2346     subexprs = ['self', 'coerced_self', 'function', 'args', 'arg_tuple']
2347     
2348     self = None
2349     coerced_self = None
2350     arg_tuple = None
2351     wrapper_call = False
2352     has_optional_args = False
2353     
2354     def compile_time_value(self, denv):
2355         function = self.function.compile_time_value(denv)
2356         args = [arg.compile_time_value(denv) for arg in self.args]
2357         try:
2358             return function(*args)
2359         except Exception, e:
2360             self.compile_time_value_error(e)
2361             
2362     def analyse_as_type(self, env):
2363         attr = self.function.as_cython_attribute()
2364         if attr == 'pointer':
2365             if len(self.args) != 1:
2366                 error(self.args.pos, "only one type allowed.")
2367             else:
2368                 type = self.args[0].analyse_as_type(env)
2369                 if not type:
2370                     error(self.args[0].pos, "Unknown type")
2371                 else:
2372                     return PyrexTypes.CPtrType(type)
2373
2374     def explicit_args_kwds(self):
2375         return self.args, None
2376
2377     def analyse_types(self, env):
2378         if self.analyse_as_type_constructor(env):
2379             return
2380         function = self.function
2381         function.is_called = 1
2382         self.function.analyse_types(env)
2383         if function.is_attribute and function.is_py_attr and \
2384            function.attribute == "append" and len(self.args) == 1:
2385             # L.append(x) is almost always applied to a list
2386             self.py_func = self.function
2387             self.function = NameNode(pos=self.function.pos, name="__Pyx_PyObject_Append")
2388             self.function.analyse_types(env)
2389             self.self = self.py_func.obj
2390             function.obj = CloneNode(self.self)
2391             env.use_utility_code(append_utility_code)
2392         if function.is_attribute and function.entry and function.entry.is_cmethod:
2393             # Take ownership of the object from which the attribute
2394             # was obtained, because we need to pass it as 'self'.
2395             self.self = function.obj
2396             function.obj = CloneNode(self.self)
2397         func_type = self.function_type()
2398         if func_type.is_pyobject:
2399             self.arg_tuple = TupleNode(self.pos, args = self.args)
2400             self.arg_tuple.analyse_types(env)
2401             self.args = None
2402             self.type = py_object_type
2403             self.gil_check(env)
2404             self.is_temp = 1
2405         else:
2406             for arg in self.args:
2407                 arg.analyse_types(env)
2408             if self.self and func_type.args:
2409                 # Coerce 'self' to the type expected by the method.
2410                 expected_type = func_type.args[0].type
2411                 self.coerced_self = CloneNode(self.self).coerce_to(
2412                     expected_type, env)
2413                 # Insert coerced 'self' argument into argument list.
2414                 self.args.insert(0, self.coerced_self)
2415             self.analyse_c_function_call(env)
2416     
2417     def function_type(self):
2418         # Return the type of the function being called, coercing a function
2419         # pointer to a function if necessary.
2420         func_type = self.function.type
2421         if func_type.is_ptr:
2422             func_type = func_type.base_type
2423         return func_type
2424     
2425     def analyse_c_function_call(self, env):
2426         entry = PyrexTypes.best_match(self.args, self.function.entry.all_alternatives(), self.pos)
2427         if not entry:
2428             self.type = PyrexTypes.error_type
2429             self.result_code = "<error>"
2430             return
2431         self.function.entry = entry
2432         self.function.type = entry.type
2433         func_type = self.function_type()
2434         # Check no. of args
2435         max_nargs = len(func_type.args)
2436         expected_nargs = max_nargs - func_type.optional_arg_count
2437         actual_nargs = len(self.args)
2438         # Coerce arguments
2439         for i in range(min(max_nargs, actual_nargs)):
2440             formal_type = func_type.args[i].type
2441             self.args[i] = self.args[i].coerce_to(formal_type, env)
2442         for i in range(max_nargs, actual_nargs):
2443             if self.args[i].type.is_pyobject:
2444                 error(self.args[i].pos, 
2445                     "Python object cannot be passed as a varargs parameter")
2446         # Calc result type and code fragment
2447         if isinstance(self.function, NewExprNode):
2448             self.type = PyrexTypes.CPtrType(self.function.class_type)
2449         else:
2450             self.type = func_type.return_type
2451         if self.type.is_pyobject:
2452             self.result_ctype = py_object_type
2453             self.is_temp = 1
2454         elif func_type.exception_value is not None \
2455                  or func_type.exception_check:
2456             self.is_temp = 1
2457         # C++ exception handler
2458         if func_type.exception_check == '+':
2459             if func_type.exception_value is None:
2460                 env.use_utility_code(cpp_exception_utility_code)
2461         # Check gil
2462         if not func_type.nogil:
2463             self.gil_check(env)
2464         if func_type.optional_arg_count and expected_nargs != actual_nargs:
2465             self.has_optional_args = 1
2466             self.is_temp = 1
2467             self.opt_arg_struct = env.allocate_temp(func_type.op_arg_struct.base_type)
2468             env.release_temp(self.opt_arg_struct)
2469         return 1
2470     
2471     def calculate_result_code(self):
2472         return self.c_call_code()
2473     
2474     def c_call_code(self):
2475         func_type = self.function_type()
2476         if self.type is PyrexTypes.error_type or not func_type.is_cfunction:
2477             return "<error>"
2478         formal_args = func_type.args
2479         arg_list_code = []
2480         args = zip(formal_args, self.args)
2481         max_nargs = len(func_type.args)
2482         expected_nargs = max_nargs - func_type.optional_arg_count
2483         actual_nargs = len(self.args)
2484         for formal_arg, actual_arg in args[:expected_nargs]:
2485                 arg_code = actual_arg.result_as(formal_arg.type)
2486                 arg_list_code.append(arg_code)
2487                 
2488         if func_type.is_overridable:
2489             arg_list_code.append(str(int(self.wrapper_call or self.function.entry.is_unbound_cmethod)))
2490                 
2491         if func_type.optional_arg_count:
2492             if expected_nargs == actual_nargs:
2493                 optional_args = 'NULL'
2494             else:
2495                 optional_args = "&%s" % self.opt_arg_struct
2496             arg_list_code.append(optional_args)
2497             
2498         for actual_arg in self.args[len(formal_args):]:
2499             arg_list_code.append(actual_arg.result())
2500         result = "%s(%s)" % (self.function.result(),
2501             ', '.join(arg_list_code))
2502 #        if self.wrapper_call or \
2503 #                self.function.entry.is_unbound_cmethod and self.function.entry.type.is_overridable:
2504 #            result = "(%s = 1, %s)" % (Naming.skip_dispatch_cname, result)
2505         return result
2506     
2507     def generate_result_code(self, code):
2508         func_type = self.function_type()
2509         if func_type.is_pyobject:
2510             arg_code = self.arg_tuple.py_result()
2511             code.putln(
2512                 "%s = PyObject_Call(%s, %s, NULL); %s" % (
2513                     self.result(),
2514                     self.function.py_result(),
2515                     arg_code,
2516                     code.error_goto_if_null(self.result(), self.pos)))
2517             code.put_gotref(self.py_result())
2518         elif func_type.is_cfunction:
2519             if self.has_optional_args:
2520                 actual_nargs = len(self.args)
2521                 expected_nargs = len(func_type.args) - func_type.optional_arg_count
2522                 code.putln("%s.%s = %s;" % (
2523                         self.opt_arg_struct,
2524                         Naming.pyrex_prefix + "n",
2525                         len(self.args) - expected_nargs))
2526                 args = zip(func_type.args, self.args)
2527                 for formal_arg, actual_arg in args[expected_nargs:actual_nargs]:
2528                     code.putln("%s.%s = %s;" % (
2529                             self.opt_arg_struct,
2530                             formal_arg.name,
2531                             actual_arg.result_as(formal_arg.type)))
2532             exc_checks = []
2533             if self.type.is_pyobject:
2534                 exc_checks.append("!%s" % self.result())
2535             else:
2536                 exc_val = func_type.exception_value
2537                 exc_check = func_type.exception_check
2538                 if exc_val is not None:
2539                     exc_checks.append("%s == %s" % (self.result(), exc_val))
2540                 if exc_check:
2541                     exc_checks.append("PyErr_Occurred()")
2542             if self.is_temp or exc_checks:
2543                 rhs = self.c_call_code()
2544                 if self.result():
2545                     lhs = "%s = " % self.result()
2546                     if self.is_temp and self.type.is_pyobject:
2547                         #return_type = self.type # func_type.return_type
2548                         #print "SimpleCallNode.generate_result_code: casting", rhs, \
2549                         #    "from", return_type, "to pyobject" ###
2550                         rhs = typecast(py_object_type, self.type, rhs)
2551                 else:
2552                     lhs = ""
2553                 if func_type.exception_check == '+':
2554                     if func_type.exception_value is None:
2555                         raise_py_exception = "__Pyx_CppExn2PyErr()"
2556                     elif func_type.exception_value.type.is_pyobject:
2557                         raise_py_exception = 'PyErr_SetString(%s, "")' % func_type.exception_value.entry.cname
2558                     else:
2559                         raise_py_exception = '%s(); if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError , "Error converting c++ exception.")' % func_type.exception_value.entry.cname
2560                     code.putln(
2561                     "try {%s%s;} catch(...) {%s; %s}" % (
2562                         lhs,
2563                         rhs,
2564                         raise_py_exception,
2565                         code.error_goto(self.pos)))
2566                 else:
2567                     if exc_checks:
2568                         goto_error = code.error_goto_if(" && ".join(exc_checks), self.pos)
2569                     else:
2570                         goto_error = ""
2571                     code.putln("%s%s; %s" % (lhs, rhs, goto_error))
2572                 if self.type.is_pyobject and self.result():
2573                     code.put_gotref(self.py_result())
2574                     
2575
2576 class GeneralCallNode(CallNode):
2577     #  General Python function call, including keyword,
2578     #  * and ** arguments.
2579     #
2580     #  function         ExprNode
2581     #  positional_args  ExprNode          Tuple of positional arguments
2582     #  keyword_args     ExprNode or None  Dict of keyword arguments
2583     #  starstar_arg     ExprNode or None  Dict of extra keyword args
2584     
2585     subexprs = ['function', 'positional_args', 'keyword_args', 'starstar_arg']
2586
2587     def compile_time_value(self, denv):
2588         function = self.function.compile_time_value(denv)
2589         positional_args = self.positional_args.compile_time_value(denv)
2590         keyword_args = self.keyword_args.compile_time_value(denv)
2591         starstar_arg = self.starstar_arg.compile_time_value(denv)
2592         try:
2593             keyword_args.update(starstar_arg)
2594             return function(*positional_args, **keyword_args)
2595         except Exception, e:
2596             self.compile_time_value_error(e)
2597             
2598     def explicit_args_kwds(self):
2599         if self.starstar_arg or not isinstance(self.positional_args, TupleNode):
2600             raise PostParseError(self.pos,
2601                 'Compile-time keyword arguments must be explicit.')
2602         return self.positional_args.args, self.keyword_args
2603
2604     def analyse_types(self, env):
2605         if self.analyse_as_type_constructor(env):
2606             return
2607         self.function.analyse_types(env)
2608         self.positional_args.analyse_types(env)
2609         if self.keyword_args:
2610             self.keyword_args.analyse_types(env)
2611         if self.starstar_arg:
2612             self.starstar_arg.analyse_types(env)
2613         if not self.function.type.is_pyobject:
2614             if hasattr(self.function, 'entry') and not self.function.entry.as_variable:
2615                 error(self.pos, "Keyword arguments not allowed in cdef functions.")
2616             else:
2617                 self.function = self.function.coerce_to_pyobject(env)
2618         self.positional_args = \
2619             self.positional_args.coerce_to_pyobject(env)
2620         if self.starstar_arg:
2621             self.starstar_arg = \
2622                 self.starstar_arg.coerce_to_pyobject(env)
2623         self.type = py_object_type
2624         self.gil_check(env)
2625         self.is_temp = 1
2626         
2627     def generate_result_code(self, code):
2628         if self.keyword_args and self.starstar_arg:
2629             code.put_error_if_neg(self.pos, 
2630                 "PyDict_Update(%s, %s)" % (
2631                     self.keyword_args.py_result(), 
2632                     self.starstar_arg.py_result()))
2633             keyword_code = self.keyword_args.py_result()
2634         elif self.keyword_args:
2635             keyword_code = self.keyword_args.py_result()
2636         elif self.starstar_arg:
2637             keyword_code = self.starstar_arg.py_result()
2638         else:
2639             keyword_code = None
2640         if not keyword_code:
2641             call_code = "PyObject_Call(%s, %s, NULL)" % (
2642                 self.function.py_result(),
2643                 self.positional_args.py_result())
2644         else:
2645             call_code = "PyEval_CallObjectWithKeywords(%s, %s, %s)" % (
2646                 self.function.py_result(),
2647                 self.positional_args.py_result(),
2648                 keyword_code)
2649         code.putln(
2650             "%s = %s; %s" % (
2651                 self.result(),
2652                 call_code,
2653                 code.error_goto_if_null(self.result(), self.pos)))
2654         code.put_gotref(self.py_result())
2655
2656
2657 class AsTupleNode(ExprNode):
2658     #  Convert argument to tuple. Used for normalising
2659     #  the * argument of a function call.
2660     #
2661     #  arg    ExprNode
2662     
2663     subexprs = ['arg']
2664
2665     def calculate_constant_result(self):
2666         self.constant_result = tuple(self.base.constant_result)
2667     
2668     def compile_time_value(self, denv):
2669         arg = self.arg.compile_time_value(denv)
2670         try:
2671             return tuple(arg)
2672         except Exception, e:
2673             self.compile_time_value_error(e)
2674
2675     def analyse_types(self, env):
2676         self.arg.analyse_types(env)
2677         self.arg = self.arg.coerce_to_pyobject(env)
2678         self.type = tuple_type
2679         self.gil_check(env)
2680         self.is_temp = 1
2681
2682     gil_message = "Constructing Python tuple"
2683
2684     def generate_result_code(self, code):
2685         code.putln(
2686             "%s = PySequence_Tuple(%s); %s" % (
2687                 self.result(),
2688                 self.arg.py_result(),
2689                 code.error_goto_if_null(self.result(), self.pos)))
2690         code.put_gotref(self.py_result())
2691     
2692
2693 class AttributeNode(NewTempExprNode):
2694     #  obj.attribute
2695     #
2696     #  obj          ExprNode
2697     #  attribute    string
2698     #  needs_none_check boolean        Used if obj is an extension type.
2699     #                                  If set to True, it is known that the type is not None.
2700     #
2701     #  Used internally:
2702     #
2703     #  is_py_attr           boolean   Is a Python getattr operation
2704     #  member               string    C name of struct member
2705     #  is_called            boolean   Function call is being done on result
2706     #  entry                Entry     Symbol table entry of attribute
2707     #  interned_attr_cname  string    C name of interned attribute name
2708     
2709     is_attribute = 1
2710     subexprs = ['obj']
2711     
2712     type = PyrexTypes.error_type
2713     entry = None
2714     is_called = 0
2715     needs_none_check = True
2716
2717     def as_cython_attribute(self):
2718         if isinstance(self.obj, NameNode) and self.obj.is_cython_module:
2719             return self.attribute
2720
2721     def coerce_to(self, dst_type, env):
2722         #  If coercing to a generic pyobject and this is a cpdef function
2723         #  we can create the corresponding attribute
2724         if dst_type is py_object_type:
2725             entry = self.entry
2726             if entry and entry.is_cfunction and entry.as_variable:
2727                 # must be a cpdef function
2728                 self.is_temp = 1
2729                 self.entry = entry.as_variable
2730                 self.analyse_as_python_attribute(env) 
2731                 return self
2732         return ExprNode.coerce_to(self, dst_type, env)
2733
2734     def calculate_constant_result(self):
2735         attr = self.attribute
2736         if attr.startswith("__") and attr.endswith("__"):
2737             return
2738         self.constant_result = getattr(self.obj.constant_result, attr)
2739
2740     def compile_time_value(self, denv):
2741         attr = self.attribute
2742         if attr.startswith("__") and attr.endswith("__"):
2743             error(self.pos,
2744                   "Invalid attribute name '%s' in compile-time expression" % attr)
2745             return None
2746         obj = self.obj.compile_time_value(denv)
2747         try:
2748             return getattr(obj, attr)
2749         except Exception, e:
2750             self.compile_time_value_error(e)
2751
2752     def analyse_target_declaration(self, env):
2753         pass
2754     
2755     def analyse_target_types(self, env):
2756         self.analyse_types(env, target = 1)
2757     
2758     def analyse_types(self, env, target = 0):
2759         if self.analyse_as_cimported_attribute(env, target):
2760             return
2761         if not target and self.analyse_as_unbound_cmethod(env):
2762             return
2763         self.analyse_as_ordinary_attribute(env, target)
2764     
2765     def analyse_as_cimported_attribute(self, env, target):
2766         # Try to interpret this as a reference to an imported
2767         # C const, type, var or function. If successful, mutates
2768         # this node into a NameNode and returns 1, otherwise
2769         # returns 0.
2770         module_scope = self.obj.analyse_as_module(env)
2771         if module_scope:
2772             entry = module_scope.lookup_here(self.attribute)
2773             if entry and (
2774                 entry.is_cglobal or entry.is_cfunction
2775                 or entry.is_type or entry.is_const):
2776                     self.mutate_into_name_node(env, entry, target)
2777                     return 1
2778         return 0
2779     
2780     def analyse_as_unbound_cmethod(self, env):
2781         # Try to interpret this as a reference to an unbound
2782         # C method of an extension type. If successful, mutates
2783         # this node into a NameNode and returns 1, otherwise
2784         # returns 0.
2785         type = self.obj.analyse_as_extension_type(env)
2786         if type:
2787             entry = type.scope.lookup_here(self.attribute)
2788             if entry and entry.is_cmethod:
2789                 # Create a temporary entry describing the C method
2790                 # as an ordinary function.
2791                 ubcm_entry = Symtab.Entry(entry.name,
2792                     "%s->%s" % (type.vtabptr_cname, entry.cname),
2793                     entry.type)
2794                 ubcm_entry.is_cfunction = 1
2795                 ubcm_entry.func_cname = entry.func_cname
2796                 ubcm_entry.is_unbound_cmethod = 1
2797                 self.mutate_into_name_node(env, ubcm_entry, None)
2798                 return 1
2799         return 0
2800         
2801     def analyse_as_type(self, env):
2802         module_scope = self.obj.analyse_as_module(env)
2803         if module_scope:
2804             return module_scope.lookup_type(self.attribute)
2805         return None
2806     
2807     def analyse_as_extension_type(self, env):
2808         # Try to interpret this as a reference to an extension type
2809         # in a cimported module. Returns the extension type, or None.
2810         module_scope = self.obj.analyse_as_module(env)
2811         if module_scope:
2812             entry = module_scope.lookup_here(self.attribute)
2813             if entry and entry.is_type and entry.type.is_extension_type:
2814                 return entry.type
2815         return None
2816     
2817     def analyse_as_module(self, env):
2818         # Try to interpret this as a reference to a cimported module
2819         # in another cimported module. Returns the module scope, or None.
2820         module_scope = self.obj.analyse_as_module(env)
2821         if module_scope:
2822             entry = module_scope.lookup_here(self.attribute)
2823             if entry and entry.as_module:
2824                 return entry.as_module
2825         return None
2826                 
2827     def mutate_into_name_node(self, env, entry, target):
2828         # Mutate this node into a NameNode and complete the
2829         # analyse_types phase.
2830         self.__class__ = NameNode
2831         self.name = self.attribute
2832         self.entry = entry
2833         del self.obj
2834         del self.attribute
2835         if target:
2836             NameNode.analyse_target_types(self, env)
2837         else:
2838             NameNode.analyse_rvalue_entry(self, env)
2839     
2840     def analyse_as_ordinary_attribute(self, env, target):
2841         self.obj.analyse_types(env)
2842         self.analyse_attribute(env)
2843         if self.entry and self.entry.is_cmethod and not self.is_called:
2844 #            error(self.pos, "C method can only be called")
2845             pass
2846         ## Reference to C array turns into pointer to first element.
2847         #while self.type.is_array:
2848         #    self.type = self.type.element_ptr_type()
2849         if self.is_py_attr:
2850             if not target:
2851                 self.is_temp = 1
2852                 self.result_ctype = py_object_type
2853     
2854     def analyse_attribute(self, env):
2855         # Look up attribute and set self.type and self.member.
2856         self.is_py_attr = 0
2857         self.member = self.attribute
2858         if self.obj.type.is_string:
2859             self.obj = self.obj.coerce_to_pyobject(env)
2860         obj_type = self.obj.type
2861         if obj_type.is_ptr or obj_type.is_array:
2862             obj_type = obj_type.base_type
2863             self.op = "->"
2864         elif obj_type.is_extension_type:
2865             self.op = "->"
2866         else:
2867             self.op = "."
2868         if obj_type.has_attributes:
2869             entry = None
2870             if obj_type.attributes_known():
2871                 entry = obj_type.scope.lookup_here(self.attribute)
2872                 if entry and entry.is_member:
2873                     entry = None
2874             else:
2875                 error(self.pos, 
2876                     "Cannot select attribute of incomplete type '%s'" 
2877                     % obj_type)
2878                 self.type = PyrexTypes.error_type
2879                 return
2880             self.entry = entry
2881             if entry:
2882                 if obj_type.is_extension_type and entry.name == "__weakref__":
2883                     error(self.pos, "Illegal use of special attribute __weakref__")
2884                 # methods need the normal attribute lookup
2885                 # because they do not have struct entries
2886                 if entry.is_variable or entry.is_cmethod:
2887                     self.type = entry.type
2888                     self.member = entry.cname
2889                     return
2890                 else:
2891                     # If it's not a variable or C method, it must be a Python
2892                     # method of an extension type, so we treat it like a Python
2893                     # attribute.
2894                     pass
2895         # If we get here, the base object is not a struct/union/extension 
2896         # type, or it is an extension type and the attribute is either not
2897         # declared or is declared as a Python method. Treat it as a Python
2898         # attribute reference.
2899         self.analyse_as_python_attribute(env)
2900                     
2901     def analyse_as_python_attribute(self, env):
2902         obj_type = self.obj.type
2903         self.member = self.attribute
2904         if obj_type.is_pyobject:
2905             self.type = py_object_type
2906             self.is_py_attr = 1
2907             self.interned_attr_cname = env.intern_identifier(self.attribute)
2908             self.gil_check(env)
2909         else:
2910             if not obj_type.is_error:
2911                 error(self.pos, 
2912                     "Object of type '%s' has no attribute '%s'" %
2913                     (obj_type, self.attribute))
2914
2915     gil_message = "Accessing Python attribute"
2916
2917     def is_simple(self):
2918         if self.obj:
2919             return self.result_in_temp() or self.obj.is_simple()
2920         else:
2921             return NameNode.is_simple(self)
2922
2923     def is_lvalue(self):
2924         if self.obj:
2925             return 1
2926         else:
2927             return NameNode.is_lvalue(self)
2928     
2929     def is_ephemeral(self):
2930         if self.obj:
2931             return self.obj.is_ephemeral()
2932         else:
2933             return NameNode.is_ephemeral(self)
2934     
2935     def calculate_result_code(self):
2936         #print "AttributeNode.calculate_result_code:", self.member ###
2937         #print "...obj node =", self.obj, "code", self.obj.result() ###
2938         #print "...obj type", self.obj.type, "ctype", self.obj.ctype() ###
2939         obj = self.obj
2940         obj_code = obj.result_as(obj.type)
2941         #print "...obj_code =", obj_code ###
2942         if self.entry and self.entry.is_cmethod:
2943             if obj.type.is_extension_type:
2944                 return "((struct %s *)%s%s%s)->%s" % (
2945                     obj.type.vtabstruct_cname, obj_code, self.op, 
2946                     obj.type.vtabslot_cname, self.member)
2947             else:
2948                 return self.member
2949         elif obj.type.is_complex:
2950             return "__Pyx_%s_PART(%s)" % (self.member.upper(), obj_code)
2951         else:
2952             return "%s%s%s" % (obj_code, self.op, self.member)
2953     
2954     def generate_result_code(self, code):
2955         if self.is_py_attr:
2956             code.putln(
2957                 '%s = PyObject_GetAttr(%s, %s); %s' % (
2958                     self.result(),
2959                     self.obj.py_result(),
2960                     self.interned_attr_cname,
2961                     code.error_goto_if_null(self.result(), self.pos)))
2962             code.put_gotref(self.py_result())
2963         else:
2964             # result_code contains what is needed, but we may need to insert
2965             # a check and raise an exception
2966             if (self.obj.type.is_extension_type
2967                   and self.needs_none_check
2968                   and code.globalstate.directives['nonecheck']):
2969                 self.put_nonecheck(code)
2970     
2971     def generate_assignment_code(self, rhs, code):
2972         self.obj.generate_evaluation_code(code)
2973         if self.is_py_attr:
2974             code.put_error_if_neg(self.pos, 
2975                 'PyObject_SetAttr(%s, %s, %s)' % (
2976                     self.obj.py_result(),
2977                     self.interned_attr_cname,
2978                     rhs.py_result()))
2979             rhs.generate_disposal_code(code)
2980             rhs.free_temps(code)
2981         else:
2982             if (self.obj.type.is_extension_type
2983                   and self.needs_none_check
2984                   and code.globalstate.directives['nonecheck']):
2985                 self.put_nonecheck(code)
2986
2987             select_code = self.result()
2988             if self.type.is_pyobject:
2989                 rhs.make_owned_reference(code)
2990                 code.put_giveref(rhs.py_result())
2991                 code.put_gotref(select_code)
2992                 code.put_decref(select_code, self.ctype())
2993             code.putln(
2994                 "%s = %s;" % (
2995                     select_code,
2996                     rhs.result_as(self.ctype())))
2997                     #rhs.result()))
2998             rhs.generate_post_assignment_code(code)
2999             rhs.free_temps(code)
3000         self.obj.generate_disposal_code(code)
3001         self.obj.free_temps(code)
3002     
3003     def generate_deletion_code(self, code):
3004         self.obj.generate_evaluation_code(code)
3005         if self.is_py_attr:
3006             code.put_error_if_neg(self.pos,
3007                 'PyObject_DelAttr(%s, %s)' % (
3008                     self.obj.py_result(),
3009                     self.interned_attr_cname))
3010         else:
3011             error(self.pos, "Cannot delete C attribute of extension type")
3012         self.obj.generate_disposal_code(code)
3013         self.obj.free_temps(code)
3014         
3015     def annotate(self, code):
3016         if self.is_py_attr:
3017             code.annotate(self.pos, AnnotationItem('py_attr', 'python attribute', size=len(self.attribute)))
3018         else:
3019             code.annotate(self.pos, AnnotationItem('c_attr', 'c attribute', size=len(self.attribute)))
3020
3021     def put_nonecheck(self, code):
3022         code.globalstate.use_utility_code(raise_noneattr_error_utility_code)
3023         code.putln("if (%s) {" % code.unlikely("%s == Py_None") % self.obj.result_as(PyrexTypes.py_object_type))
3024         code.putln("__Pyx_RaiseNoneAttributeError(\"%s\");" % self.attribute.encode("UTF-8")) # todo: fix encoding
3025         code.putln(code.error_goto(self.pos))
3026         code.putln("}")
3027
3028
3029 #-------------------------------------------------------------------
3030 #
3031 #  Constructor nodes
3032 #
3033 #-------------------------------------------------------------------
3034
3035 class SequenceNode(NewTempExprNode):
3036     #  Base class for list and tuple constructor nodes.
3037     #  Contains common code for performing sequence unpacking.
3038     #
3039     #  args                    [ExprNode]
3040     #  iterator                ExprNode
3041     #  unpacked_items          [ExprNode] or None
3042     #  coerced_unpacked_items  [ExprNode] or None
3043     
3044     subexprs = ['args']
3045     
3046     is_sequence_constructor = 1
3047     unpacked_items = None
3048     
3049     def compile_time_value_list(self, denv):
3050         return [arg.compile_time_value(denv) for arg in self.args]
3051
3052     def analyse_target_declaration(self, env):
3053         for arg in self.args:
3054             arg.analyse_target_declaration(env)
3055
3056     def analyse_types(self, env, skip_children=False):
3057         for i in range(len(self.args)):
3058             arg = self.args[i]
3059             if not skip_children: arg.analyse_types(env)
3060             self.args[i] = arg.coerce_to_pyobject(env)
3061         self.type = py_object_type
3062         self.gil_check(env)
3063         self.is_temp = 1
3064
3065     def analyse_target_types(self, env):
3066         self.iterator = PyTempNode(self.pos, env)
3067         self.unpacked_items = []
3068         self.coerced_unpacked_items = []
3069         for arg in self.args:
3070             arg.analyse_target_types(env)
3071             unpacked_item = PyTempNode(self.pos, env)
3072             coerced_unpacked_item = unpacked_item.coerce_to(arg.type, env)
3073             self.unpacked_items.append(unpacked_item)
3074             self.coerced_unpacked_items.append(coerced_unpacked_item)
3075         self.type = py_object_type
3076         env.use_utility_code(unpacking_utility_code)
3077     
3078     def allocate_target_temps(self, env, rhs):
3079         self.iterator.allocate_temps(env)
3080         for node in self.coerced_unpacked_items:
3081             node.allocate_temps(env)
3082             #arg.release_target_temp(env)
3083             #node.release_temp(env)
3084         for arg in self.args:
3085             arg.allocate_target_temps(env, None)
3086         if rhs:
3087             rhs.release_temp(env)
3088         self.iterator.release_temp(env)
3089         for node in self.coerced_unpacked_items:
3090             node.release_temp(env)
3091
3092 #    def release_target_temp(self, env):
3093 #        #for arg in self.args:
3094 #        #    arg.release_target_temp(env)
3095 #        #for node in self.coerced_unpacked_items:
3096 #        #    node.release_temp(env)
3097 #        self.iterator.release_temp(env)
3098     
3099     def generate_result_code(self, code):
3100         self.generate_operation_code(code)
3101     
3102     def generate_assignment_code(self, rhs, code):
3103         # Need to work around the fact that generate_evaluation_code
3104         # allocates the temps in a rather hacky way -- the assignment
3105         # is evaluated twice, within each if-block.
3106
3107         if rhs.type is tuple_type:
3108             tuple_check = "likely(%s != Py_None)"
3109         else:
3110             tuple_check = "PyTuple_CheckExact(%s)"
3111         code.putln(
3112             "if (%s && likely(PyTuple_GET_SIZE(%s) == %s)) {" % (
3113                 tuple_check % rhs.py_result(), 
3114                 rhs.py_result(), 
3115                 len(self.args)))
3116         code.putln("PyObject* tuple = %s;" % rhs.py_result())
3117         for i in range(len(self.args)):
3118             item = self.unpacked_items[i]
3119             code.put(
3120                 "%s = PyTuple_GET_ITEM(tuple, %s); " % (
3121                     item.result(),
3122                     i))
3123             code.put_incref(item.result(), item.ctype())
3124             value_node = self.coerced_unpacked_items[i]
3125             value_node.generate_evaluation_code(code)
3126         rhs.generate_disposal_code(code)
3127
3128         for i in range(len(self.args)):
3129             self.args[i].generate_assignment_code(
3130                 self.coerced_unpacked_items[i], code)
3131                  
3132         code.putln("} else {")
3133
3134         if rhs.type is tuple_type:
3135             code.globalstate.use_utility_code(tuple_unpacking_error_code)
3136             code.putln("__Pyx_UnpackTupleError(%s, %s);" % (
3137                         rhs.py_result(), len(self.args)))
3138             code.putln(code.error_goto(self.pos))
3139         else:
3140             code.putln(
3141                 "%s = PyObject_GetIter(%s); %s" % (
3142                     self.iterator.result(),
3143                     rhs.py_result(),
3144                     code.error_goto_if_null(self.iterator.result(), self.pos)))
3145             code.put_gotref(self.iterator.py_result())
3146             rhs.generate_disposal_code(code)
3147             for i in range(len(self.args)):
3148                 item = self.unpacked_items[i]
3149                 unpack_code = "__Pyx_UnpackItem(%s, %d)" % (
3150                     self.iterator.py_result(), i)
3151                 code.putln(
3152                     "%s = %s; %s" % (
3153                         item.result(),
3154                         typecast(item.ctype(), py_object_type, unpack_code),
3155                         code.error_goto_if_null(item.result(), self.pos)))
3156                 code.put_gotref(item.py_result())
3157                 value_node = self.coerced_unpacked_items[i]
3158                 value_node.generate_evaluation_code(code)
3159             code.put_error_if_neg(self.pos, 
3160                 "__Pyx_EndUnpack(%s)" % (
3161                     self.iterator.py_result()))
3162             if debug_disposal_code:
3163                 print("UnpackNode.generate_assignment_code:")
3164                 print("...generating disposal code for %s" % self.iterator)
3165             self.iterator.generate_disposal_code(code)
3166             self.iterator.free_temps(code)
3167
3168             for i in range(len(self.args)):
3169                 self.args[i].generate_assignment_code(
3170                     self.coerced_unpacked_items[i], code)
3171
3172         code.putln("}")
3173         rhs.free_temps(code)
3174         
3175     def annotate(self, code):
3176         for arg in self.args:
3177             arg.annotate(code)
3178         if self.unpacked_items:
3179             for arg in self.unpacked_items:
3180                 arg.annotate(code)
3181             for arg in self.coerced_unpacked_items:
3182                 arg.annotate(code)
3183
3184
3185 class TupleNode(SequenceNode):
3186     #  Tuple constructor.
3187
3188     gil_message = "Constructing Python tuple"
3189
3190     def analyse_types(self, env, skip_children=False):
3191         if len(self.args) == 0:
3192             self.is_temp = 0
3193             self.is_literal = 1
3194         else:
3195             SequenceNode.analyse_types(self, env, skip_children)
3196         self.type = tuple_type
3197             
3198     def calculate_result_code(self):
3199         if len(self.args) > 0:
3200             error(self.pos, "Positive length tuples must be constructed.")
3201         else:
3202             return Naming.empty_tuple
3203
3204     def calculate_constant_result(self):
3205         self.constant_result = tuple([
3206                 arg.constant_result for arg in self.args])
3207
3208     def compile_time_value(self, denv):
3209         values = self.compile_time_value_list(denv)
3210         try:
3211             return tuple(values)
3212         except Exception, e:
3213             self.compile_time_value_error(e)
3214     
3215     def generate_operation_code(self, code):
3216         if len(self.args) == 0:
3217             # result_code is Naming.empty_tuple
3218             return
3219         code.putln(
3220             "%s = PyTuple_New(%s); %s" % (
3221                 self.result(),
3222                 len(self.args),
3223                 code.error_goto_if_null(self.result(), self.pos)))
3224         code.put_gotref(self.py_result())
3225         for i in range(len(self.args)):
3226             arg = self.args[i]
3227             if not arg.result_in_temp():
3228                 code.put_incref(arg.result(), arg.ctype())
3229             code.putln(
3230                 "PyTuple_SET_ITEM(%s, %s, %s);" % (
3231                     self.result(),
3232                     i,
3233                     arg.py_result()))
3234             code.put_giveref(arg.py_result())
3235     
3236     def generate_subexpr_disposal_code(self, code):
3237         # We call generate_post_assignment_code here instead
3238         # of generate_disposal_code, because values were stored
3239         # in the tuple using a reference-stealing operation.
3240         for arg in self.args:
3241             arg.generate_post_assignment_code(code)
3242             # Should NOT call free_temps -- this is invoked by the default
3243             # generate_evaluation_code which will do that.
3244
3245
3246 class ListNode(SequenceNode):
3247     #  List constructor.
3248     
3249     # obj_conversion_errors    [PyrexError]   used internally
3250     # orignial_args            [ExprNode]     used internally
3251
3252     gil_message = "Constructing Python list"
3253
3254     def analyse_expressions(self, env):
3255         SequenceNode.analyse_expressions(self, env)
3256         self.coerce_to_pyobject(env)
3257
3258     def analyse_types(self, env):
3259         hold_errors()
3260         self.original_args = list(self.args)
3261         SequenceNode.analyse_types(self, env)
3262         self.type = list_type
3263         self.obj_conversion_errors = held_errors()
3264         release_errors(ignore=True)
3265         
3266     def coerce_to(self, dst_type, env):
3267         if dst_type.is_pyobject:
3268             for err in self.obj_conversion_errors:
3269                 report_error(err)
3270             self.obj_conversion_errors = []
3271             if not self.type.subtype_of(dst_type):
3272                 error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
3273         elif dst_type.is_ptr:
3274             base_type = dst_type.base_type
3275             self.type = PyrexTypes.CArrayType(base_type, len(self.args))
3276             for i in range(len(self.original_args)):
3277                 arg = self.args[i]
3278                 if isinstance(arg, CoerceToPyTypeNode):
3279                     arg = arg.arg
3280                 self.args[i] = arg.coerce_to(base_type, env)
3281         elif dst_type.is_struct:
3282             if len(self.args) > len(dst_type.scope.var_entries):
3283                 error(self.pos, "Too may members for '%s'" % dst_type)
3284             else:
3285                 if len(self.args) < len(dst_type.scope.var_entries):
3286                     warning(self.pos, "Too few members for '%s'" % dst_type, 1)
3287                 for i, (arg, member) in enumerate(zip(self.original_args, dst_type.scope.var_entries)):
3288                     if isinstance(arg, CoerceToPyTypeNode):
3289                         arg = arg.arg
3290                     self.args[i] = arg.coerce_to(member.type, env)
3291             self.type = dst_type
3292         else:
3293             self.type = error_type
3294             error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
3295         return self
3296         
3297     def release_temp(self, env):
3298         if self.type.is_array:
3299             # To be valid C++, we must allocate the memory on the stack 
3300             # manually and be sure not to reuse it for something else. 
3301             pass
3302         else:
3303             SequenceNode.release_temp(self, env)
3304
3305     def calculate_constant_result(self):
3306         self.constant_result = [
3307             arg.constant_result for arg in self.args]
3308
3309     def compile_time_value(self, denv):
3310         return self.compile_time_value_list(denv)
3311
3312     def generate_operation_code(self, code):
3313         if self.type.is_pyobject:
3314             for err in self.obj_conversion_errors:
3315                 report_error(err)
3316             code.putln("%s = PyList_New(%s); %s" %
3317                 (self.result(),
3318                 len(self.args),
3319                 code.error_goto_if_null(self.result(), self.pos)))
3320             code.put_gotref(self.py_result())
3321             for i in range(len(self.args)):
3322                 arg = self.args[i]
3323                 #if not arg.is_temp:
3324                 if not arg.result_in_temp():
3325                     code.put_incref(arg.result(), arg.ctype())
3326                 code.putln("PyList_SET_ITEM(%s, %s, %s);" %
3327                     (self.result(),
3328                     i,
3329                     arg.py_result()))
3330                 code.put_giveref(arg.py_result())
3331         elif self.type.is_array:
3332             for i, arg in enumerate(self.args):
3333                 code.putln("%s[%s] = %s;" % (
3334                                 self.result(),
3335                                 i,
3336                                 arg.result()))
3337         elif self.type.is_struct:
3338             for arg, member in zip(self.args, self.type.scope.var_entries):
3339                 code.putln("%s.%s = %s;" % (
3340                         self.result(),
3341                         member.cname,
3342                         arg.result()))
3343         else:
3344             raise InternalError("List type never specified")
3345
3346     def generate_subexpr_disposal_code(self, code):
3347         # We call generate_post_assignment_code here instead
3348         # of generate_disposal_code, because values were stored
3349         # in the list using a reference-stealing operation.
3350         for arg in self.args:
3351             arg.generate_post_assignment_code(code)
3352             # Should NOT call free_temps -- this is invoked by the default
3353             # generate_evaluation_code which will do that.
3354
3355
3356 class ComprehensionNode(NewTempExprNode):
3357     subexprs = ["target"]
3358     child_attrs = ["loop", "append"]
3359
3360     def analyse_types(self, env):
3361         self.target.analyse_expressions(env)
3362         self.type = self.target.type
3363         self.append.target = self # this is a CloneNode used in the PyList_Append in the inner loop
3364         self.loop.analyse_declarations(env)
3365
3366     def allocate_temps(self, env, result = None): 
3367         if debug_temp_alloc:
3368             print("%s Allocating temps" % self)
3369         self.allocate_temp(env, result)
3370         # call loop.analyse_expressions() now to make sure temps get
3371         # allocated at the right time
3372         self.loop.analyse_expressions(env)
3373
3374     def calculate_result_code(self):
3375         return self.target.result()
3376     
3377     def generate_result_code(self, code):
3378         self.generate_operation_code(code)
3379
3380     def generate_operation_code(self, code):
3381         self.loop.generate_execution_code(code)
3382
3383     def annotate(self, code):
3384         self.loop.annotate(code)
3385
3386
3387 class ComprehensionAppendNode(NewTempExprNode):
3388     # Need to be careful to avoid infinite recursion:
3389     # target must not be in child_attrs/subexprs
3390     subexprs = ['expr']
3391     
3392     def analyse_types(self, env):
3393         self.expr.analyse_types(env)
3394         if not self.expr.type.is_pyobject:
3395             self.expr = self.expr.coerce_to_pyobject(env)
3396         self.type = PyrexTypes.c_int_type
3397         self.is_temp = 1
3398
3399     def generate_result_code(self, code):
3400         if self.target.type is list_type:
3401             function = "PyList_Append"
3402         elif self.target.type is set_type:
3403             function = "PySet_Add"
3404         else:
3405             raise InternalError(
3406                 "Invalid type for comprehension node: %s" % self.target.type)
3407             
3408         code.putln("%s = %s(%s, (PyObject*)%s); %s" %
3409             (self.result(),
3410              function,
3411              self.target.result(),
3412              self.expr.result(),
3413              code.error_goto_if(self.result(), self.pos)))
3414
3415 class DictComprehensionAppendNode(ComprehensionAppendNode):
3416     subexprs = ['key_expr', 'value_expr']
3417     
3418     def analyse_types(self, env):
3419         self.key_expr.analyse_types(env)
3420         if not self.key_expr.type.is_pyobject:
3421             self.key_expr = self.key_expr.coerce_to_pyobject(env)
3422         self.value_expr.analyse_types(env)
3423         if not self.value_expr.type.is_pyobject:
3424             self.value_expr = self.value_expr.coerce_to_pyobject(env)
3425         self.type = PyrexTypes.c_int_type
3426         self.is_temp = 1
3427
3428     def generate_result_code(self, code):
3429         code.putln("%s = PyDict_SetItem(%s, (PyObject*)%s, (PyObject*)%s); %s" %
3430             (self.result(),
3431              self.target.result(),
3432              self.key_expr.result(),
3433              self.value_expr.result(),
3434              code.error_goto_if(self.result(), self.pos)))
3435
3436
3437 class SetNode(NewTempExprNode):
3438     #  Set constructor.
3439
3440     subexprs = ['args']
3441
3442     gil_message = "Constructing Python set"
3443
3444     def analyse_types(self, env):
3445         for i in range(len(self.args)):
3446             arg = self.args[i]
3447             arg.analyse_types(env)
3448             self.args[i] = arg.coerce_to_pyobject(env)
3449         self.type = set_type
3450         self.gil_check(env)
3451         self.is_temp = 1
3452
3453     def calculate_constant_result(self):
3454         self.constant_result = set([
3455                 arg.constant_result for arg in self.args])
3456
3457     def compile_time_value(self, denv):
3458         values = [arg.compile_time_value(denv) for arg in self.args]
3459         try:
3460             return set(values)
3461         except Exception, e:
3462             self.compile_time_value_error(e)
3463
3464     def generate_evaluation_code(self, code):
3465         code.globalstate.use_utility_code(Builtin.py23_set_utility_code)
3466         self.allocate_temp_result(code)
3467         code.putln(
3468             "%s = PySet_New(0); %s" % (
3469                 self.result(),
3470                 code.error_goto_if_null(self.result(), self.pos)))
3471         code.put_gotref(self.py_result())
3472         for arg in self.args:
3473             arg.generate_evaluation_code(code)
3474             code.putln(
3475                 code.error_goto_if_neg(
3476                     "PySet_Add(%s, %s)" % (self.result(), arg.py_result()),
3477                     self.pos))
3478             arg.generate_disposal_code(code)
3479             arg.free_temps(code)
3480
3481
3482 class DictNode(ExprNode):
3483     #  Dictionary constructor.
3484     #
3485     #  key_value_pairs  [DictItemNode]
3486     #
3487     # obj_conversion_errors    [PyrexError]   used internally
3488     
3489     subexprs = ['key_value_pairs']
3490
3491     def calculate_constant_result(self):
3492         self.constant_result = dict([
3493                 item.constant_result for item in self.key_value_pairs])
3494     
3495     def compile_time_value(self, denv):
3496         pairs = [(item.key.compile_time_value(denv), item.value.compile_time_value(denv))
3497             for item in self.key_value_pairs]
3498         try:
3499             return dict(pairs)
3500         except Exception, e:
3501             self.compile_time_value_error(e)
3502     
3503     def analyse_types(self, env):
3504         hold_errors()
3505         self.type = dict_type
3506         for item in self.key_value_pairs:
3507             item.analyse_types(env)
3508         self.gil_check(env)
3509         self.obj_conversion_errors = held_errors()
3510         release_errors(ignore=True)
3511         self.is_temp = 1
3512         
3513     def coerce_to(self, dst_type, env):
3514         if dst_type.is_pyobject:
3515             self.release_errors()
3516             if not self.type.subtype_of(dst_type):
3517                 error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
3518         elif dst_type.is_struct_or_union:
3519             self.type = dst_type
3520             if not dst_type.is_struct and len(self.key_value_pairs) != 1:
3521                 error(self.pos, "Exactly one field must be specified to convert to union '%s'" % dst_type)
3522             elif dst_type.is_struct and len(self.key_value_pairs) < len(dst_type.scope.var_entries):
3523                 warning(self.pos, "Not all members given for struct '%s'" % dst_type, 1)
3524             for item in self.key_value_pairs:
3525                 if isinstance(item.key, CoerceToPyTypeNode):
3526                     item.key = item.key.arg
3527                 if not isinstance(item.key, (StringNode, IdentifierStringNode)):
3528                     error(item.key.pos, "Invalid struct field identifier")
3529                     item.key = IdentifierStringNode(item.key.pos, value="<error>")
3530                 else:
3531                     member = dst_type.scope.lookup_here(item.key.value)
3532                     if not member:
3533                         error(item.key.pos, "struct '%s' has no field '%s'" % (dst_type, item.key.value))
3534                     else:
3535                         value = item.value
3536                         if isinstance(value, CoerceToPyTypeNode):
3537                             value = value.arg
3538                         item.value = value.coerce_to(member.type, env)
3539         else:
3540             self.type = error_type
3541             error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
3542         return self
3543     
3544     def release_errors(self):
3545         for err in self.obj_conversion_errors:
3546             report_error(err)
3547         self.obj_conversion_errors = []
3548
3549     gil_message = "Constructing Python dict"
3550
3551     def allocate_temps(self, env, result = None):
3552         #  Custom method used here because key-value
3553         #  pairs are evaluated and used one at a time.
3554         self.allocate_temp(env, result)
3555         for item in self.key_value_pairs:
3556             item.key.allocate_temps(env)
3557             item.value.allocate_temps(env)
3558             item.key.release_temp(env)
3559             item.value.release_temp(env)
3560     
3561     def generate_evaluation_code(self, code):
3562         #  Custom method used here because key-value
3563         #  pairs are evaluated and used one at a time.
3564         if self.type.is_pyobject:
3565             self.release_errors()
3566             code.putln(
3567                 "%s = PyDict_New(); %s" % (
3568                     self.result(),
3569                     code.error_goto_if_null(self.result(), self.pos)))
3570             code.put_gotref(self.py_result())
3571         for item in self.key_value_pairs:
3572             item.generate_evaluation_code(code)
3573             if self.type.is_pyobject:
3574                 code.put_error_if_neg(self.pos, 
3575                     "PyDict_SetItem(%s, %s, %s)" % (
3576                         self.result(),
3577                         item.key.py_result(),
3578                         item.value.py_result()))
3579             else:
3580                 code.putln("%s.%s = %s;" % (
3581                         self.result(),
3582                         item.key.value,
3583                         item.value.result()))
3584             item.generate_disposal_code(code)
3585             item.free_temps(code)
3586             
3587     def annotate(self, code):
3588         for item in self.key_value_pairs:
3589             item.annotate(code)
3590             
3591 class DictItemNode(ExprNode):
3592     # Represents a single item in a DictNode
3593     #
3594     # key          ExprNode
3595     # value        ExprNode
3596     subexprs = ['key', 'value']
3597
3598     def calculate_constant_result(self):
3599         self.constant_result = (
3600             self.key.constant_result, self.value.constant_result)
3601             
3602     def analyse_types(self, env):
3603         self.key.analyse_types(env)
3604         self.value.analyse_types(env)
3605         self.key = self.key.coerce_to_pyobject(env)
3606         self.value = self.value.coerce_to_pyobject(env)
3607         
3608     def generate_evaluation_code(self, code):
3609         self.key.generate_evaluation_code(code)
3610         self.value.generate_evaluation_code(code)
3611
3612     def generate_disposal_code(self, code):
3613         self.key.generate_disposal_code(code)
3614         self.value.generate_disposal_code(code)
3615
3616     def free_temps(self, code):
3617         self.key.free_temps(code)
3618         self.value.free_temps(code)
3619         
3620     def __iter__(self):
3621         return iter([self.key, self.value])
3622
3623
3624 class ClassNode(ExprNode):
3625     #  Helper class used in the implementation of Python
3626     #  class definitions. Constructs a class object given
3627     #  a name, tuple of bases and class dictionary.
3628     #
3629     #  name         EncodedString      Name of the class
3630     #  cname        string             Class name as a Python string
3631     #  bases        ExprNode           Base class tuple
3632     #  dict         ExprNode           Class dict (not owned by this node)
3633     #  doc          ExprNode or None   Doc string
3634     #  module_name  string             Name of defining module
3635     
3636     subexprs = ['bases', 'doc']
3637
3638     def analyse_types(self, env):
3639         self.cname = env.intern_identifier(self.name)
3640         self.bases.analyse_types(env)
3641         if self.doc:
3642             self.doc.analyse_types(env)
3643             self.doc = self.doc.coerce_to_pyobject(env)
3644         self.module_name = env.global_scope().qualified_name
3645         self.type = py_object_type
3646         self.gil_check(env)
3647         self.is_temp = 1
3648         env.use_utility_code(create_class_utility_code);
3649
3650     gil_message = "Constructing Python class"
3651
3652     def generate_result_code(self, code):
3653         if self.doc:
3654             code.put_error_if_neg(self.pos, 
3655                 'PyDict_SetItemString(%s, "__doc__", %s)' % (
3656                     self.dict.py_result(),
3657                     self.doc.py_result()))
3658         code.putln(
3659             '%s = __Pyx_CreateClass(%s, %s, %s, "%s"); %s' % (
3660                 self.result(),
3661                 self.bases.py_result(),
3662                 self.dict.py_result(),
3663                 self.cname,
3664                 self.module_name,
3665                 code.error_goto_if_null(self.result(), self.pos)))
3666         code.put_gotref(self.py_result())
3667
3668
3669 class UnboundMethodNode(ExprNode):
3670     #  Helper class used in the implementation of Python
3671     #  class definitions. Constructs an unbound method
3672     #  object from a class and a function.
3673     #
3674     #  class_cname   string     C var holding the class object
3675     #  function      ExprNode   Function object
3676     
3677     subexprs = ['function']
3678     
3679     def analyse_types(self, env):
3680         self.function.analyse_types(env)
3681         self.type = py_object_type
3682         self.gil_check(env)
3683         self.is_temp = 1
3684
3685     gil_message = "Constructing an unbound method"
3686
3687     def generate_result_code(self, code):
3688         code.putln(
3689             "%s = PyMethod_New(%s, 0, %s); %s" % (
3690                 self.result(),
3691                 self.function.py_result(),
3692                 self.class_cname,
3693                 code.error_goto_if_null(self.result(), self.pos)))
3694         code.put_gotref(self.py_result())
3695
3696 class PyCFunctionNode(AtomicNewTempExprNode):
3697     #  Helper class used in the implementation of Python
3698     #  class definitions. Constructs a PyCFunction object
3699     #  from a PyMethodDef struct.
3700     #
3701     #  pymethdef_cname   string   PyMethodDef structure
3702     
3703     def analyse_types(self, env):
3704         self.type = py_object_type
3705         self.gil_check(env)
3706         self.is_temp = 1
3707
3708     gil_message = "Constructing Python function"
3709
3710     def generate_result_code(self, code):
3711         code.putln(
3712             "%s = PyCFunction_New(&%s, 0); %s" % (
3713                 self.result(),
3714                 self.pymethdef_cname,
3715                 code.error_goto_if_null(self.result(), self.pos)))
3716         code.put_gotref(self.py_result())
3717
3718 #-------------------------------------------------------------------
3719 #
3720 #  Unary operator nodes
3721 #
3722 #-------------------------------------------------------------------
3723
3724 compile_time_unary_operators = {
3725     'not': operator.not_,
3726     '~': operator.inv,
3727     '-': operator.neg,
3728     '+': operator.pos,
3729 }
3730
3731 class UnopNode(ExprNode):
3732     #  operator     string
3733     #  operand      ExprNode
3734     #
3735     #  Processing during analyse_expressions phase:
3736     #
3737     #    analyse_c_operation
3738     #      Called when the operand is not a pyobject.
3739     #      - Check operand type and coerce if needed.
3740     #      - Determine result type and result code fragment.
3741     #      - Allocate temporary for result if needed.
3742     
3743     subexprs = ['operand']
3744     infix = True
3745
3746     def calculate_constant_result(self):
3747         func = compile_time_unary_operators[self.operator]
3748         self.constant_result = func(self.operand.constant_result)
3749     
3750     def compile_time_value(self, denv):
3751         func = compile_time_unary_operators.get(self.operator)
3752         if not func:
3753             error(self.pos,
3754                 "Unary '%s' not supported in compile-time expression"
3755                     % self.operator)
3756         operand = self.operand.compile_time_value(denv)
3757         try:
3758             return func(operand)
3759         except Exception, e:
3760             self.compile_time_value_error(e)
3761
3762     def analyse_types(self, env):
3763         self.operand.analyse_types(env)
3764         if self.is_py_operation():
3765             self.coerce_operand_to_pyobject(env)
3766             self.type = py_object_type
3767             self.gil_check(env)
3768             self.is_temp = 1
3769         elif self.is_cpp_operation():
3770             self.analyse_cpp_operation(env)
3771         else:
3772             self.analyse_c_operation(env)
3773     
3774     def check_const(self):
3775         self.operand.check_const()
3776     
3777     def is_py_operation(self):
3778         return self.operand.type.is_pyobject
3779
3780     def is_cpp_operation(self):
3781         return self.operand.type.is_cpp_class
3782     
3783     def coerce_operand_to_pyobject(self, env):
3784         self.operand = self.operand.coerce_to_pyobject(env)
3785     
3786     def generate_result_code(self, code):
3787         if self.operand.type.is_pyobject:
3788             self.generate_py_operation_code(code)
3789         else:
3790             if self.is_temp:
3791                 self.generate_c_operation_code(code)
3792     
3793     def generate_py_operation_code(self, code):
3794         function = self.py_operation_function()
3795         code.putln(
3796             "%s = %s(%s); %s" % (
3797                 self.result(), 
3798                 function, 
3799                 self.operand.py_result(),
3800                 code.error_goto_if_null(self.result(), self.pos)))
3801         code.put_gotref(self.py_result())
3802         
3803     def type_error(self):
3804         if not self.operand.type.is_error:
3805             error(self.pos, "Invalid operand type for '%s' (%s)" %
3806                 (self.operator, self.operand.type))
3807         self.type = PyrexTypes.error_type
3808
3809     def analyse_cpp_operation(self, env):
3810         type = operand.type
3811         if type.is_ptr:
3812             type = type.base_type
3813         entry = env.lookup(type.name)
3814         function = entry.type.scope.lookup("operator%s" % self.operator)
3815         if not function:
3816             error(self.pos, "'%s' operator not defined for %s"
3817                 % (self.operator, type))
3818             self.type_error()
3819             return
3820         self.type = function.type.return_type
3821         
3822
3823
3824 class NotNode(ExprNode):
3825     #  'not' operator
3826     #
3827     #  operand   ExprNode
3828
3829     def calculate_constant_result(self):
3830         self.constant_result = not self.operand.constant_result
3831
3832     def compile_time_value(self, denv):
3833         operand = self.operand.compile_time_value(denv)
3834         try:
3835             return not operand
3836         except Exception, e:
3837             self.compile_time_value_error(e)
3838
3839     subexprs = ['operand']
3840     
3841     def analyse_types(self, env):
3842         self.operand.analyse_types(env)
3843         self.operand = self.operand.coerce_to_boolean(env)
3844         self.type = PyrexTypes.c_bint_type
3845     
3846     def calculate_result_code(self):
3847         return "(!%s)" % self.operand.result()
3848     
3849     def generate_result_code(self, code):
3850         pass
3851
3852
3853 class UnaryPlusNode(UnopNode):
3854     #  unary '+' operator
3855     
3856     operator = '+'
3857     
3858     def analyse_c_operation(self, env):
3859         self.type = self.operand.type
3860     
3861     def py_operation_function(self):
3862         return "PyNumber_Positive"
3863     
3864     def calculate_result_code(self):
3865         return self.operand.result()
3866
3867
3868 class UnaryMinusNode(UnopNode):
3869     #  unary '-' operator
3870     
3871     operator = '-'
3872     
3873     def analyse_c_operation(self, env):
3874         if self.operand.type.is_numeric:
3875             self.type = self.operand.type
3876         else:
3877             self.type_error()
3878         if self.type.is_complex:
3879             self.infix = env.directives['c99_complex']
3880     
3881     def py_operation_function(self):
3882         return "PyNumber_Negative"
3883     
3884     def calculate_result_code(self):
3885         if self.infix:
3886             return "(-%s)" % self.operand.result()
3887         else:
3888             return "%s(%s)" % (self.operand.type.unary_op('-'), self.operand.result())
3889
3890 class TildeNode(UnopNode):
3891     #  unary '~' operator
3892
3893     def analyse_c_operation(self, env):
3894         if self.operand.type.is_int:
3895             self.type = self.operand.type
3896         else:
3897             self.type_error()
3898
3899     def py_operation_function(self):
3900         return "PyNumber_Invert"
3901     
3902     def calculate_result_code(self):
3903         return "(~%s)" % self.operand.result()
3904
3905
3906 class AmpersandNode(ExprNode):
3907     #  The C address-of operator.
3908     #
3909     #  operand  ExprNode
3910     
3911     subexprs = ['operand']
3912
3913     def analyse_types(self, env):
3914         self.operand.analyse_types(env)
3915         argtype = self.operand.type
3916         if not (argtype.is_cfunction or self.operand.is_lvalue()):
3917             self.error("Taking address of non-lvalue")
3918             return
3919         if argtype.is_pyobject:
3920             self.error("Cannot take address of Python variable")
3921             return
3922         self.type = PyrexTypes.c_ptr_type(argtype)
3923     
3924     def check_const(self):
3925         self.operand.check_const_addr()
3926     
3927     def error(self, mess):
3928         error(self.pos, mess)
3929         self.type = PyrexTypes.error_type
3930         self.result_code = "<error>"
3931     
3932     def calculate_result_code(self):
3933         return "(&%s)" % self.operand.result()
3934
3935     def generate_result_code(self, code):
3936         pass
3937     
3938
3939 unop_node_classes = {
3940     "+":  UnaryPlusNode,
3941     "-":  UnaryMinusNode,
3942     "~":  TildeNode,
3943 }
3944
3945 def unop_node(pos, operator, operand):
3946     # Construct unnop node of appropriate class for 
3947     # given operator.
3948     if isinstance(operand, IntNode) and operator == '-':
3949         return IntNode(pos = operand.pos, value = str(-int(operand.value, 0)))
3950     elif isinstance(operand, UnopNode) and operand.operator == operator:
3951         warning(pos, "Python has no increment/decrement operator: %s%sx = %s(%sx) = x" % ((operator,)*4), 5)
3952     return unop_node_classes[operator](pos, 
3953         operator = operator, 
3954         operand = operand)
3955
3956
3957 class TypecastNode(NewTempExprNode):
3958     #  C type cast
3959     #
3960     #  operand      ExprNode
3961     #  base_type    CBaseTypeNode
3962     #  declarator   CDeclaratorNode
3963     #
3964     #  If used from a transform, one can if wanted specify the attribute
3965     #  "type" directly and leave base_type and declarator to None
3966     
3967     subexprs = ['operand']
3968     base_type = declarator = type = None
3969     
3970     def analyse_types(self, env):
3971         if self.type is None:
3972             base_type = self.base_type.analyse(env)
3973             _, self.type = self.declarator.analyse(base_type, env)
3974         if self.type.is_cfunction:
3975             error(self.pos,
3976                 "Cannot cast to a function type")
3977             self.type = PyrexTypes.error_type
3978         self.operand.analyse_types(env)
3979         to_py = self.type.is_pyobject
3980         from_py = self.operand.type.is_pyobject
3981         if from_py and not to_py and self.operand.is_ephemeral() and not self.type.is_numeric:
3982             error(self.pos, "Casting temporary Python object to non-numeric non-Python type")
3983         if to_py and not from_py:
3984             if (self.operand.type.to_py_function and
3985                     self.operand.type.create_to_py_utility_code(env)):
3986                 self.result_ctype = py_object_type
3987                 self.operand = self.operand.coerce_to_pyobject(env)
3988             else:
3989                 if not (self.operand.type.is_ptr and self.operand.type.base_type.is_void):
3990                     warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.operand.type, self.type))
3991                 self.operand = self.operand.coerce_to_simple(env)
3992         elif from_py and not to_py:
3993             if self.type.from_py_function:
3994                 self.operand = self.operand.coerce_to(self.type, env)
3995             elif self.type.is_ptr and not (self.type.base_type.is_void or self.type.base_type.is_struct):
3996                 error(self.pos, "Python objects cannot be casted to pointers of primitive types")
3997             else:
3998                 warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.type, self.operand.type))
3999         elif from_py and to_py:
4000             if self.typecheck and self.type.is_extension_type:
4001                 self.operand = PyTypeTestNode(self.operand, self.type, env)
4002     
4003     def check_const(self):
4004         self.operand.check_const()
4005
4006     def calculate_constant_result(self):
4007         # we usually do not know the result of a type cast at code
4008         # generation time
4009         pass
4010     
4011     def calculate_result_code(self):
4012         opnd = self.operand
4013         return self.type.cast_code(opnd.result())
4014     
4015     def result_as(self, type):
4016         if self.type.is_pyobject and not self.is_temp:
4017             #  Optimise away some unnecessary casting
4018             return self.operand.result_as(type)
4019         else:
4020             return ExprNode.result_as(self, type)
4021
4022     def generate_result_code(self, code):
4023         if self.is_temp:
4024             code.putln(
4025                 "%s = (PyObject *)%s;" % (
4026                     self.result(),
4027                     self.operand.result()))
4028             code.put_incref(self.result(), self.ctype())
4029
4030
4031 class SizeofNode(ExprNode):
4032     #  Abstract base class for sizeof(x) expression nodes.
4033     
4034     type = PyrexTypes.c_size_t_type
4035
4036     def check_const(self):
4037         pass
4038
4039     def generate_result_code(self, code):
4040         pass
4041
4042
4043 class SizeofTypeNode(SizeofNode):
4044     #  C sizeof function applied to a type
4045     #
4046     #  base_type   CBaseTypeNode
4047     #  declarator  CDeclaratorNode
4048     
4049     subexprs = []
4050     arg_type = None
4051     
4052     def analyse_types(self, env):
4053         # we may have incorrectly interpreted a dotted name as a type rather than an attribute
4054         # this could be better handled by more uniformly treating types as runtime-available objects
4055         if 0 and self.base_type.module_path:
4056             path = self.base_type.module_path
4057             obj = env.lookup(path[0])
4058             if obj.as_module is None:
4059                 operand = NameNode(pos=self.pos, name=path[0])
4060                 for attr in path[1:]:
4061                     operand = AttributeNode(pos=self.pos, obj=operand, attribute=attr)
4062                 operand = AttributeNode(pos=self.pos, obj=operand, attribute=self.base_type.name)
4063                 self.operand = operand
4064                 self.__class__ = SizeofVarNode
4065                 self.analyse_types(env)
4066                 return
4067         if self.arg_type is None:
4068             base_type = self.base_type.analyse(env)
4069             _, arg_type = self.declarator.analyse(base_type, env)
4070             self.arg_type = arg_type
4071         self.check_type()
4072         
4073     def check_type(self):
4074         arg_type = self.arg_type
4075         if arg_type.is_pyobject and not arg_type.is_extension_type:
4076             error(self.pos, "Cannot take sizeof Python object")
4077         elif arg_type.is_void:
4078             error(self.pos, "Cannot take sizeof void")
4079         elif not arg_type.is_complete():
4080             error(self.pos, "Cannot take sizeof incomplete type '%s'" % arg_type)
4081         
4082     def calculate_result_code(self):
4083         if self.arg_type.is_extension_type:
4084             # the size of the pointer is boring
4085             # we want the size of the actual struct
4086             arg_code = self.arg_type.declaration_code("", deref=1)
4087         else:
4088             arg_code = self.arg_type.declaration_code("")
4089         return "(sizeof(%s))" % arg_code
4090     
4091
4092 class SizeofVarNode(SizeofNode):
4093     #  C sizeof function applied to a variable
4094     #
4095     #  operand   ExprNode
4096     
4097     subexprs = ['operand']
4098     
4099     def analyse_types(self, env):
4100         # We may actually be looking at a type rather than a variable...
4101         # If we are, traditional analysis would fail...
4102         operand_as_type = self.operand.analyse_as_type(env)
4103         if operand_as_type:
4104             self.arg_type = operand_as_type
4105             self.__class__ = SizeofTypeNode
4106             self.check_type()
4107         else:
4108             self.operand.analyse_types(env)
4109     
4110     def calculate_result_code(self):
4111         return "(sizeof(%s))" % self.operand.result()
4112     
4113     def generate_result_code(self, code):
4114         pass
4115
4116
4117 #-------------------------------------------------------------------
4118 #
4119 #  Binary operator nodes
4120 #
4121 #-------------------------------------------------------------------
4122
4123 def _not_in(x, seq):
4124     return x not in seq
4125
4126 compile_time_binary_operators = {
4127     '<': operator.lt,
4128     '<=': operator.le,
4129     '==': operator.eq,
4130     '!=': operator.ne,
4131     '>=': operator.ge,
4132     '>': operator.gt,
4133     'is': operator.is_,
4134     'is_not': operator.is_not,
4135     '+': operator.add,
4136     '&': operator.and_,
4137     '/': operator.div,
4138     '//': operator.floordiv,
4139     '<<': operator.lshift,
4140     '%': operator.mod,
4141     '*': operator.mul,
4142     '|': operator.or_,
4143     '**': operator.pow,
4144     '>>': operator.rshift,
4145     '-': operator.sub,
4146     #'/': operator.truediv,
4147     '^': operator.xor,
4148     'in': operator.contains,
4149     'not_in': _not_in,
4150 }
4151
4152 def get_compile_time_binop(node):
4153     func = compile_time_binary_operators.get(node.operator)
4154     if not func:
4155         error(node.pos,
4156             "Binary '%s' not supported in compile-time expression"
4157                 % node.operator)
4158     return func
4159
4160 class BinopNode(NewTempExprNode):
4161     #  operator     string
4162     #  operand1     ExprNode
4163     #  operand2     ExprNode
4164     #
4165     #  Processing during analyse_expressions phase:
4166     #
4167     #    analyse_c_operation
4168     #      Called when neither operand is a pyobject.
4169     #      - Check operand types and coerce if needed.
4170     #      - Determine result type and result code fragment.
4171     #      - Allocate temporary for result if needed.
4172     
4173     subexprs = ['operand1', 'operand2']
4174
4175     def calculate_constant_result(self):
4176         func = compile_time_binary_operators[self.operator]
4177         self.constant_result = func(
4178             self.operand1.constant_result,
4179             self.operand2.constant_result)
4180
4181     def compile_time_value(self, denv):
4182         func = get_compile_time_binop(self)
4183         operand1 = self.operand1.compile_time_value(denv)
4184         operand2 = self.operand2.compile_time_value(denv)
4185         try:
4186             return func(operand1, operand2)
4187         except Exception, e:
4188             self.compile_time_value_error(e)
4189
4190     def analyse_types(self, env):
4191         self.operand1.analyse_types(env)
4192         self.operand2.analyse_types(env)
4193         if self.is_py_operation():
4194             self.coerce_operands_to_pyobjects(env)
4195             self.type = py_object_type
4196             self.gil_check(env)
4197             self.is_temp = 1
4198             if Options.incref_local_binop and self.operand1.type.is_pyobject:
4199                 self.operand1 = self.operand1.coerce_to_temp(env)
4200         elif self.is_cpp_operation():
4201             self.analyse_cpp_operation(env)
4202         else:
4203             self.analyse_c_operation(env)
4204     
4205     def is_py_operation(self):
4206         return (self.operand1.type.is_pyobject 
4207             or self.operand2.type.is_pyobject)
4208     
4209     def is_cpp_operation(self):
4210         type1 = self.operand1.type
4211         type2 = self.operand2.type
4212         if type1.is_ptr:
4213             type1 = type1.base_type
4214         if type2.is_ptr:
4215             type2 = type2.base_type
4216         return (type1.is_cpp_class
4217             or type2.is_cpp_class)
4218     
4219     def coerce_operands_to_pyobjects(self, env):
4220         self.operand1 = self.operand1.coerce_to_pyobject(env)
4221         self.operand2 = self.operand2.coerce_to_pyobject(env)
4222     
4223     def check_const(self):
4224         self.operand1.check_const()
4225         self.operand2.check_const()
4226     
4227     def generate_result_code(self, code):
4228         #print "BinopNode.generate_result_code:", self.operand1, self.operand2 ###
4229         if self.operand1.type.is_pyobject:
4230             function = self.py_operation_function()
4231             if function == "PyNumber_Power":
4232                 extra_args = ", Py_None"
4233             else:
4234                 extra_args = ""
4235             code.putln(
4236                 "%s = %s(%s, %s%s); %s" % (
4237                     self.result(), 
4238                     function, 
4239                     self.operand1.py_result(),
4240                     self.operand2.py_result(),
4241                     extra_args,
4242                     code.error_goto_if_null(self.result(), self.pos)))
4243             code.put_gotref(self.py_result())
4244         else:
4245             if self.is_temp:
4246                 self.generate_c_operation_code(code)
4247     
4248     def type_error(self):
4249         if not (self.operand1.type.is_error
4250                 or self.operand2.type.is_error):
4251             error(self.pos, "Invalid operand types for '%s' (%s; %s)" %
4252                 (self.operator, self.operand1.type, 
4253                     self.operand2.type))
4254         self.type = PyrexTypes.error_type
4255
4256
4257 class NumBinopNode(BinopNode):
4258     #  Binary operation taking numeric arguments.
4259     
4260     infix = True
4261     
4262     def analyse_c_operation(self, env):
4263         type1 = self.operand1.type
4264         type2 = self.operand2.type
4265         self.type = self.compute_c_result_type(type1, type2)
4266         if not self.type:
4267             self.type_error()
4268             return
4269         if self.type.is_complex and not env.directives['c99_complex']:
4270             self.infix = False
4271         if not self.infix:
4272             self.operand1 = self.operand1.coerce_to(self.type, env)
4273             self.operand2 = self.operand2.coerce_to(self.type, env)
4274             
4275     def analyse_cpp_operation(self, env):
4276         type1 = self.operand1.type
4277         type2 = self.operand2.type
4278         if type1.is_ptr:
4279             type1 = type1.base_type
4280         if type2.is_ptr:
4281             type2 = type2.base_type
4282         entry = env.lookup(type1.name)
4283         function = entry.type.scope.lookup("operator%s" % self.operator)
4284         if function is not None:
4285             operands = [self.operand2]
4286         else:
4287             function = env.lookup("operator%s" % self.operator)
4288             operands = [self.operand1, self.operand2]
4289         if not function:
4290             self.type_error()
4291             return
4292         entry = PyrexTypes.best_match(operands, function.all_alternatives(), self.pos)
4293         if entry is None:
4294             self.type = PyrexTypes.error_type
4295             self.result_code = "<error>"
4296             return
4297         if (entry.type.is_ptr):
4298             self.type = entry.type.base_type.return_type
4299         else:
4300             self.type = entry.type.return_type
4301     
4302     def compute_c_result_type(self, type1, type2):
4303         if self.c_types_okay(type1, type2):
4304             return PyrexTypes.widest_numeric_type(type1, type2)
4305         else:
4306             return None
4307     
4308     def c_types_okay(self, type1, type2):
4309         #print "NumBinopNode.c_types_okay:", type1, type2 ###
4310         return (type1.is_numeric  or type1.is_enum) \
4311             and (type2.is_numeric  or type2.is_enum)
4312
4313     def calculate_result_code(self):
4314         if self.infix:
4315             return "(%s %s %s)" % (
4316                 self.operand1.result(), 
4317                 self.operator, 
4318                 self.operand2.result())
4319         else:
4320             func = self.type.binary_op(self.operator)
4321             if func is None:
4322                 error(self.pos, "binary operator %s not supported for %s" % (self.operator, self.type))
4323             return "%s(%s, %s)" % (
4324                 func,
4325                 self.operand1.result(),
4326                 self.operand2.result())
4327     
4328     def py_operation_function(self):
4329         return self.py_functions[self.operator]
4330     
4331
4332     py_functions = {
4333         "|":        "PyNumber_Or",
4334         "^":        "PyNumber_Xor",
4335         "&":        "PyNumber_And",
4336         "<<":        "PyNumber_Lshift",
4337         ">>":        "PyNumber_Rshift",
4338         "+":        "PyNumber_Add",
4339         "-":        "PyNumber_Subtract",
4340         "*":        "PyNumber_Multiply",
4341         "/":        "__Pyx_PyNumber_Divide",
4342         "//":        "PyNumber_FloorDivide",
4343         "%":        "PyNumber_Remainder",
4344         "**":       "PyNumber_Power"
4345     }
4346     
4347
4348 class IntBinopNode(NumBinopNode):
4349     #  Binary operation taking integer arguments.
4350     
4351     def c_types_okay(self, type1, type2):
4352         #print "IntBinopNode.c_types_okay:", type1, type2 ###
4353         return (type1.is_int or type1.is_enum) \
4354             and (type2.is_int or type2.is_enum)
4355
4356     
4357 class AddNode(NumBinopNode):
4358     #  '+' operator.
4359             
4360     def is_py_operation(self):
4361         if self.operand1.type.is_string \
4362             and self.operand2.type.is_string:
4363                 return 1
4364         else:
4365             return NumBinopNode.is_py_operation(self)
4366
4367     def compute_c_result_type(self, type1, type2):
4368         #print "AddNode.compute_c_result_type:", type1, self.operator, type2 ###
4369         if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
4370             return type1
4371         elif (type2.is_ptr or type2.is_array) and (type1.is_int or type1.is_enum):
4372             return type2
4373         else:
4374             return NumBinopNode.compute_c_result_type(
4375                 self, type1, type2)
4376
4377
4378 class SubNode(NumBinopNode):
4379     #  '-' operator.
4380     
4381     def compute_c_result_type(self, type1, type2):
4382         if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
4383             return type1
4384         elif (type1.is_ptr or type1.is_array) and (type2.is_ptr or type2.is_array):
4385             return PyrexTypes.c_int_type
4386         else:
4387             return NumBinopNode.compute_c_result_type(
4388                 self, type1, type2)
4389
4390
4391 class MulNode(NumBinopNode):
4392     #  '*' operator.
4393     
4394     def is_py_operation(self):
4395         type1 = self.operand1.type
4396         type2 = self.operand2.type
4397         if (type1.is_string and type2.is_int) \
4398             or (type2.is_string and type1.is_int):
4399                 return 1
4400         else:
4401             return NumBinopNode.is_py_operation(self)
4402
4403
4404 class DivNode(NumBinopNode):
4405     #  '/' or '//' operator.
4406     
4407     cdivision = None
4408     cdivision_warnings = False
4409     zerodivision_check = None
4410     
4411     def analyse_types(self, env):
4412         NumBinopNode.analyse_types(self, env)
4413         if not self.type.is_pyobject:
4414             self.zerodivision_check = self.cdivision is None and not env.directives['cdivision']
4415             if self.zerodivision_check or env.directives['cdivision_warnings']:
4416                 # Need to check ahead of time to warn or raise zero division error
4417                 self.operand1 = self.operand1.coerce_to_simple(env)
4418                 self.operand2 = self.operand2.coerce_to_simple(env)
4419                 if env.nogil:
4420                     error(self.pos, "Pythonic division not allowed without gil, consider using cython.cdivision(True)")
4421     
4422     def zero_division_message(self):
4423         if self.type.is_int:
4424             return "integer division or modulo by zero"
4425         else:
4426             return "float division"
4427
4428     def generate_evaluation_code(self, code):
4429         if not self.type.is_pyobject and not self.type.is_complex:
4430             if self.cdivision is None:
4431                 self.cdivision = (code.globalstate.directives['cdivision'] 
4432                                     or not self.type.signed
4433                                     or self.type.is_float)
4434             if not self.cdivision:
4435                 code.globalstate.use_utility_code(div_int_utility_code.specialize(self.type))
4436         NumBinopNode.generate_evaluation_code(self, code)
4437         self.generate_div_warning_code(code)
4438     
4439     def generate_div_warning_code(self, code):
4440         if not self.type.is_pyobject:
4441             if self.zerodivision_check:
4442                 if not self.infix:
4443                     zero_test = "%s(%s)" % (self.type.unary_op('zero'), self.operand2.result())
4444                 else:
4445                     zero_test = "%s == 0" % self.operand2.result()
4446                 code.putln("if (unlikely(%s)) {" % zero_test)
4447                 code.putln('PyErr_Format(PyExc_ZeroDivisionError, "%s");' % self.zero_division_message())
4448                 code.putln(code.error_goto(self.pos))
4449                 code.putln("}")
4450                 if self.type.is_int and self.type.signed and self.operator != '%':
4451                     code.globalstate.use_utility_code(division_overflow_test_code)
4452                     code.putln("else if (sizeof(%s) == sizeof(long) && unlikely(%s == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(%s))) {" % (
4453                                     self.type.declaration_code(''), 
4454                                     self.operand2.result(),
4455                                     self.operand1.result()))
4456                     code.putln('PyErr_Format(PyExc_OverflowError, "value too large to perform division");')
4457                     code.putln(code.error_goto(self.pos))
4458                     code.putln("}")
4459             if code.globalstate.directives['cdivision_warnings'] and self.operator != '/':
4460                 code.globalstate.use_utility_code(cdivision_warning_utility_code)
4461                 code.putln("if ((%s < 0) ^ (%s < 0)) {" % (
4462                                 self.operand1.result(),
4463                                 self.operand2.result()))
4464                 code.putln(code.set_error_info(self.pos));
4465                 code.put("if (__Pyx_cdivision_warning()) ")
4466                 code.put_goto(code.error_label)
4467                 code.putln("}")
4468     
4469     def calculate_result_code(self):
4470         if self.type.is_complex:
4471             return NumBinopNode.calculate_result_code(self)
4472         elif self.type.is_float and self.operator == '//':
4473             return "floor(%s / %s)" % (
4474                 self.operand1.result(), 
4475                 self.operand2.result())
4476         elif self.cdivision:
4477             return "(%s / %s)" % (
4478                 self.operand1.result(), 
4479                 self.operand2.result())
4480         else:
4481             return "__Pyx_div_%s(%s, %s)" % (
4482                     self.type.specalization_name(),
4483                     self.operand1.result(), 
4484                     self.operand2.result())
4485
4486
4487 class ModNode(DivNode):
4488     #  '%' operator.
4489
4490     def is_py_operation(self):
4491         return (self.operand1.type.is_string
4492             or self.operand2.type.is_string
4493             or NumBinopNode.is_py_operation(self))
4494
4495     def zero_division_message(self):
4496         if self.type.is_int:
4497             return "integer division or modulo by zero"
4498         else:
4499             return "float divmod()"
4500     
4501     def generate_evaluation_code(self, code):
4502         if not self.type.is_pyobject:
4503             if self.cdivision is None:
4504                 self.cdivision = code.globalstate.directives['cdivision'] or not self.type.signed
4505             if not self.cdivision:
4506                 if self.type.is_int:
4507                     code.globalstate.use_utility_code(mod_int_utility_code.specialize(self.type))
4508                 else:
4509                     code.globalstate.use_utility_code(
4510                         mod_float_utility_code.specialize(self.type, math_h_modifier=self.type.math_h_modifier))
4511         NumBinopNode.generate_evaluation_code(self, code)
4512         self.generate_div_warning_code(code)
4513     
4514     def calculate_result_code(self):
4515         if self.cdivision:
4516             if self.type.is_float:
4517                 return "fmod%s(%s, %s)" % (
4518                     self.type.math_h_modifier,
4519                     self.operand1.result(), 
4520                     self.operand2.result())
4521             else:
4522                 return "(%s %% %s)" % (
4523                     self.operand1.result(), 
4524                     self.operand2.result())
4525         else:
4526             return "__Pyx_mod_%s(%s, %s)" % (
4527                     self.type.specalization_name(),
4528                     self.operand1.result(), 
4529                     self.operand2.result())
4530
4531 class PowNode(NumBinopNode):
4532     #  '**' operator.
4533     
4534     def analyse_c_operation(self, env):
4535         NumBinopNode.analyse_c_operation(self, env)
4536         if self.type.is_complex:
4537             error(self.pos, "complex powers not yet supported")
4538             self.pow_func = "<error>"
4539         elif self.type.is_float:
4540             self.pow_func = "pow"
4541         else:
4542             self.pow_func = "__Pyx_pow_%s" % self.type.declaration_code('').replace(' ', '_')
4543             env.use_utility_code(
4544                     int_pow_utility_code.specialize(func_name=self.pow_func, 
4545                                                 type=self.type.declaration_code('')))
4546
4547     def calculate_result_code(self):
4548         return "%s(%s, %s)" % (
4549             self.pow_func, 
4550             self.operand1.result(), 
4551             self.operand2.result())
4552
4553
4554 # Note: This class is temporary "shut down" into an ineffective mode temp
4555 # allocation mode.
4556 #
4557 # More sophisticated temp reuse was going on before,
4558 # one could have a look at adding this again after /all/ classes
4559 # are converted to the new temp scheme. (The temp juggling cannot work
4560 # otherwise).
4561 class BoolBinopNode(NewTempExprNode):
4562     #  Short-circuiting boolean operation.
4563     #
4564     #  operator     string
4565     #  operand1     ExprNode
4566     #  operand2     ExprNode
4567     
4568     subexprs = ['operand1', 'operand2']
4569
4570     def calculate_constant_result(self):
4571         if self.operator == 'and':
4572             self.constant_result = \
4573                 self.operand1.constant_result and \
4574                 self.operand2.constant_result
4575         else:
4576             self.constant_result = \
4577                 self.operand1.constant_result or \
4578                 self.operand2.constant_result
4579     
4580     def compile_time_value(self, denv):
4581         if self.operator == 'and':
4582             return self.operand1.compile_time_value(denv) \
4583                 and self.operand2.compile_time_value(denv)
4584         else:
4585             return self.operand1.compile_time_value(denv) \
4586                 or self.operand2.compile_time_value(denv)
4587     
4588     def coerce_to_boolean(self, env):
4589         self.operand1 = self.operand1.coerce_to_boolean(env)
4590         self.operand2 = self.operand2.coerce_to_boolean(env)
4591         self.type = PyrexTypes.c_bint_type
4592         return self
4593
4594     def analyse_types(self, env):
4595         self.operand1.analyse_types(env)
4596         self.operand2.analyse_types(env)
4597         if self.operand1.type.is_pyobject or \
4598                 self.operand2.type.is_pyobject:
4599             self.operand1 = self.operand1.coerce_to_pyobject(env)
4600             self.operand2 = self.operand2.coerce_to_pyobject(env)
4601             self.type = py_object_type
4602             self.gil_check(env)
4603         else:
4604             self.operand1 = self.operand1.coerce_to_boolean(env)
4605             self.operand2 = self.operand2.coerce_to_boolean(env)
4606             self.type = PyrexTypes.c_bint_type
4607
4608         # Below disabled for 
4609         
4610         # For what we're about to do, it's vital that
4611         # both operands be temp nodes.
4612 #        self.operand1 = self.operand1.coerce_to_temp(env) #CTT
4613 #        self.operand2 = self.operand2.coerce_to_temp(env)
4614         self.is_temp = 1
4615
4616     gil_message = "Truth-testing Python object"
4617
4618 ##     def allocate_temps(self, env, result_code = None):
4619 ##         #  We don't need both operands at the same time, and
4620 ##         #  one of the operands will also be our result. So we
4621 ##         #  use an allocation strategy here which results in
4622 ##         #  this node and both its operands sharing the same
4623 ##         #  result variable. This allows us to avoid some 
4624 ##         #  assignments and increfs/decrefs that would otherwise
4625 ##         #  be necessary.
4626 ##         self.allocate_temp(env, result_code)
4627 ##         self.operand1.allocate_temps(env, self.result())
4628 ##         self.operand2.allocate_temps(env, self.result())
4629 ##         #  We haven't called release_temp on either operand,
4630 ##         #  because although they are temp nodes, they don't own 
4631 ##         #  their result variable. And because they are temp
4632 ##         #  nodes, any temps in their subnodes will have been
4633 ##         #  released before their allocate_temps returned.
4634 ##         #  Therefore, they contain no temp vars that need to
4635 ##         #  be released.
4636
4637     def check_const(self):
4638         self.operand1.check_const()
4639         self.operand2.check_const()
4640     
4641     def calculate_result_code(self):
4642         return "(%s %s %s)" % (
4643             self.operand1.result(),
4644             self.py_to_c_op[self.operator],
4645             self.operand2.result())
4646     
4647     py_to_c_op = {'and': "&&", 'or': "||"}
4648
4649     def generate_evaluation_code(self, code):
4650         code.mark_pos(self.pos)
4651         self.operand1.generate_evaluation_code(code)
4652         test_result, uses_temp = self.generate_operand1_test(code)
4653         if self.operator == 'and':
4654             sense = ""
4655         else:
4656             sense = "!"
4657         code.putln(
4658             "if (%s%s) {" % (
4659                 sense,
4660                 test_result))
4661         if uses_temp:
4662             code.funcstate.release_temp(test_result)
4663         self.operand1.generate_disposal_code(code)
4664         self.operand2.generate_evaluation_code(code)
4665         self.allocate_temp_result(code)
4666         self.operand2.make_owned_reference(code)
4667         code.putln("%s = %s;" % (self.result(), self.operand2.result()))
4668         self.operand2.generate_post_assignment_code(code)
4669         self.operand2.free_temps(code)
4670         code.putln("} else {")
4671         self.operand1.make_owned_reference(code)
4672         code.putln("%s = %s;" % (self.result(), self.operand1.result()))
4673         self.operand1.generate_post_assignment_code(code)
4674         self.operand1.free_temps(code)
4675         code.putln("}")
4676     
4677     def generate_operand1_test(self, code):
4678         #  Generate code to test the truth of the first operand.
4679         if self.type.is_pyobject:
4680             test_result = code.funcstate.allocate_temp(PyrexTypes.c_bint_type,
4681                                                        manage_ref=False)
4682             code.putln(
4683                 "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
4684                     test_result,
4685                     self.operand1.py_result(),
4686                     code.error_goto_if_neg(test_result, self.pos)))
4687         else:
4688             test_result = self.operand1.result()
4689         return (test_result, self.type.is_pyobject)
4690
4691
4692 class CondExprNode(ExprNode):
4693     #  Short-circuiting conditional expression.
4694     #
4695     #  test        ExprNode
4696     #  true_val    ExprNode
4697     #  false_val   ExprNode
4698     
4699     true_val = None
4700     false_val = None
4701     
4702     subexprs = ['test', 'true_val', 'false_val']
4703
4704     def calculate_constant_result(self):
4705         if self.test.constant_result:
4706             self.constant_result = self.true_val.constant_result
4707         else:
4708             self.constant_result = self.false_val.constant_result
4709
4710     def analyse_types(self, env):
4711         self.test.analyse_types(env)
4712         self.test = self.test.coerce_to_boolean(env)
4713         self.true_val.analyse_types(env)
4714         self.false_val.analyse_types(env)
4715         self.type = self.compute_result_type(self.true_val.type, self.false_val.type)
4716         if self.true_val.type.is_pyobject or self.false_val.type.is_pyobject:
4717             self.true_val = self.true_val.coerce_to(self.type, env)
4718             self.false_val = self.false_val.coerce_to(self.type, env)
4719         self.is_temp = 1
4720         if self.type == PyrexTypes.error_type:
4721             self.type_error()
4722         
4723     def compute_result_type(self, type1, type2):
4724         if type1 == type2:
4725             return type1
4726         elif type1.is_numeric and type2.is_numeric:
4727             return PyrexTypes.widest_numeric_type(type1, type2)
4728         elif type1.is_extension_type and type1.subtype_of_resolved_type(type2):
4729             return type2
4730         elif type2.is_extension_type and type2.subtype_of_resolved_type(type1):
4731             return type1
4732         elif type1.is_pyobject or type2.is_pyobject:
4733             return py_object_type
4734         elif type1.assignable_from(type2):
4735             return type1
4736         elif type2.assignable_from(type1):
4737             return type2
4738         else:
4739             return PyrexTypes.error_type
4740         
4741     def type_error(self):
4742         if not (self.true_val.type.is_error or self.false_val.type.is_error):
4743             error(self.pos, "Incompatable types in conditional expression (%s; %s)" %
4744                 (self.true_val.type, self.false_val.type))
4745         self.type = PyrexTypes.error_type
4746     
4747     def check_const(self):
4748         self.test.check_const()
4749         self.true_val.check_const()
4750         self.false_val.check_const()
4751     
4752     def generate_evaluation_code(self, code):
4753         # Because subexprs may not be evaluated we can use a more optimal
4754         # subexpr allocation strategy than the default, so override evaluation_code.
4755         
4756         code.mark_pos(self.pos)
4757         #self.allocate_temp_result(code) # uncomment this when we switch to new temps
4758         self.test.generate_evaluation_code(code)
4759         code.putln("if (%s) {" % self.test.result() )
4760         self.eval_and_get(code, self.true_val)
4761         code.putln("} else {")
4762         self.eval_and_get(code, self.false_val)
4763         code.putln("}")
4764         self.test.generate_disposal_code(code)
4765         self.test.free_temps(code)
4766
4767     def eval_and_get(self, code, expr):
4768         expr.generate_evaluation_code(code)
4769         expr.make_owned_reference(code)
4770         code.putln("%s = %s;" % (self.result(), expr.result()))
4771         expr.generate_post_assignment_code(code)
4772         expr.free_temps(code)
4773
4774 richcmp_constants = {
4775     "<" : "Py_LT",
4776     "<=": "Py_LE",
4777     "==": "Py_EQ",
4778     "!=": "Py_NE",
4779     "<>": "Py_NE",
4780     ">" : "Py_GT",
4781     ">=": "Py_GE",
4782 }
4783
4784 class CmpNode(object):
4785     #  Mixin class containing code common to PrimaryCmpNodes
4786     #  and CascadedCmpNodes.
4787
4788     def calculate_cascaded_constant_result(self, operand1_result):
4789         func = compile_time_binary_operators[self.operator]
4790         operand2_result = self.operand2.constant_result
4791         result = func(operand1_result, operand2_result)
4792         if result and self.cascade:
4793             result = result and \
4794                 self.cascade.cascaded_compile_time_value(operand2_result)
4795         self.constant_result = result
4796     
4797     def cascaded_compile_time_value(self, operand1, denv):
4798         func = get_compile_time_binop(self)
4799         operand2 = self.operand2.compile_time_value(denv)
4800         try:
4801             result = func(operand1, operand2)
4802         except Exception, e:
4803             self.compile_time_value_error(e)
4804             result = None
4805         if result:
4806             cascade = self.cascade
4807             if cascade:
4808                 # FIXME: I bet this must call cascaded_compile_time_value()
4809                 result = result and cascade.compile_time_value(operand2, denv)
4810         return result
4811
4812     def is_cpp_comparison(self):
4813         type1 = self.operand1.type
4814         type2 = self.operand2.type
4815         if type1.is_ptr:
4816             type1 = type1.base_type
4817         if type2.is_ptr:
4818             type2 = type2.base_type
4819         return type1.is_cpp_class or type2.is_cpp_class
4820
4821     def is_python_comparison(self):
4822         return (self.has_python_operands()
4823             or (self.cascade and self.cascade.is_python_comparison())
4824             or self.operator in ('in', 'not_in'))
4825
4826     def is_python_result(self):
4827         return ((self.has_python_operands() and self.operator not in ('is', 'is_not', 'in', 'not_in'))
4828             or (self.cascade and self.cascade.is_python_result()))
4829
4830     def check_types(self, env, operand1, op, operand2):
4831         if operand1.type.is_complex or operand2.type.is_complex:
4832             if op not in ('==', '!='):
4833                 error(self.pos, "complex types unordered")
4834             common_type = PyrexTypes.widest_numeric_type(operand1.type, operand2.type)
4835             self.operand1 = operand1.coerce_to(common_type, env)
4836             self.operand2 = operand2.coerce_to(common_type, env)
4837         elif not self.types_okay(operand1, op, operand2):
4838             error(self.pos, "Invalid types for '%s' (%s, %s)" %
4839                 (self.operator, operand1.type, operand2.type))
4840     
4841     def types_okay(self, operand1, op, operand2):
4842         type1 = operand1.type
4843         type2 = operand2.type
4844         if type1.is_error or type2.is_error:
4845             return 1
4846         if type1.is_pyobject: # type2 will be, too
4847             return 1
4848         elif type1.is_ptr or type1.is_array:
4849             return type1.is_null_ptr or type2.is_null_ptr \
4850                 or ((type2.is_ptr or type2.is_array)
4851                     and type1.base_type.same_as(type2.base_type))
4852         elif ((type1.is_numeric and type2.is_numeric
4853                     or type1.is_enum and (type1 is type2 or type2.is_int)
4854                     or type1.is_int and type2.is_enum)
4855                 and op not in ('is', 'is_not')):
4856             return 1
4857         else:
4858             return type1.is_cfunction and type1.is_cfunction and type1 == type2
4859
4860     def generate_operation_code(self, code, result_code, 
4861             operand1, op , operand2):
4862         if self.type is PyrexTypes.py_object_type:
4863             coerce_result = "__Pyx_PyBool_FromLong"
4864         else:
4865             coerce_result = ""
4866         if 'not' in op: negation = "!"
4867         else: negation = ""
4868         if op == 'in' or op == 'not_in':
4869             code.putln(
4870                 "%s = %s(%sPySequence_Contains(%s, %s)); %s" % (
4871                     result_code, 
4872                     coerce_result, 
4873                     negation,
4874                     operand2.py_result(), 
4875                     operand1.py_result(), 
4876                     code.error_goto_if_neg(result_code, self.pos)))
4877         elif (operand1.type.is_pyobject
4878             and op not in ('is', 'is_not')):
4879                 code.putln("%s = PyObject_RichCompare(%s, %s, %s); %s" % (
4880                         result_code, 
4881                         operand1.py_result(), 
4882                         operand2.py_result(), 
4883                         richcmp_constants[op],
4884                         code.error_goto_if_null(result_code, self.pos)))
4885                 code.put_gotref(result_code)
4886         elif operand1.type.is_complex and not code.globalstate.directives['c99_complex']:
4887             if op == "!=": negation = "!"
4888             else: negation = ""
4889             code.putln("%s = %s(%s%s(%s, %s));" % (
4890                 result_code, 
4891                 coerce_result,
4892                 negation,
4893                 operand1.type.unary_op('eq'), 
4894                 operand1.result(), 
4895                 operand2.result()))
4896         else:
4897             type1 = operand1.type
4898             type2 = operand2.type
4899             if (type1.is_extension_type or type2.is_extension_type) \
4900                     and not type1.same_as(type2):
4901                 common_type = py_object_type
4902             elif type1.is_numeric:
4903                 common_type = PyrexTypes.widest_numeric_type(type1, type2)
4904             else:
4905                 common_type = type1
4906             code1 = operand1.result_as(common_type)
4907             code2 = operand2.result_as(common_type)
4908             code.putln("%s = %s(%s %s %s);" % (
4909                 result_code, 
4910                 coerce_result, 
4911                 code1, 
4912                 self.c_operator(op), 
4913                 code2))
4914
4915     def c_operator(self, op):
4916         if op == 'is':
4917             return "=="
4918         elif op == 'is_not':
4919             return "!="
4920         else:
4921             return op
4922     
4923
4924 class PrimaryCmpNode(NewTempExprNode, CmpNode):
4925     #  Non-cascaded comparison or first comparison of
4926     #  a cascaded sequence.
4927     #
4928     #  operator      string
4929     #  operand1      ExprNode
4930     #  operand2      ExprNode
4931     #  cascade       CascadedCmpNode
4932     
4933     #  We don't use the subexprs mechanism, because
4934     #  things here are too complicated for it to handle.
4935     #  Instead, we override all the framework methods
4936     #  which use it.
4937     
4938     child_attrs = ['operand1', 'operand2', 'cascade']
4939     
4940     cascade = None
4941
4942     def calculate_constant_result(self):
4943         self.constant_result = self.calculate_cascaded_constant_result(
4944             self.operand1.constant_result)
4945     
4946     def compile_time_value(self, denv):
4947         operand1 = self.operand1.compile_time_value(denv)
4948         return self.cascaded_compile_time_value(operand1, denv)
4949
4950     def analyse_types(self, env):
4951         self.operand1.analyse_types(env)
4952         self.operand2.analyse_types(env)
4953         if self.is_cpp_comparison():
4954             self.analyse_cpp_comparison(env)
4955             return
4956         if self.cascade:
4957             self.cascade.analyse_types(env, self.operand2)
4958         self.is_pycmp = self.is_python_comparison()
4959         if self.is_pycmp:
4960             self.coerce_operands_to_pyobjects(env)
4961         if self.has_int_operands():
4962             self.coerce_chars_to_ints(env)
4963         if self.cascade:
4964             self.operand2 = self.operand2.coerce_to_simple(env)
4965             self.cascade.coerce_cascaded_operands_to_temp(env)
4966         self.check_operand_types(env)
4967         if self.is_python_result():
4968             self.type = PyrexTypes.py_object_type
4969         else:
4970             self.type = PyrexTypes.c_bint_type
4971         cdr = self.cascade
4972         while cdr:
4973             cdr.type = self.type
4974             cdr = cdr.cascade
4975         if self.is_pycmp or self.cascade:
4976             self.is_temp = 1
4977     
4978     def analyse_cpp_comparison(self, env):
4979         type1 = self.operand1.type
4980         type2 = self.operand2.type
4981         if type1.is_ptr:
4982             type1 = type1.base_type
4983         if type2.is_ptr:
4984             type2 = type2.base_type
4985         entry = env.lookup(type1.name)
4986         function = entry.type.scope.lookup("operator%s" % self.operator)
4987         if not function:
4988             error(self.pos, "Invalid types for '%s' (%s, %s)" %
4989                 (self.operator, type1, type2))
4990             return
4991         entry = PyrexTypes.best_match([self.operand1, self.operand2], function.all_alternatives(), self.pos)
4992         if entry is None:
4993             self.type = PyrexTypes.error_type
4994             self.result_code = "<error>"
4995             return
4996         if (entry.type.is_ptr):
4997             self.type = entry.type.base_type.return_type
4998         else:
4999             self.type = entry.type.return_type
5000     
5001     def check_operand_types(self, env):
5002         self.check_types(env, 
5003             self.operand1, self.operator, self.operand2)
5004         if self.cascade:
5005             self.cascade.check_operand_types(env, self.operand2)
5006     
5007     def has_python_operands(self):
5008         return (self.operand1.type.is_pyobject
5009             or self.operand2.type.is_pyobject)
5010             
5011     def coerce_operands_to_pyobjects(self, env):
5012         self.operand1 = self.operand1.coerce_to_pyobject(env)
5013         self.operand2 = self.operand2.coerce_to_pyobject(env)
5014         if self.cascade:
5015             self.cascade.coerce_operands_to_pyobjects(env)
5016         
5017     def has_int_operands(self):
5018         return (self.operand1.type.is_int or self.operand2.type.is_int) \
5019            or (self.cascade and self.cascade.has_int_operands())
5020     
5021     def coerce_chars_to_ints(self, env):
5022         # coerce literal single-char strings to c chars
5023         if self.operand1.type.is_string and isinstance(self.operand1, StringNode):
5024             self.operand1 = self.operand1.coerce_to(PyrexTypes.c_uchar_type, env)
5025         if self.operand2.type.is_string and isinstance(self.operand2, StringNode):
5026             self.operand2 = self.operand2.coerce_to(PyrexTypes.c_uchar_type, env)
5027         if self.cascade:
5028             self.cascade.coerce_chars_to_ints(env)
5029     
5030     def allocate_subexpr_temps(self, env):
5031         self.operand1.allocate_temps(env)
5032         self.operand2.allocate_temps(env)
5033         if self.cascade:
5034             self.cascade.allocate_subexpr_temps(env)
5035     
5036     def release_subexpr_temps(self, env):
5037         self.operand1.release_temp(env)
5038         self.operand2.release_temp(env)
5039         if self.cascade:
5040             self.cascade.release_subexpr_temps(env)
5041     
5042     def check_const(self):
5043         self.operand1.check_const()
5044         self.operand2.check_const()
5045         if self.cascade:
5046             self.not_const()
5047
5048     def calculate_result_code(self):
5049         if self.operand1.type.is_complex:
5050             if self.operator == "!=":
5051                 negation = "!"
5052             else:
5053                 negation = ""
5054             return "(%s%s(%s, %s))" % (
5055                 negation,
5056                 self.operand1.type.binary_op('=='), 
5057                 self.operand1.result(), 
5058                 self.operand2.result())
5059         else:
5060             return "(%s %s %s)" % (
5061                 self.operand1.result(),
5062                 self.c_operator(self.operator),
5063                 self.operand2.result())
5064
5065     def generate_evaluation_code(self, code):
5066         self.operand1.generate_evaluation_code(code)
5067         self.operand2.generate_evaluation_code(code)
5068         if self.is_temp:
5069             self.allocate_temp_result(code)
5070             self.generate_operation_code(code, self.result(), 
5071                 self.operand1, self.operator, self.operand2)
5072             if self.cascade:
5073                 self.cascade.generate_evaluation_code(code,
5074                     self.result(), self.operand2)
5075             self.operand1.generate_disposal_code(code)
5076             self.operand1.free_temps(code)
5077             self.operand2.generate_disposal_code(code)
5078             self.operand2.free_temps(code)
5079
5080     def generate_subexpr_disposal_code(self, code):
5081         #  If this is called, it is a non-cascaded cmp,
5082         #  so only need to dispose of the two main operands.
5083         self.operand1.generate_disposal_code(code)
5084         self.operand2.generate_disposal_code(code)
5085         
5086     def free_subexpr_temps(self, code):
5087         #  If this is called, it is a non-cascaded cmp,
5088         #  so only need to dispose of the two main operands.
5089         self.operand1.free_temps(code)
5090         self.operand2.free_temps(code)
5091         
5092     def annotate(self, code):
5093         self.operand1.annotate(code)
5094         self.operand2.annotate(code)
5095         if self.cascade:
5096             self.cascade.annotate(code)
5097     
5098
5099 class CascadedCmpNode(Node, CmpNode):
5100     #  A CascadedCmpNode is not a complete expression node. It 
5101     #  hangs off the side of another comparison node, shares 
5102     #  its left operand with that node, and shares its result 
5103     #  with the PrimaryCmpNode at the head of the chain.
5104     #
5105     #  operator      string
5106     #  operand2      ExprNode
5107     #  cascade       CascadedCmpNode
5108
5109     child_attrs = ['operand2', 'cascade']
5110
5111     cascade = None
5112     constant_result = constant_value_not_set # FIXME: where to calculate this?
5113
5114     def analyse_types(self, env, operand1):
5115         self.operand2.analyse_types(env)
5116         if self.cascade:
5117             self.cascade.analyse_types(env, self.operand2)
5118     
5119     def check_operand_types(self, env, operand1):
5120         self.check_types(env, 
5121             operand1, self.operator, self.operand2)
5122         if self.cascade:
5123             self.cascade.check_operand_types(env, self.operand2)
5124     
5125     def has_python_operands(self):
5126         return self.operand2.type.is_pyobject
5127         
5128     def coerce_operands_to_pyobjects(self, env):
5129         self.operand2 = self.operand2.coerce_to_pyobject(env)
5130         if self.cascade:
5131             self.cascade.coerce_operands_to_pyobjects(env)
5132
5133     def has_int_operands(self):
5134         return self.operand2.type.is_int
5135         
5136     def coerce_chars_to_ints(self, env):
5137         if self.operand2.type.is_string and isinstance(self.operand2, StringNode):
5138             self.operand2 = self.operand2.coerce_to(PyrexTypes.c_uchar_type, env)
5139
5140     def coerce_cascaded_operands_to_temp(self, env):
5141         if self.cascade:
5142             #self.operand2 = self.operand2.coerce_to_temp(env) #CTT
5143             self.operand2 = self.operand2.coerce_to_simple(env)
5144             self.cascade.coerce_cascaded_operands_to_temp(env)
5145     
5146     def allocate_subexpr_temps(self, env):
5147         self.operand2.allocate_temps(env)
5148         if self.cascade:
5149             self.cascade.allocate_subexpr_temps(env)
5150     
5151     def release_subexpr_temps(self, env):
5152         self.operand2.release_temp(env)
5153         if self.cascade:
5154             self.cascade.release_subexpr_temps(env)
5155     
5156     def generate_evaluation_code(self, code, result, operand1):
5157         if self.type.is_pyobject:
5158             code.putln("if (__Pyx_PyObject_IsTrue(%s)) {" % result)
5159             code.put_decref(result, self.type)
5160         else:
5161             code.putln("if (%s) {" % result)
5162         self.operand2.generate_evaluation_code(code)
5163         self.generate_operation_code(code, result, 
5164             operand1, self.operator, self.operand2)
5165         if self.cascade:
5166             self.cascade.generate_evaluation_code(
5167                 code, result, self.operand2)
5168         # Cascaded cmp result is always temp
5169         self.operand2.generate_disposal_code(code)
5170         self.operand2.free_temps(code)
5171         code.putln("}")
5172
5173     def annotate(self, code):
5174         self.operand2.annotate(code)
5175         if self.cascade:
5176             self.cascade.annotate(code)
5177
5178
5179 binop_node_classes = {
5180     "or":       BoolBinopNode,
5181     "and":      BoolBinopNode,
5182     "|":        IntBinopNode,
5183     "^":        IntBinopNode,
5184     "&":        IntBinopNode,
5185     "<<":       IntBinopNode,
5186     ">>":       IntBinopNode,
5187     "+":        AddNode,
5188     "-":        SubNode,
5189     "*":        MulNode,
5190     "/":        DivNode,
5191     "//":       DivNode,
5192     "%":        ModNode,
5193     "**":       PowNode
5194 }
5195
5196 def binop_node(pos, operator, operand1, operand2):
5197     # Construct binop node of appropriate class for 
5198     # given operator.
5199     return binop_node_classes[operator](pos, 
5200         operator = operator, 
5201         operand1 = operand1, 
5202         operand2 = operand2)
5203
5204 #-------------------------------------------------------------------
5205 #
5206 #  Coercion nodes
5207 #
5208 #  Coercion nodes are special in that they are created during
5209 #  the analyse_types phase of parse tree processing.
5210 #  Their __init__ methods consequently incorporate some aspects
5211 #  of that phase.
5212 #
5213 #-------------------------------------------------------------------
5214
5215 class CoercionNode(NewTempExprNode):
5216     #  Abstract base class for coercion nodes.
5217     #
5218     #  arg       ExprNode       node being coerced
5219     
5220     subexprs = ['arg']
5221     
5222     def __init__(self, arg):
5223         self.pos = arg.pos
5224         self.arg = arg
5225         if debug_coercion:
5226             print("%s Coercing %s" % (self, self.arg))
5227
5228     def calculate_constant_result(self):
5229         # constant folding can break type coercion, so this is disabled
5230         pass
5231             
5232     def annotate(self, code):
5233         self.arg.annotate(code)
5234         if self.arg.type != self.type:
5235             file, line, col = self.pos
5236             code.annotate((file, line, col-1), AnnotationItem(style='coerce', tag='coerce', text='[%s] to [%s]' % (self.arg.type, self.type)))
5237
5238
5239 class CastNode(CoercionNode):
5240     #  Wrap a node in a C type cast.
5241     
5242     def __init__(self, arg, new_type):
5243         CoercionNode.__init__(self, arg)
5244         self.type = new_type
5245     
5246     def calculate_result_code(self):
5247         return self.arg.result_as(self.type)
5248
5249     def generate_result_code(self, code):
5250         self.arg.generate_result_code(code)
5251
5252
5253 class PyTypeTestNode(CoercionNode):
5254     #  This node is used to check that a generic Python
5255     #  object is an instance of a particular extension type.
5256     #  This node borrows the result of its argument node.
5257
5258     def __init__(self, arg, dst_type, env):
5259         #  The arg is know to be a Python object, and
5260         #  the dst_type is known to be an extension type.
5261         assert dst_type.is_extension_type or dst_type.is_builtin_type, "PyTypeTest on non extension type"
5262         CoercionNode.__init__(self, arg)
5263         self.type = dst_type
5264         self.gil_check(env)
5265         self.result_ctype = arg.ctype()
5266
5267     gil_message = "Python type test"
5268     
5269     def analyse_types(self, env):
5270         pass
5271     
5272     def result_in_temp(self):
5273         return self.arg.result_in_temp()
5274     
5275     def is_ephemeral(self):
5276         return self.arg.is_ephemeral()
5277     
5278     def calculate_result_code(self):
5279         return self.arg.result()
5280     
5281     def generate_result_code(self, code):
5282         if self.type.typeobj_is_available():
5283             if not self.type.is_builtin_type:
5284                 code.globalstate.use_utility_code(type_test_utility_code)
5285             code.putln(
5286                 "if (!(%s)) %s" % (
5287                     self.type.type_test_code(self.arg.py_result()),
5288                     code.error_goto(self.pos)))
5289         else:
5290             error(self.pos, "Cannot test type of extern C class "
5291                 "without type object name specification")
5292                 
5293     def generate_post_assignment_code(self, code):
5294         self.arg.generate_post_assignment_code(code)
5295
5296     def free_temps(self, code):
5297         self.arg.free_temps(code)
5298                 
5299
5300 class CoerceToPyTypeNode(CoercionNode):
5301     #  This node is used to convert a C data type
5302     #  to a Python object.
5303
5304     def __init__(self, arg, env):
5305         CoercionNode.__init__(self, arg)
5306         self.type = py_object_type
5307         self.gil_check(env)
5308         self.is_temp = 1
5309         if not arg.type.create_to_py_utility_code(env):
5310             error(arg.pos,
5311                 "Cannot convert '%s' to Python object" % arg.type)
5312         
5313     gil_message = "Converting to Python object"
5314     
5315     def coerce_to_boolean(self, env):
5316         return self.arg.coerce_to_boolean(env).coerce_to_temp(env)
5317     
5318     def coerce_to_integer(self, env):
5319         # If not already some C integer type, coerce to longint.
5320         if self.arg.type.is_int:
5321             return self.arg
5322         else:
5323             return self.arg.coerce_to(PyrexTypes.c_long_type, env)
5324
5325     def analyse_types(self, env):
5326         # The arg is always already analysed
5327         pass
5328
5329     def generate_result_code(self, code):
5330         function = self.arg.type.to_py_function
5331         code.putln('%s = %s(%s); %s' % (
5332             self.result(), 
5333             function, 
5334             self.arg.result(), 
5335             code.error_goto_if_null(self.result(), self.pos)))
5336         code.put_gotref(self.py_result())
5337
5338
5339 class CoerceFromPyTypeNode(CoercionNode):
5340     #  This node is used to convert a Python object
5341     #  to a C data type.
5342
5343     def __init__(self, result_type, arg, env):
5344         CoercionNode.__init__(self, arg)
5345         self.type = result_type
5346         self.is_temp = 1
5347         if not result_type.create_from_py_utility_code(env):
5348             error(arg.pos,
5349                 "Cannot convert Python object to '%s'" % result_type)
5350         if self.type.is_string and self.arg.is_ephemeral():
5351             error(arg.pos,
5352                 "Obtaining char * from temporary Python value")
5353     
5354     def analyse_types(self, env):
5355         # The arg is always already analysed
5356         pass
5357
5358     def generate_result_code(self, code):
5359         function = self.type.from_py_function
5360         operand = self.arg.py_result()
5361         rhs = "%s(%s)" % (function, operand)
5362         if self.type.is_enum:
5363             rhs = typecast(self.type, c_long_type, rhs)
5364         code.putln('%s = %s; %s' % (
5365             self.result(), 
5366             rhs,
5367             code.error_goto_if(self.type.error_condition(self.result()), self.pos)))
5368         if self.type.is_pyobject:
5369             code.put_gotref(self.py_result())
5370
5371
5372 class CoerceToBooleanNode(CoercionNode):
5373     #  This node is used when a result needs to be used
5374     #  in a boolean context.
5375     
5376     def __init__(self, arg, env):
5377         CoercionNode.__init__(self, arg)
5378         self.type = PyrexTypes.c_bint_type
5379         if arg.type.is_pyobject:
5380             if env.nogil:
5381                 self.gil_error()
5382             self.is_temp = 1
5383
5384     gil_message = "Truth-testing Python object"
5385     
5386     def check_const(self):
5387         if self.is_temp:
5388             self.not_const()
5389         self.arg.check_const()
5390     
5391     def calculate_result_code(self):
5392         return "(%s != 0)" % self.arg.result()
5393
5394     def generate_result_code(self, code):
5395         if self.arg.type.is_pyobject:
5396             code.putln(
5397                 "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
5398                     self.result(), 
5399                     self.arg.py_result(), 
5400                     code.error_goto_if_neg(self.result(), self.pos)))
5401
5402 class CoerceToComplexNode(CoercionNode):
5403
5404     def __init__(self, arg, dst_type, env):
5405         if arg.type.is_complex:
5406             arg = arg.coerce_to_simple(env)
5407         self.type = dst_type
5408         CoercionNode.__init__(self, arg)
5409         dst_type.create_declaration_utility_code(env)
5410
5411     def calculate_result_code(self):
5412         if self.arg.type.is_complex:
5413             real_part = "__Pyx_REAL_PART(%s)" % self.arg.result()
5414             imag_part = "__Pyx_IMAG_PART(%s)" % self.arg.result()
5415         else:
5416             real_part = self.arg.result()
5417             imag_part = "0"
5418         return "%s(%s, %s)" % (
5419                 self.type.from_parts,
5420                 real_part,
5421                 imag_part)
5422     
5423     def generate_result_code(self, code):
5424         pass
5425
5426 class CoerceToTempNode(CoercionNode):
5427     #  This node is used to force the result of another node
5428     #  to be stored in a temporary. It is only used if the
5429     #  argument node's result is not already in a temporary.
5430
5431     def __init__(self, arg, env):
5432         CoercionNode.__init__(self, arg)
5433         self.type = self.arg.type
5434         self.is_temp = 1
5435         if self.type.is_pyobject:
5436             self.gil_check(env)
5437             self.result_ctype = py_object_type
5438
5439     gil_message = "Creating temporary Python reference"
5440
5441     def analyse_types(self, env):
5442         # The arg is always already analysed
5443         pass
5444         
5445     def coerce_to_boolean(self, env):
5446         self.arg = self.arg.coerce_to_boolean(env)
5447         self.type = self.arg.type
5448         self.result_ctype = self.type
5449         return self
5450
5451     def generate_result_code(self, code):
5452         #self.arg.generate_evaluation_code(code) # Already done
5453         # by generic generate_subexpr_evaluation_code!
5454         code.putln("%s = %s;" % (
5455             self.result(), self.arg.result_as(self.ctype())))
5456         if self.type.is_pyobject:
5457             code.put_incref(self.result(), self.ctype())
5458
5459
5460 class CloneNode(CoercionNode):
5461     #  This node is employed when the result of another node needs
5462     #  to be used multiple times. The argument node's result must
5463     #  be in a temporary. This node "borrows" the result from the
5464     #  argument node, and does not generate any evaluation or
5465     #  disposal code for it. The original owner of the argument 
5466     #  node is responsible for doing those things.
5467     
5468     subexprs = [] # Arg is not considered a subexpr
5469     
5470     def __init__(self, arg):
5471         CoercionNode.__init__(self, arg)
5472         if hasattr(arg, 'type'):
5473             self.type = arg.type
5474             self.result_ctype = arg.result_ctype
5475         if hasattr(arg, 'entry'):
5476             self.entry = arg.entry
5477     
5478     def result(self):
5479         return self.arg.result()
5480         
5481     def analyse_types(self, env):
5482         self.type = self.arg.type
5483         self.result_ctype = self.arg.result_ctype
5484         self.is_temp = 1
5485         if hasattr(self.arg, 'entry'):
5486             self.entry = self.arg.entry
5487     
5488     def generate_evaluation_code(self, code):
5489         pass
5490
5491     def generate_result_code(self, code):
5492         pass
5493         
5494     def generate_disposal_code(self, code):
5495         pass
5496                 
5497     def allocate_temps(self, env):
5498         pass
5499         
5500     def release_temp(self, env):
5501         pass
5502
5503     def free_temps(self, code):
5504         pass
5505
5506
5507 #------------------------------------------------------------------------------------
5508 #
5509 #  Runtime support code
5510 #
5511 #------------------------------------------------------------------------------------
5512
5513 get_name_interned_utility_code = UtilityCode(
5514 proto = """
5515 static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
5516 """,
5517 impl = """
5518 static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
5519     PyObject *result;
5520     result = PyObject_GetAttr(dict, name);
5521     if (!result)
5522         PyErr_SetObject(PyExc_NameError, name);
5523     return result;
5524 }
5525 """)
5526
5527 #------------------------------------------------------------------------------------
5528
5529 import_utility_code = UtilityCode(
5530 proto = """
5531 static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); /*proto*/
5532 """,
5533 impl = """
5534 static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list) {
5535     PyObject *__import__ = 0;
5536     PyObject *empty_list = 0;
5537     PyObject *module = 0;
5538     PyObject *global_dict = 0;
5539     PyObject *empty_dict = 0;
5540     PyObject *list;
5541     __import__ = __Pyx_GetAttrString(%(BUILTINS)s, "__import__");
5542     if (!__import__)
5543         goto bad;
5544     if (from_list)
5545         list = from_list;
5546     else {
5547         empty_list = PyList_New(0);
5548         if (!empty_list)
5549             goto bad;
5550         list = empty_list;
5551     }
5552     global_dict = PyModule_GetDict(%(GLOBALS)s);
5553     if (!global_dict)
5554         goto bad;
5555     empty_dict = PyDict_New();
5556     if (!empty_dict)
5557         goto bad;
5558     module = PyObject_CallFunctionObjArgs(__import__,
5559         name, global_dict, empty_dict, list, NULL);
5560 bad:
5561     Py_XDECREF(empty_list);
5562     Py_XDECREF(__import__);
5563     Py_XDECREF(empty_dict);
5564     return module;
5565 }
5566 """ % {
5567     "BUILTINS": Naming.builtins_cname,
5568     "GLOBALS":  Naming.module_cname,
5569 })
5570
5571 #------------------------------------------------------------------------------------
5572
5573 get_exception_utility_code = UtilityCode(
5574 proto = """
5575 static PyObject *__Pyx_GetExcValue(void); /*proto*/
5576 """,
5577 impl = """
5578 static PyObject *__Pyx_GetExcValue(void) {
5579     PyObject *type = 0, *value = 0, *tb = 0;
5580     PyObject *tmp_type, *tmp_value, *tmp_tb;
5581     PyObject *result = 0;
5582     PyThreadState *tstate = PyThreadState_Get();
5583     PyErr_Fetch(&type, &value, &tb);
5584     PyErr_NormalizeException(&type, &value, &tb);
5585     if (PyErr_Occurred())
5586         goto bad;
5587     if (!value) {
5588         value = Py_None;
5589         Py_INCREF(value);
5590     }
5591     tmp_type = tstate->exc_type;
5592     tmp_value = tstate->exc_value;
5593     tmp_tb = tstate->exc_traceback;
5594     tstate->exc_type = type;
5595     tstate->exc_value = value;
5596     tstate->exc_traceback = tb;
5597     /* Make sure tstate is in a consistent state when we XDECREF
5598     these objects (XDECREF may run arbitrary code). */
5599     Py_XDECREF(tmp_type);
5600     Py_XDECREF(tmp_value);
5601     Py_XDECREF(tmp_tb);
5602     result = value;
5603     Py_XINCREF(result);
5604     type = 0;
5605     value = 0;
5606     tb = 0;
5607 bad:
5608     Py_XDECREF(type);
5609     Py_XDECREF(value);
5610     Py_XDECREF(tb);
5611     return result;
5612 }
5613 """)
5614
5615 #------------------------------------------------------------------------------------
5616
5617 type_test_utility_code = UtilityCode(
5618 proto = """
5619 static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/
5620 """,
5621 impl = """
5622 static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
5623     if (!type) {
5624         PyErr_Format(PyExc_SystemError, "Missing type object");
5625         return 0;
5626     }
5627     if (obj == Py_None || PyObject_TypeCheck(obj, type))
5628         return 1;
5629     PyErr_Format(PyExc_TypeError, "Cannot convert %s to %s",
5630         Py_TYPE(obj)->tp_name, type->tp_name);
5631     return 0;
5632 }
5633 """)
5634
5635 #------------------------------------------------------------------------------------
5636
5637 create_class_utility_code = UtilityCode(
5638 proto = """
5639 static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name, const char *modname); /*proto*/
5640 """,
5641 impl = """
5642 static PyObject *__Pyx_CreateClass(
5643     PyObject *bases, PyObject *dict, PyObject *name, const char *modname)
5644 {
5645     PyObject *py_modname;
5646     PyObject *result = 0;
5647
5648     #if PY_MAJOR_VERSION < 3
5649     py_modname = PyString_FromString(modname);
5650     #else
5651     py_modname = PyUnicode_FromString(modname);
5652     #endif
5653     if (!py_modname)
5654         goto bad;
5655     if (PyDict_SetItemString(dict, "__module__", py_modname) < 0)
5656         goto bad;
5657     #if PY_MAJOR_VERSION < 3
5658     result = PyClass_New(bases, dict, name);
5659     #else
5660     result = PyObject_CallFunctionObjArgs((PyObject *)&PyType_Type, name, bases, dict, NULL);
5661     #endif
5662 bad:
5663     Py_XDECREF(py_modname);
5664     return result;
5665 }
5666 """)
5667
5668 #------------------------------------------------------------------------------------
5669
5670 cpp_exception_utility_code = UtilityCode(
5671 proto = """
5672 #ifndef __Pyx_CppExn2PyErr
5673 static void __Pyx_CppExn2PyErr() {
5674   try {
5675     if (PyErr_Occurred())
5676       ; // let the latest Python exn pass through and ignore the current one
5677     else
5678       throw;
5679   } catch (const std::out_of_range& exn) {
5680     // catch out_of_range explicitly so the proper Python exn may be raised
5681     PyErr_SetString(PyExc_IndexError, exn.what());
5682   } catch (const std::exception& exn) {
5683     PyErr_SetString(PyExc_RuntimeError, exn.what());
5684   }
5685   catch (...)
5686   {
5687     PyErr_SetString(PyExc_RuntimeError, "Unknown exception");
5688   }
5689 }
5690 #endif
5691 """,
5692 impl = ""
5693 )
5694
5695 #------------------------------------------------------------------------------------
5696
5697 append_utility_code = UtilityCode(
5698 proto = """
5699 static INLINE PyObject* __Pyx_PyObject_Append(PyObject* L, PyObject* x) {
5700     if (likely(PyList_CheckExact(L))) {
5701         if (PyList_Append(L, x) < 0) return NULL;
5702         Py_INCREF(Py_None);
5703         return Py_None; /* this is just to have an accurate signature */
5704     }
5705     else {
5706         PyObject *r, *m;
5707         m = __Pyx_GetAttrString(L, "append");
5708         if (!m) return NULL;
5709         r = PyObject_CallFunctionObjArgs(m, x, NULL);
5710         Py_DECREF(m);
5711         return r;
5712     }
5713 }
5714 """,
5715 impl = ""
5716 )
5717
5718 #------------------------------------------------------------------------------------
5719
5720 # If the is_unsigned flag is set, we need to do some extra work to make 
5721 # sure the index doesn't become negative. 
5722
5723 getitem_int_utility_code = UtilityCode(
5724 proto = """
5725
5726 static INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
5727     PyObject *r;
5728     if (!j) return NULL;
5729     r = PyObject_GetItem(o, j);
5730     Py_DECREF(j);
5731     return r;
5732 }
5733
5734 """ + ''.join([
5735 """
5736 #define __Pyx_GetItemInt_%(type)s(o, i, size, to_py_func) ((size <= sizeof(Py_ssize_t)) ? \\
5737                                                     __Pyx_GetItemInt_%(type)s_Fast(o, i, size <= sizeof(long)) : \\
5738                                                     __Pyx_GetItemInt_Generic(o, to_py_func(i)))
5739
5740 static INLINE PyObject *__Pyx_GetItemInt_%(type)s_Fast(PyObject *o, Py_ssize_t i, int fits_long) {
5741     if (likely(o != Py_None)) {
5742         if (likely((0 <= i) & (i < Py%(type)s_GET_SIZE(o)))) {
5743             PyObject *r = Py%(type)s_GET_ITEM(o, i);
5744             Py_INCREF(r);
5745             return r;
5746         }
5747         else if ((-Py%(type)s_GET_SIZE(o) <= i) & (i < 0)) {
5748             PyObject *r = Py%(type)s_GET_ITEM(o, Py%(type)s_GET_SIZE(o) + i);
5749             Py_INCREF(r);
5750             return r;
5751         }
5752     }
5753     return __Pyx_GetItemInt_Generic(o, fits_long ? PyInt_FromLong(i) : PyLong_FromLongLong(i));
5754 }
5755 """ % {'type' : type_name} for type_name in ('List', 'Tuple')
5756 ]) + """
5757
5758 #define __Pyx_GetItemInt(o, i, size, to_py_func) ((size <= sizeof(Py_ssize_t)) ? \\
5759                                                     __Pyx_GetItemInt_Fast(o, i, size <= sizeof(long)) : \\
5760                                                     __Pyx_GetItemInt_Generic(o, to_py_func(i)))
5761
5762 static INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int fits_long) {
5763     PyObject *r;
5764     if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) {
5765         r = PyList_GET_ITEM(o, i);
5766         Py_INCREF(r);
5767     }
5768     else if (PyTuple_CheckExact(o) && ((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
5769         r = PyTuple_GET_ITEM(o, i);
5770         Py_INCREF(r);
5771     }
5772     else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_item && (likely(i >= 0))) {
5773         r = PySequence_GetItem(o, i);
5774     }
5775     else {
5776         r = __Pyx_GetItemInt_Generic(o, fits_long ? PyInt_FromLong(i) : PyLong_FromLongLong(i));
5777     }
5778     return r;
5779 }
5780 """,
5781 impl = """
5782 """)
5783
5784
5785
5786 #------------------------------------------------------------------------------------
5787
5788 setitem_int_utility_code = UtilityCode(
5789 proto = """
5790 #define __Pyx_SetItemInt(o, i, v, size, to_py_func) ((size <= sizeof(Py_ssize_t)) ? \\
5791                                                     __Pyx_SetItemInt_Fast(o, i, v, size <= sizeof(long)) : \\
5792                                                     __Pyx_SetItemInt_Generic(o, to_py_func(i), v))
5793
5794 static INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) {
5795     int r;
5796     if (!j) return -1;
5797     r = PyObject_SetItem(o, j, v);
5798     Py_DECREF(j);
5799     return r;
5800 }
5801
5802 static INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v, int fits_long) {
5803     if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) {
5804         Py_INCREF(v);
5805         Py_DECREF(PyList_GET_ITEM(o, i));
5806         PyList_SET_ITEM(o, i, v);
5807         return 1;
5808     }
5809     else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && (likely(i >= 0)))
5810         return PySequence_SetItem(o, i, v);
5811     else {
5812         PyObject *j = fits_long ? PyInt_FromLong(i) : PyLong_FromLongLong(i);
5813         return __Pyx_SetItemInt_Generic(o, j, v);
5814     }
5815 }
5816 """,
5817 impl = """
5818 """)
5819
5820 #------------------------------------------------------------------------------------
5821
5822 delitem_int_utility_code = UtilityCode(
5823 proto = """
5824 #define __Pyx_DelItemInt(o, i, size, to_py_func) ((size <= sizeof(Py_ssize_t)) ? \\
5825                                                     __Pyx_DelItemInt_Fast(o, i, size <= sizeof(long)) : \\
5826                                                     __Pyx_DelItem_Generic(o, to_py_func(i)))
5827
5828 static INLINE int __Pyx_DelItem_Generic(PyObject *o, PyObject *j) {
5829     int r;
5830     if (!j) return -1;
5831     r = PyObject_DelItem(o, j);
5832     Py_DECREF(j);
5833     return r;
5834 }
5835
5836 static INLINE int __Pyx_DelItemInt_Fast(PyObject *o, Py_ssize_t i, int fits_long) {
5837     if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && likely(i >= 0))
5838         return PySequence_DelItem(o, i);
5839     else {
5840         PyObject *j = fits_long ? PyInt_FromLong(i) : PyLong_FromLongLong(i);
5841         return __Pyx_DelItem_Generic(o, j);
5842     }
5843 }
5844 """,
5845 impl = """
5846 """)
5847
5848 #------------------------------------------------------------------------------------
5849
5850 raise_noneattr_error_utility_code = UtilityCode(
5851 proto = """
5852 static INLINE void __Pyx_RaiseNoneAttributeError(const char* attrname);
5853 """,
5854 impl = '''
5855 static INLINE void __Pyx_RaiseNoneAttributeError(const char* attrname) {
5856     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", attrname);
5857 }
5858 ''')
5859
5860 raise_noneindex_error_utility_code = UtilityCode(
5861 proto = """
5862 static INLINE void __Pyx_RaiseNoneIndexingError(void);
5863 """,
5864 impl = '''
5865 static INLINE void __Pyx_RaiseNoneIndexingError(void) {
5866     PyErr_SetString(PyExc_TypeError, "'NoneType' object is unsubscriptable");
5867 }
5868 ''')
5869
5870 raise_none_iter_error_utility_code = UtilityCode(
5871 proto = """
5872 static INLINE void __Pyx_RaiseNoneNotIterableError(void);
5873 """,
5874 impl = '''
5875 static INLINE void __Pyx_RaiseNoneNotIterableError(void) {
5876     PyErr_SetString(PyExc_TypeError, "'NoneType' object is iterable");
5877 }
5878 ''')
5879
5880 raise_too_many_values_to_unpack = UtilityCode(
5881 proto = """
5882 static INLINE void __Pyx_RaiseTooManyValuesError(void);
5883 """,
5884 impl = '''
5885 static INLINE void __Pyx_RaiseTooManyValuesError(void) {
5886     PyErr_SetString(PyExc_ValueError, "too many values to unpack");
5887 }
5888 ''')
5889
5890 raise_need_more_values_to_unpack = UtilityCode(
5891 proto = """
5892 static INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
5893 """,
5894 impl = '''
5895 static INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
5896     PyErr_Format(PyExc_ValueError,
5897         #if PY_VERSION_HEX < 0x02050000
5898                  "need more than %d value%s to unpack", (int)index,
5899         #else
5900                  "need more than %zd value%s to unpack", index,
5901         #endif
5902                  (index == 1) ? "" : "s");
5903 }
5904 ''')
5905
5906 #------------------------------------------------------------------------------------
5907
5908 tuple_unpacking_error_code = UtilityCode(
5909 proto = """
5910 static void __Pyx_UnpackTupleError(PyObject *, Py_ssize_t index); /*proto*/
5911 """, 
5912 impl = """
5913 static void __Pyx_UnpackTupleError(PyObject *t, Py_ssize_t index) {
5914     if (t == Py_None) {
5915       __Pyx_RaiseNoneNotIterableError();
5916     } else if (PyTuple_GET_SIZE(t) < index) {
5917       __Pyx_RaiseNeedMoreValuesError(PyTuple_GET_SIZE(t));
5918     } else {
5919       __Pyx_RaiseTooManyValuesError();
5920     }
5921 }
5922 """, 
5923 requires = [raise_none_iter_error_utility_code,
5924             raise_need_more_values_to_unpack,
5925             raise_too_many_values_to_unpack]
5926 )
5927
5928 unpacking_utility_code = UtilityCode(
5929 proto = """
5930 static PyObject *__Pyx_UnpackItem(PyObject *, Py_ssize_t index); /*proto*/
5931 static int __Pyx_EndUnpack(PyObject *); /*proto*/
5932 """,
5933 impl = """
5934 static PyObject *__Pyx_UnpackItem(PyObject *iter, Py_ssize_t index) {
5935     PyObject *item;
5936     if (!(item = PyIter_Next(iter))) {
5937         if (!PyErr_Occurred()) {
5938             __Pyx_RaiseNeedMoreValuesError(index);
5939         }
5940     }
5941     return item;
5942 }
5943
5944 static int __Pyx_EndUnpack(PyObject *iter) {
5945     PyObject *item;
5946     if ((item = PyIter_Next(iter))) {
5947         Py_DECREF(item);
5948         __Pyx_RaiseTooManyValuesError();
5949         return -1;
5950     }
5951     else if (!PyErr_Occurred())
5952         return 0;
5953     else
5954         return -1;
5955 }
5956 """,
5957 requires = [raise_need_more_values_to_unpack,
5958             raise_too_many_values_to_unpack]
5959 )
5960
5961
5962 #------------------------------------------------------------------------------------
5963
5964 int_pow_utility_code = UtilityCode(
5965 proto="""
5966 static INLINE %(type)s %(func_name)s(%(type)s, %(type)s); /* proto */
5967 """,
5968 impl="""
5969 static INLINE %(type)s %(func_name)s(%(type)s b, %(type)s e) {
5970     %(type)s t = b;
5971     switch (e) {
5972         case 3:
5973             t *= b;
5974         case 2:
5975             t *= b;
5976         case 1:
5977             return t;
5978         case 0:
5979             return 1;
5980     }
5981     if (unlikely(e<0)) return 0;
5982     t = 1;
5983     while (likely(e)) {
5984         t *= (b * (e&1)) | ((~e)&1);    /* 1 or b */
5985         b *= b;
5986         e >>= 1;
5987     }
5988     return t;
5989 }
5990 """)
5991
5992 # ------------------------------ Division ------------------------------------
5993
5994 div_int_utility_code = UtilityCode(
5995 proto="""
5996 static INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s, %(type)s); /* proto */
5997 """,
5998 impl="""
5999 static INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s a, %(type)s b) {
6000     %(type)s q = a / b;
6001     %(type)s r = a - q*b;
6002     q -= ((r != 0) & ((r ^ b) < 0));
6003     return q;
6004 }
6005 """)
6006
6007 mod_int_utility_code = UtilityCode(
6008 proto="""
6009 static INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
6010 """,
6011 impl="""
6012 static INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
6013     %(type)s r = a %% b;
6014     r += ((r != 0) & ((r ^ b) < 0)) * b;
6015     return r;
6016 }
6017 """)
6018
6019 mod_float_utility_code = UtilityCode(
6020 proto="""
6021 static INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
6022 """,
6023 impl="""
6024 static INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
6025     %(type)s r = fmod%(math_h_modifier)s(a, b);
6026     r += ((r != 0) & ((r < 0) ^ (b < 0))) * b;
6027     return r;
6028 }
6029 """)
6030
6031 cdivision_warning_utility_code = UtilityCode(
6032 proto="""
6033 static int __Pyx_cdivision_warning(void); /* proto */
6034 """,
6035 impl="""
6036 static int __Pyx_cdivision_warning(void) {
6037     return PyErr_WarnExplicit(PyExc_RuntimeWarning, 
6038                               "division with oppositely signed operands, C and Python semantics differ",
6039                               %(FILENAME)s, 
6040                               %(LINENO)s,
6041                               __Pyx_MODULE_NAME,
6042                               NULL);
6043 }
6044 """ % {
6045     'FILENAME': Naming.filename_cname,
6046     'LINENO':  Naming.lineno_cname,
6047 })
6048
6049 # from intobject.c
6050 division_overflow_test_code = UtilityCode(
6051 proto="""
6052 #define UNARY_NEG_WOULD_OVERFLOW(x)     \
6053         (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x)))
6054 """)