Use method to get result code, deferred to code generation time.
authorRobert Bradshaw <robertwb@math.washington.edu>
Tue, 23 Sep 2008 20:48:06 +0000 (13:48 -0700)
committerRobert Bradshaw <robertwb@math.washington.edu>
Tue, 23 Sep 2008 20:48:06 +0000 (13:48 -0700)
Cython/Compiler/ExprNodes.py
Cython/Compiler/Nodes.py

index 690a397c838105eff87ea7b5c92d6bc193e546bb..cd9a5a46151688c19d29ab713fbf9a38de7c282e 100644 (file)
@@ -103,11 +103,6 @@ class ExprNode(Node):
     #        - Call release_temp on sub-nodes and release any other
     #          temps used during assignment.
     #
-    #      calculate_result_code
-    #        - Called during the Allocate Temps phase. Should return a
-    #          C code fragment evaluating to the result. This is only
-    #          called when the result is not a temporary.
-    #
     #      target_code
     #        Called by the default implementation of allocate_target_temps.
     #        Should return a C lvalue for assigning to the node. The default
@@ -140,13 +135,18 @@ class ExprNode(Node):
     #          on all sub-expressions.
     #
     #        A default implementation of generate_evaluation_code
-    #        is provided which uses the following abstract method:
+    #        is provided which uses the following abstract methods:
     #
     #          generate_result_code
     #            - Generate any C statements necessary to calculate
     #              the result of this node from the results of its
     #              sub-expressions.
     #
+    #          calculate_result_code
+    #            - Should return a C code fragment evaluating to the 
+    #              result. This is only called when the result is not 
+    #              a temporary.
+    #
     #      generate_assignment_code
     #        Called on the LHS of an assignment.
     #        - Call generate_evaluation_code for sub-expressions.
@@ -204,10 +204,16 @@ class ExprNode(Node):
                         nodes.extend(item)
             self.saved_subexpr_nodes = nodes
         return self.saved_subexpr_nodes
+        
+    def result(self):
+               if self.is_temp:
+                       return self.result_code
+               else:
+                       return self.calculate_result_code()
     
     def result_as(self, type = None):
         #  Return the result code cast to the specified C type.
-        return typecast(type, self.ctype(), self.result_code)
+        return typecast(type, self.ctype(), self.result())
     
     def py_result(self):
         #  Return the result code cast to PyObject *.
@@ -381,8 +387,6 @@ class ExprNode(Node):
                 self.result_code = None
             if debug_temp_alloc:
                 print("%s Allocated result %s" % (self, self.result_code))
-        else:
-            self.result_code = self.calculate_result_code()
     
     def target_code(self):
         #  Return code fragment for use as LHS of a C assignment.
@@ -418,7 +422,7 @@ class ExprNode(Node):
         #  If result is a pyobject, make sure we own
         #  a reference to it.
         if self.type.is_pyobject and not self.result_in_temp():
-            code.put_incref(self.result_code, self.ctype())
+            code.put_incref(self.result(), self.ctype())
     
     def generate_evaluation_code(self, code):
         code.mark_pos(self.pos)
@@ -442,7 +446,7 @@ class ExprNode(Node):
         # temporary Python reference.
         if self.is_temp:
             if self.type.is_pyobject:
-                code.put_decref_clear(self.result_code, self.ctype())
+                code.put_decref_clear(self.result(), self.ctype())
         else:
             self.generate_subexpr_disposal_code(code)
     
@@ -458,7 +462,7 @@ class ExprNode(Node):
         # the result if it is a Python object.
         if self.is_temp:
             if self.type.is_pyobject:
-                code.putln("%s = 0;" % self.result_code)
+                code.putln("%s = 0;" % self.result())
         else:
             self.generate_subexpr_disposal_code(code)
     
@@ -795,9 +799,9 @@ class LongNode(AtomicExprNode):
     def generate_evaluation_code(self, code):
         code.putln(
             '%s = PyLong_FromString("%s", 0, 0); %s' % (
-                self.result_code,
+                self.result(),
                 self.value,
-                code.error_goto_if_null(self.result_code, self.pos)))
+                code.error_goto_if_null(self.result(), self.pos)))
 
 
 class ImagNode(AtomicExprNode):
@@ -818,9 +822,9 @@ class ImagNode(AtomicExprNode):
     def generate_evaluation_code(self, code):
         code.putln(
             "%s = PyComplex_FromDoubles(0.0, %s); %s" % (
-                self.result_code,
+                self.result(),
                 self.value,
-                code.error_goto_if_null(self.result_code, self.pos)))
+                code.error_goto_if_null(self.result(), self.pos)))
 
 
 class NameNode(AtomicExprNode):
@@ -1017,10 +1021,10 @@ class NameNode(AtomicExprNode):
                 namespace = entry.scope.namespace_cname
             code.putln(
                 '%s = __Pyx_GetName(%s, %s); %s' % (
-                self.result_code,
+                self.result(),
                 namespace, 
                 self.interned_cname,
-                code.error_goto_if_null(self.result_code, self.pos)))
+                code.error_goto_if_null(self.result(), self.pos)))
         elif entry.is_local and False:
             # control flow not good enough yet
             assigned = entry.scope.control_flow.get_state((entry.name, 'initalized'), self.pos)
@@ -1083,12 +1087,12 @@ class NameNode(AtomicExprNode):
                     if entry.is_local and not Options.init_local_none:
                         initalized = entry.scope.control_flow.get_state((entry.name, 'initalized'), self.pos)
                         if initalized is True:
-                            code.put_decref(self.result_code, self.ctype())
+                            code.put_decref(self.result(), self.ctype())
                         elif initalized is None:
-                            code.put_xdecref(self.result_code, self.ctype())
+                            code.put_xdecref(self.result(), self.ctype())
                     else:
-                        code.put_decref(self.result_code, self.ctype())
-            code.putln('%s = %s;' % (self.result_code, rhs.result_as(self.ctype())))
+                        code.put_decref(self.result(), self.ctype())
+            code.putln('%s = %s;' % (self.result(), rhs.result_as(self.ctype())))
             if debug_disposal_code:
                 print("NameNode.generate_assignment_code:")
                 print("...generating post-assignment code for %s" % rhs)
@@ -1101,7 +1105,7 @@ class NameNode(AtomicExprNode):
         code.putln('%s = %s;' % (rhstmp, rhs.result_as(self.ctype())))
 
         import Buffer
-        Buffer.put_assign_to_buffer(self.result_code, rhstmp, buffer_aux, self.entry.type,
+        Buffer.put_assign_to_buffer(self.result(), rhstmp, buffer_aux, self.entry.type,
                                     is_initialized=not self.skip_assignment_decref,
                                     pos=self.pos, code=code)
         code.putln("%s = 0;" % rhstmp)
@@ -1145,9 +1149,9 @@ class BackquoteNode(ExprNode):
     def generate_result_code(self, code):
         code.putln(
             "%s = PyObject_Repr(%s); %s" % (
-                self.result_code,
+                self.result(),
                 self.arg.py_result(),
-                code.error_goto_if_null(self.result_code, self.pos)))
+                code.error_goto_if_null(self.result(), self.pos)))
 
 
 class ImportNode(ExprNode):
@@ -1179,10 +1183,10 @@ class ImportNode(ExprNode):
             name_list_code = "0"
         code.putln(
             "%s = __Pyx_Import(%s, %s); %s" % (
-                self.result_code,
+                self.result(),
                 self.module_name.py_result(),
                 name_list_code,
-                code.error_goto_if_null(self.result_code, self.pos)))
+                code.error_goto_if_null(self.result(), self.pos)))
 
 
 class IteratorNode(ExprNode):
@@ -1206,7 +1210,7 @@ class IteratorNode(ExprNode):
     gil_message = "Iterating over Python object"
 
     def release_temp(self, env):
-        env.release_temp(self.result_code)
+        env.release_temp(self.result())
         self.counter.release_temp(env)
     
     def generate_result_code(self, code):
@@ -1216,16 +1220,16 @@ class IteratorNode(ExprNode):
                 self.sequence.py_result()))
         code.putln(
             "%s = 0; %s = %s; Py_INCREF(%s);" % (
-                self.counter.result_code,
-                self.result_code,
+                self.counter.result(),
+                self.result(),
                 self.sequence.py_result(),
-                self.result_code))
+                self.result()))
         code.putln("} else {")
         code.putln("%s = -1; %s = PyObject_GetIter(%s); %s" % (
-                self.counter.result_code,
-                self.result_code,
+                self.counter.result(),
+                self.result(),
                 self.sequence.py_result(),
-                code.error_goto_if_null(self.result_code, self.pos)))
+                code.error_goto_if_null(self.result(), self.pos)))
         code.putln("}")
 
 
@@ -1249,26 +1253,26 @@ class NextNode(AtomicExprNode):
                 "if (likely(Py%s_CheckExact(%s))) {" % (py_type, self.iterator.py_result()))
             code.putln(
                 "if (%s >= Py%s_GET_SIZE(%s)) break;" % (
-                    self.iterator.counter.result_code,
+                    self.iterator.counter.result(),
                     py_type,
                     self.iterator.py_result()))
             code.putln(
                 "%s = Py%s_GET_ITEM(%s, %s); Py_INCREF(%s); %s++;" % (
-                    self.result_code,
+                    self.result(),
                     py_type,
                     self.iterator.py_result(),
-                    self.iterator.counter.result_code,
-                    self.result_code,
-                    self.iterator.counter.result_code))
+                    self.iterator.counter.result(),
+                    self.result(),
+                    self.iterator.counter.result()))
             code.put("} else ")
         code.putln("{")
         code.putln(
             "%s = PyIter_Next(%s);" % (
-                self.result_code,
+                self.result(),
                 self.iterator.py_result()))
         code.putln(
             "if (!%s) {" %
-                self.result_code)
+                self.result())
         code.putln(code.error_goto_if_PyErr(self.pos))
         code.putln("break;")
         code.putln("}")
@@ -1465,7 +1469,7 @@ class IndexNode(ExprNode):
             return "<not used>"
         else:
             return "(%s[%s])" % (
-                self.base.result_code, self.index.result_code)
+                self.base.result(), self.index.result())
             
     def index_unsigned_parameter(self):
         if self.index.type.is_int:
@@ -1496,33 +1500,33 @@ class IndexNode(ExprNode):
         if self.is_buffer_access:
             ptrcode = self.buffer_lookup_code(code)
             code.putln("%s = *%s;" % (
-                self.result_code,
+                self.result(),
                 self.buffer_type.buffer_ptr_type.cast_code(ptrcode)))
             # Must incref the value we pulled out.
             if self.buffer_type.dtype.is_pyobject:
-                code.putln("Py_INCREF((PyObject*)%s);" % self.result_code)
+                code.putln("Py_INCREF((PyObject*)%s);" % self.result())
         elif self.type.is_pyobject:
             if self.index.type.is_int:
                 function = "__Pyx_GetItemInt"
-                index_code = self.index.result_code
+                index_code = self.index.result()
             else:
                 function = "PyObject_GetItem"
                 index_code = self.index.py_result()
                 sign_code = ""
             code.putln(
                 "%s = %s(%s, %s%s); if (!%s) %s" % (
-                    self.result_code,
+                    self.result(),
                     function,
                     self.base.py_result(),
                     index_code,
                     self.index_unsigned_parameter(),
-                    self.result_code,
+                    self.result(),
                     code.error_goto(self.pos)))
 
     def generate_setitem_code(self, value_code, code):
         if self.index.type.is_int:
             function = "__Pyx_SetItemInt"
-            index_code = self.index.result_code
+            index_code = self.index.result()
         else:
             function = "PyObject_SetItem"
             index_code = self.index.py_result()
@@ -1545,7 +1549,7 @@ class IndexNode(ExprNode):
             if rhs.is_temp:
                 rhs_code = code.funcstate.allocate_temp(rhs.type)
             else:
-                rhs_code = rhs.result_code
+                rhs_code = rhs.result()
             code.putln("%s = %s;" % (ptr, ptrexpr))
             code.putln("Py_DECREF(*%s); Py_INCREF(%s);" % (
                 ptr, rhs_code
@@ -1556,7 +1560,7 @@ class IndexNode(ExprNode):
             code.funcstate.release_temp(ptr)
         else: 
             # Simple case
-            code.putln("*%s %s= %s;" % (ptrexpr, op, rhs.result_code))
+            code.putln("*%s %s= %s;" % (ptrexpr, op, rhs.result()))
 
     def generate_assignment_code(self, rhs, code):
         self.generate_subexpr_evaluation_code(code)
@@ -1567,7 +1571,7 @@ class IndexNode(ExprNode):
         else:
             code.putln(
                 "%s = %s;" % (
-                    self.result_code, rhs.result_code))
+                    self.result(), rhs.result()))
         self.generate_subexpr_disposal_code(code)
         rhs.generate_disposal_code(code)
     
@@ -1576,7 +1580,7 @@ class IndexNode(ExprNode):
         #if self.type.is_pyobject:
         if self.index.type.is_int:
             function = "PySequence_DelItem"
-            index_code = self.index.result_code
+            index_code = self.index.result()
         else:
             function = "PyObject_DelItem"
             index_code = self.index.py_result()
@@ -1592,7 +1596,7 @@ class IndexNode(ExprNode):
         # Assign indices to temps
         index_temps = [code.funcstate.allocate_temp(i.type) for i in self.indices]
         for temp, index in zip(index_temps, self.indices):
-            code.putln("%s = %s;" % (temp, index.result_code))
+            code.putln("%s = %s;" % (temp, index.result()))
         # Generate buffer access code using these temps
         import Buffer
         # The above could happen because child_attrs is wrong somewhere so that
@@ -1645,11 +1649,11 @@ class SliceIndexNode(ExprNode):
     def generate_result_code(self, code):
         code.putln(
             "%s = PySequence_GetSlice(%s, %s, %s); %s" % (
-                self.result_code,
+                self.result(),
                 self.base.py_result(),
                 self.start_code(),
                 self.stop_code(),
-                code.error_goto_if_null(self.result_code, self.pos)))
+                code.error_goto_if_null(self.result(), self.pos)))
     
     def generate_assignment_code(self, rhs, code):
         self.generate_subexpr_evaluation_code(code)
@@ -1658,7 +1662,7 @@ class SliceIndexNode(ExprNode):
                 self.base.py_result(),
                 self.start_code(),
                 self.stop_code(),
-                rhs.result_code))
+                rhs.result()))
         self.generate_subexpr_disposal_code(code)
         rhs.generate_disposal_code(code)
 
@@ -1673,18 +1677,18 @@ class SliceIndexNode(ExprNode):
     
     def start_code(self):
         if self.start:
-            return self.start.result_code
+            return self.start.result()
         else:
             return "0"
     
     def stop_code(self):
         if self.stop:
-            return self.stop.result_code
+            return self.stop.result()
         else:
             return "PY_SSIZE_T_MAX"
     
     def calculate_result_code(self):
-        # self.result_code is not used, but this method must exist
+        # self.result() is not used, but this method must exist
         return "<unused>"
     
 
@@ -1722,11 +1726,11 @@ class SliceNode(ExprNode):
     def generate_result_code(self, code):
         code.putln(
             "%s = PySlice_New(%s, %s, %s); %s" % (
-                self.result_code,
+                self.result(),
                 self.start.py_result(), 
                 self.stop.py_result(), 
                 self.step.py_result(),
-                code.error_goto_if_null(self.result_code, self.pos)))
+                code.error_goto_if_null(self.result(), self.pos)))
 
 
 class CallNode(ExprNode):
@@ -1897,8 +1901,8 @@ class SimpleCallNode(CallNode):
             arg_list_code.append(optional_args)
             
         for actual_arg in self.args[len(formal_args):]:
-            arg_list_code.append(actual_arg.result_code)
-        result = "%s(%s)" % (self.function.result_code,
+            arg_list_code.append(actual_arg.result())
+        result = "%s(%s)" % (self.function.result(),
             join(arg_list_code, ", "))
 #        if self.wrapper_call or \
 #                self.function.entry.is_unbound_cmethod and self.function.entry.type.is_overridable:
@@ -1911,10 +1915,10 @@ class SimpleCallNode(CallNode):
             arg_code = self.arg_tuple.py_result()
             code.putln(
                 "%s = PyObject_Call(%s, %s, NULL); %s" % (
-                    self.result_code,
+                    self.result(),
                     self.function.py_result(),
                     arg_code,
-                    code.error_goto_if_null(self.result_code, self.pos)))
+                    code.error_goto_if_null(self.result(), self.pos)))
         elif func_type.is_cfunction:
             if self.has_optional_args:
                 actual_nargs = len(self.args)
@@ -1931,18 +1935,18 @@ class SimpleCallNode(CallNode):
                             actual_arg.result_as(formal_arg.type)))
             exc_checks = []
             if self.type.is_pyobject:
-                exc_checks.append("!%s" % self.result_code)
+                exc_checks.append("!%s" % self.result())
             else:
                 exc_val = func_type.exception_value
                 exc_check = func_type.exception_check
                 if exc_val is not None:
-                    exc_checks.append("%s == %s" % (self.result_code, exc_val))
+                    exc_checks.append("%s == %s" % (self.result(), exc_val))
                 if exc_check:
                     exc_checks.append("PyErr_Occurred()")
             if self.is_temp or exc_checks:
                 rhs = self.c_call_code()
-                if self.result_code:
-                    lhs = "%s = " % self.result_code
+                if self.result():
+                    lhs = "%s = " % self.result()
                     if self.is_temp and self.type.is_pyobject:
                         #return_type = self.type # func_type.return_type
                         #print "SimpleCallNode.generate_result_code: casting", rhs, \
@@ -2033,9 +2037,9 @@ class GeneralCallNode(CallNode):
                 keyword_code)
         code.putln(
             "%s = %s; %s" % (
-                self.result_code,
+                self.result(),
                 call_code,
-                code.error_goto_if_null(self.result_code, self.pos)))
+                code.error_goto_if_null(self.result(), self.pos)))
 
 
 class AsTupleNode(ExprNode):
@@ -2065,9 +2069,9 @@ class AsTupleNode(ExprNode):
     def generate_result_code(self, code):
         code.putln(
             "%s = PySequence_Tuple(%s); %s" % (
-                self.result_code,
+                self.result(),
                 self.arg.py_result(),
-                code.error_goto_if_null(self.result_code, self.pos)))
+                code.error_goto_if_null(self.result(), self.pos)))
     
 
 class AttributeNode(ExprNode):
@@ -2090,7 +2094,6 @@ class AttributeNode(ExprNode):
     subexprs = ['obj']
     
     type = PyrexTypes.error_type
-    result = "<error>"
     entry = None
     is_called = 0
     needs_none_check = True
@@ -2299,7 +2302,7 @@ class AttributeNode(ExprNode):
     
     def calculate_result_code(self):
         #print "AttributeNode.calculate_result_code:", self.member ###
-        #print "...obj node =", self.obj, "code", self.obj.result_code ###
+        #print "...obj node =", self.obj, "code", self.obj.result() ###
         #print "...obj type", self.obj.type, "ctype", self.obj.ctype() ###
         obj = self.obj
         obj_code = obj.result_as(obj.type)
@@ -2318,10 +2321,10 @@ class AttributeNode(ExprNode):
         if self.is_py_attr:
             code.putln(
                 '%s = PyObject_GetAttr(%s, %s); %s' % (
-                    self.result_code,
+                    self.result(),
                     self.obj.py_result(),
                     self.interned_attr_cname,
-                    code.error_goto_if_null(self.result_code, self.pos)))
+                    code.error_goto_if_null(self.result(), self.pos)))
         else:
             # result_code contains what is needed, but we may need to insert
             # a check and raise an exception
@@ -2345,7 +2348,7 @@ class AttributeNode(ExprNode):
                   and code.globalstate.directives['nonecheck']):
                 self.put_nonecheck(code)
 
-            select_code = self.result_code
+            select_code = self.result()
             if self.type.is_pyobject:
                 rhs.make_owned_reference(code)
                 code.put_decref(select_code, self.ctype())
@@ -2353,7 +2356,7 @@ class AttributeNode(ExprNode):
                 "%s = %s;" % (
                     select_code,
                     rhs.result_as(self.ctype())))
-                    #rhs.result_code))
+                    #rhs.result()))
             rhs.generate_post_assignment_code(code)
         self.obj.generate_disposal_code(code)
     
@@ -2463,9 +2466,9 @@ class SequenceNode(ExprNode):
             item = self.unpacked_items[i]
             code.putln(
                 "%s = PyTuple_GET_ITEM(tuple, %s);" % (
-                    item.result_code,
+                    item.result(),
                     i))
-            code.put_incref(item.result_code, item.ctype())
+            code.put_incref(item.result(), item.ctype())
             value_node = self.coerced_unpacked_items[i]
             value_node.generate_evaluation_code(code)
             self.args[i].generate_assignment_code(value_node, code)
@@ -2476,9 +2479,9 @@ class SequenceNode(ExprNode):
 
         code.putln(
             "%s = PyObject_GetIter(%s); %s" % (
-                self.iterator.result_code,
+                self.iterator.result(),
                 rhs.py_result(),
-                code.error_goto_if_null(self.iterator.result_code, self.pos)))
+                code.error_goto_if_null(self.iterator.result(), self.pos)))
         rhs.generate_disposal_code(code)
         for i in range(len(self.args)):
             item = self.unpacked_items[i]
@@ -2486,9 +2489,9 @@ class SequenceNode(ExprNode):
                 self.iterator.py_result(), i)
             code.putln(
                 "%s = %s; %s" % (
-                    item.result_code,
+                    item.result(),
                     typecast(item.ctype(), py_object_type, unpack_code),
-                    code.error_goto_if_null(item.result_code, self.pos)))
+                    code.error_goto_if_null(item.result(), self.pos)))
             value_node = self.coerced_unpacked_items[i]
             value_node.generate_evaluation_code(code)
             self.args[i].generate_assignment_code(value_node, code)
@@ -2544,16 +2547,16 @@ class TupleNode(SequenceNode):
             return
         code.putln(
             "%s = PyTuple_New(%s); %s" % (
-                self.result_code,
+                self.result(),
                 len(self.args),
-                code.error_goto_if_null(self.result_code, self.pos)))
+                code.error_goto_if_null(self.result(), self.pos)))
         for i in range(len(self.args)):
             arg = self.args[i]
             if not arg.result_in_temp():
-                code.put_incref(arg.result_code, arg.ctype())
+                code.put_incref(arg.result(), arg.ctype())
             code.putln(
                 "PyTuple_SET_ITEM(%s, %s, %s);" % (
-                    self.result_code,
+                    self.result(),
                     i,
                     arg.py_result()))
     
@@ -2579,16 +2582,16 @@ class ListNode(SequenceNode):
 
     def generate_operation_code(self, code):
         code.putln("%s = PyList_New(%s); %s" %
-            (self.result_code,
+            (self.result(),
             len(self.args),
-            code.error_goto_if_null(self.result_code, self.pos)))
+            code.error_goto_if_null(self.result(), self.pos)))
         for i in range(len(self.args)):
             arg = self.args[i]
             #if not arg.is_temp:
             if not arg.result_in_temp():
-                code.put_incref(arg.result_code, arg.ctype())
+                code.put_incref(arg.result(), arg.ctype())
             code.putln("PyList_SET_ITEM(%s, %s, %s);" %
-                (self.result_code,
+                (self.result(),
                 i,
                 arg.py_result()))
                 
@@ -2621,9 +2624,9 @@ class ListComprehensionNode(SequenceNode):
         
     def generate_operation_code(self, code):
         code.putln("%s = PyList_New(%s); %s" %
-            (self.result_code,
+            (self.result(),
             0,
-            code.error_goto_if_null(self.result_code, self.pos)))
+            code.error_goto_if_null(self.result(), self.pos)))
         self.loop.generate_execution_code(code)
         
     def annotate(self, code):
@@ -2645,10 +2648,10 @@ class ListComprehensionAppendNode(ExprNode):
     
     def generate_result_code(self, code):
         code.putln("%s = PyList_Append(%s, (PyObject*)%s); %s" %
-            (self.result_code,
-            self.target.result_code,
-            self.expr.result_code,
-            code.error_goto_if(self.result_code, self.pos)))
+            (self.result(),
+            self.target.result(),
+            self.expr.result(),
+            code.error_goto_if(self.result(), self.pos)))
 
 
 class DictNode(ExprNode):
@@ -2690,13 +2693,13 @@ class DictNode(ExprNode):
         #  pairs are evaluated and used one at a time.
         code.putln(
             "%s = PyDict_New(); %s" % (
-                self.result_code,
-                code.error_goto_if_null(self.result_code, self.pos)))
+                self.result(),
+                code.error_goto_if_null(self.result(), self.pos)))
         for item in self.key_value_pairs:
             item.generate_evaluation_code(code)
             code.put_error_if_neg(self.pos, 
                 "PyDict_SetItem(%s, %s, %s)" % (
-                    self.result_code,
+                    self.result(),
                     item.key.py_result(),
                     item.value.py_result()))
             item.generate_disposal_code(code)
@@ -2763,12 +2766,12 @@ class ClassNode(ExprNode):
                     self.doc.py_result()))
         code.putln(
             '%s = __Pyx_CreateClass(%s, %s, %s, "%s"); %s' % (
-                self.result_code,
+                self.result(),
                 self.bases.py_result(),
                 self.dict.py_result(),
                 self.cname,
                 self.module_name,
-                code.error_goto_if_null(self.result_code, self.pos)))
+                code.error_goto_if_null(self.result(), self.pos)))
 
 
 class UnboundMethodNode(ExprNode):
@@ -2792,10 +2795,10 @@ class UnboundMethodNode(ExprNode):
     def generate_result_code(self, code):
         code.putln(
             "%s = PyMethod_New(%s, 0, %s); %s" % (
-                self.result_code,
+                self.result(),
                 self.function.py_result(),
                 self.class_cname,
-                code.error_goto_if_null(self.result_code, self.pos)))
+                code.error_goto_if_null(self.result(), self.pos)))
 
 
 class PyCFunctionNode(AtomicExprNode):
@@ -2815,9 +2818,9 @@ class PyCFunctionNode(AtomicExprNode):
     def generate_result_code(self, code):
         code.putln(
             "%s = PyCFunction_New(&%s, 0); %s" % (
-                self.result_code,
+                self.result(),
                 self.pymethdef_cname,
-                code.error_goto_if_null(self.result_code, self.pos)))
+                code.error_goto_if_null(self.result(), self.pos)))
 
 #-------------------------------------------------------------------
 #
@@ -2888,10 +2891,10 @@ class UnopNode(ExprNode):
         function = self.py_operation_function()
         code.putln(
             "%s = %s(%s); %s" % (
-                self.result_code
+                self.result()
                 function, 
                 self.operand.py_result(),
-                code.error_goto_if_null(self.result_code, self.pos)))
+                code.error_goto_if_null(self.result(), self.pos)))
         
     def type_error(self):
         if not self.operand.type.is_error:
@@ -2920,7 +2923,7 @@ class NotNode(ExprNode):
         self.type = PyrexTypes.c_bint_type
     
     def calculate_result_code(self):
-        return "(!%s)" % self.operand.result_code
+        return "(!%s)" % self.operand.result()
     
     def generate_result_code(self, code):
         pass
@@ -2938,7 +2941,7 @@ class UnaryPlusNode(UnopNode):
         return "PyNumber_Positive"
     
     def calculate_result_code(self):
-        return self.operand.result_code
+        return self.operand.result()
 
 
 class UnaryMinusNode(UnopNode):
@@ -2956,7 +2959,7 @@ class UnaryMinusNode(UnopNode):
         return "PyNumber_Negative"
     
     def calculate_result_code(self):
-        return "(-%s)" % self.operand.result_code
+        return "(-%s)" % self.operand.result()
 
 
 class TildeNode(UnopNode):
@@ -2972,7 +2975,7 @@ class TildeNode(UnopNode):
         return "PyNumber_Invert"
     
     def calculate_result_code(self):
-        return "(~%s)" % self.operand.result_code
+        return "(~%s)" % self.operand.result()
 
 
 class AmpersandNode(ExprNode):
@@ -3002,7 +3005,7 @@ class AmpersandNode(ExprNode):
         self.result_code = "<error>"
     
     def calculate_result_code(self):
-        return "(&%s)" % self.operand.result_code
+        return "(&%s)" % self.operand.result()
 
     def generate_result_code(self, code):
         pass
@@ -3073,8 +3076,7 @@ class TypecastNode(ExprNode):
     
     def calculate_result_code(self):
         opnd = self.operand
-        result_code = self.type.cast_code(opnd.result_code)
-        return result_code
+        return self.type.cast_code(opnd.result())
     
     def result_as(self, type):
         if self.type.is_pyobject and not self.is_temp:
@@ -3087,9 +3089,9 @@ class TypecastNode(ExprNode):
         if self.is_temp:
             code.putln(
                 "%s = (PyObject *)%s;" % (
-                    self.result_code,
-                    self.operand.result_code))
-            code.put_incref(self.result_code, self.ctype())
+                    self.result(),
+                    self.operand.result()))
+            code.put_incref(self.result(), self.ctype())
 
 
 class SizeofNode(ExprNode):
@@ -3158,7 +3160,7 @@ class SizeofVarNode(SizeofNode):
         self.type = PyrexTypes.c_int_type
     
     def calculate_result_code(self):
-        return "(sizeof(%s))" % self.operand.result_code
+        return "(sizeof(%s))" % self.operand.result()
     
     def generate_result_code(self, code):
         pass
@@ -3266,12 +3268,12 @@ class BinopNode(ExprNode):
                 extra_args = ""
             code.putln(
                 "%s = %s(%s, %s%s); %s" % (
-                    self.result_code
+                    self.result()
                     function, 
                     self.operand1.py_result(),
                     self.operand2.py_result(),
                     extra_args,
-                    code.error_goto_if_null(self.result_code, self.pos)))
+                    code.error_goto_if_null(self.result(), self.pos)))
         else:
             if self.is_temp:
                 self.generate_c_operation_code(code)
@@ -3312,9 +3314,9 @@ class NumBinopNode(BinopNode):
 
     def calculate_result_code(self):
         return "(%s %s %s)" % (
-            self.operand1.result_code
+            self.operand1.result()
             self.operator, 
-            self.operand2.result_code)
+            self.operand2.result())
     
     def py_operation_function(self):
         return self.py_functions[self.operator]
@@ -3396,9 +3398,9 @@ class FloorDivNode(NumBinopNode):
     
     def calculate_result_code(self):
         return "(%s %s %s)" % (
-            self.operand1.result_code
+            self.operand1.result()
             "/",  # c division is by default floor-div 
-            self.operand2.result_code)
+            self.operand2.result())
 
 
 class ModNode(IntBinopNode):
@@ -3438,7 +3440,7 @@ class PowNode(NumBinopNode):
 
     def calculate_result_code(self):
         return "pow(%s, %s)" % (
-            self.operand1.result_code, self.operand2.result_code)
+            self.operand1.result(), self.operand2.result())
 
 
 class BoolBinopNode(ExprNode):
@@ -3492,11 +3494,11 @@ class BoolBinopNode(ExprNode):
         #  assignments and increfs/decrefs that would otherwise
         #  be necessary.
         self.allocate_temp(env, result_code)
-        self.operand1.allocate_temps(env, self.result_code)
+        self.operand1.allocate_temps(env, self.result())
         if self.temp_bool:
             self.temp_bool.allocate_temp(env)
             self.temp_bool.release_temp(env)
-        self.operand2.allocate_temps(env, self.result_code)
+        self.operand2.allocate_temps(env, self.result())
         #  We haven't called release_temp on either operand,
         #  because although they are temp nodes, they don't own 
         #  their result variable. And because they are temp
@@ -3511,9 +3513,9 @@ class BoolBinopNode(ExprNode):
     
     def calculate_result_code(self):
         return "(%s %s %s)" % (
-            self.operand1.result_code,
+            self.operand1.result(),
             self.py_to_c_op[self.operator],
-            self.operand2.result_code)
+            self.operand2.result())
     
     py_to_c_op = {'and': "&&", 'or': "||"}
 
@@ -3536,14 +3538,14 @@ class BoolBinopNode(ExprNode):
     def generate_operand1_test(self, code):
         #  Generate code to test the truth of the first operand.
         if self.type.is_pyobject:
-            test_result = self.temp_bool.result_code
+            test_result = self.temp_bool.result()
             code.putln(
                 "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
                     test_result,
                     self.operand1.py_result(),
                     code.error_goto_if_neg(test_result, self.pos)))
         else:
-            test_result = self.operand1.result_code
+            test_result = self.operand1.result()
         return test_result
 
 
@@ -3586,8 +3588,8 @@ class CondExprNode(ExprNode):
         #  be necessary.
         self.allocate_temp(env, result_code)
         self.test.allocate_temps(env, result_code)
-        self.true_val.allocate_temps(env, self.result_code)
-        self.false_val.allocate_temps(env, self.result_code)
+        self.true_val.allocate_temps(env, self.result())
+        self.false_val.allocate_temps(env, self.result())
         #  We haven't called release_temp on either value,
         #  because although they are temp nodes, they don't own 
         #  their result variable. And because they are temp
@@ -3627,7 +3629,7 @@ class CondExprNode(ExprNode):
     
     def generate_evaluation_code(self, code):
         self.test.generate_evaluation_code(code)
-        code.putln("if (%s) {" % self.test.result_code )
+        code.putln("if (%s) {" % self.test.result() )
         self.true_val.generate_evaluation_code(code)
         code.putln("} else {")
         self.false_val.generate_evaluation_code(code)
@@ -3844,19 +3846,19 @@ class PrimaryCmpNode(ExprNode, CmpNode):
 
     def calculate_result_code(self):
         return "(%s %s %s)" % (
-            self.operand1.result_code,
+            self.operand1.result(),
             self.c_operator(self.operator),
-            self.operand2.result_code)
+            self.operand2.result())
     
     def generate_evaluation_code(self, code):
         self.operand1.generate_evaluation_code(code)
         self.operand2.generate_evaluation_code(code)
         if self.is_temp:
-            self.generate_operation_code(code, self.result_code
+            self.generate_operation_code(code, self.result()
                 self.operand1, self.operator, self.operand2)
             if self.cascade:
                 self.cascade.generate_evaluation_code(code,
-                    self.result_code, self.operand2)
+                    self.result(), self.operand2)
             self.operand1.generate_disposal_code(code)
             self.operand2.generate_disposal_code(code)
     
@@ -4047,7 +4049,7 @@ class PyTypeTestNode(CoercionNode):
         return self.arg.is_ephemeral()
     
     def calculate_result_code(self):
-        return self.arg.result_code
+        return self.arg.result()
     
     def generate_result_code(self, code):
         if self.type.typeobj_is_available():
@@ -4085,10 +4087,10 @@ class CoerceToPyTypeNode(CoercionNode):
     def generate_result_code(self, code):
         function = self.arg.type.to_py_function
         code.putln('%s = %s(%s); %s' % (
-            self.result_code
+            self.result()
             function, 
-            self.arg.result_code
-            code.error_goto_if_null(self.result_code, self.pos)))
+            self.arg.result()
+            code.error_goto_if_null(self.result(), self.pos)))
 
 
 class CoerceFromPyTypeNode(CoercionNode):
@@ -4117,9 +4119,9 @@ class CoerceFromPyTypeNode(CoercionNode):
         if self.type.is_enum:
             rhs = typecast(self.type, c_long_type, rhs)
         code.putln('%s = %s; %s' % (
-            self.result_code
+            self.result()
             rhs,
-            code.error_goto_if(self.type.error_condition(self.result_code), self.pos)))
+            code.error_goto_if(self.type.error_condition(self.result()), self.pos)))
 
 
 class CoerceToBooleanNode(CoercionNode):
@@ -4142,15 +4144,15 @@ class CoerceToBooleanNode(CoercionNode):
         self.arg.check_const()
     
     def calculate_result_code(self):
-        return "(%s != 0)" % self.arg.result_code
+        return "(%s != 0)" % self.arg.result()
 
     def generate_result_code(self, code):
         if self.arg.type.is_pyobject:
             code.putln(
                 "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
-                    self.result_code
+                    self.result()
                     self.arg.py_result(), 
-                    code.error_goto_if_neg(self.result_code, self.pos)))
+                    code.error_goto_if_neg(self.result(), self.pos)))
 
 
 class CoerceToTempNode(CoercionNode):
@@ -4176,9 +4178,9 @@ class CoerceToTempNode(CoercionNode):
         #self.arg.generate_evaluation_code(code) # Already done
         # by generic generate_subexpr_evaluation_code!
         code.putln("%s = %s;" % (
-            self.result_code, self.arg.result_as(self.ctype())))
+            self.result(), self.arg.result_as(self.ctype())))
         if self.type.is_pyobject:
-            code.put_incref(self.result_code, self.ctype())
+            code.put_incref(self.result(), self.ctype())
 
 
 class CloneNode(CoercionNode):
@@ -4200,7 +4202,7 @@ class CloneNode(CoercionNode):
             self.entry = arg.entry
     
     def calculate_result_code(self):
-        return self.arg.result_code
+        return self.arg.result()
         
     def analyse_types(self, env):
         self.type = self.arg.type
@@ -4249,22 +4251,22 @@ class PersistentNode(ExprNode):
         self.analyse_counter += 1
     
     def calculate_result_code(self):
-        return self.result_code
+        return self.result()
 
     def generate_evaluation_code(self, code):
         if self.generate_counter == 0:
             self.arg.generate_evaluation_code(code)
             code.putln("%s = %s;" % (
-                self.result_code, self.arg.result_as(self.ctype())))
+                self.result(), self.arg.result_as(self.ctype())))
             if self.type.is_pyobject:
-                code.put_incref(self.result_code, self.ctype())
+                code.put_incref(self.result(), self.ctype())
             self.arg.generate_disposal_code(code)
         self.generate_counter += 1
                 
     def generate_disposal_code(self, code):
         if self.generate_counter == self.uses:
             if self.type.is_pyobject:
-                code.put_decref_clear(self.result_code, self.ctype())
+                code.put_decref_clear(self.result(), self.ctype())
 
     def allocate_temps(self, env, result=None):
         if self.temp_counter == 0:
@@ -4281,7 +4283,7 @@ class PersistentNode(ExprNode):
         
     def release_temp(self, env):
         if self.temp_counter == self.uses:
-            env.release_temp(self.result_code)
+            env.release_temp(self.result())
     
 #------------------------------------------------------------------------------------
 #
index fb4b25536f0699ab2e069c03601038a52ed0391b..6ecabcbd56002741be60c951f96c1a75ac1c5cf1 100644 (file)
@@ -439,7 +439,7 @@ class CArrayDeclaratorNode(CDeclaratorNode):
             self.dimension.analyse_const_expression(env)
             if not self.dimension.type.is_int:
                 error(self.dimension.pos, "Array dimension not integer")
-            size = self.dimension.result_code
+            size = self.dimension.result()
         else:
             size = None
         if not base_type.is_complete():
@@ -529,7 +529,7 @@ class CFuncDeclaratorNode(CDeclaratorNode):
                             "Exception value must be a Python exception or cdef function with no arguments.")
                     exc_val = self.exception_value
                 else:
-                    exc_val = self.exception_value.result_code
+                    exc_val = self.exception_value.result()
                     if not return_type.assignable_from(self.exception_value.type):
                         error(self.exception_value.pos,
                             "Exception value incompatible with function return type")
@@ -815,7 +815,7 @@ class CEnumDefItemNode(StatNode):
             if not self.value.type.is_int:
                 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
                 self.value.analyse_const_expression(env)
-            value = self.value.result_code
+            value = self.value.result()
         else:
             value = self.name
         entry = env.declare_const(self.name, enum_entry.type, 
@@ -1100,7 +1100,7 @@ class FuncDefNode(StatNode, BlockNode):
                     if default.is_temp and default.type.is_pyobject:
                         code.putln(
                             "%s = 0;" %
-                                default.result_code)
+                                default.result())
         # For Python class methods, create and store function object
         if self.assmt:
             self.assmt.generate_execution_code(code)
@@ -2142,16 +2142,16 @@ class OverrideCheckNode(StatNode):
             code.putln("else {")
         else:
             code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
-        err = code.error_goto_if_null(self.func_node.result_code, self.pos)
+        err = code.error_goto_if_null(self.func_node.result(), self.pos)
         # need to get attribute manually--scope would return cdef method
-        code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (self.func_node.result_code, self_arg, self.py_func.interned_attr_cname, err))
+        code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (self.func_node.result(), self_arg, self.py_func.interned_attr_cname, err))
         # It appears that this type is not anywhere exposed in the Python/C API
-        is_builtin_function_or_method = '(strcmp(Py_TYPE(%s)->tp_name, "builtin_function_or_method") == 0)' % self.func_node.result_code
-        is_overridden = '(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)' % (self.func_node.result_code, self.py_func.entry.func_cname)
+        is_builtin_function_or_method = '(strcmp(Py_TYPE(%s)->tp_name, "builtin_function_or_method") == 0)' % self.func_node.result()
+        is_overridden = '(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)' % (self.func_node.result(), self.py_func.entry.func_cname)
         code.putln('if (!%s || %s) {' % (is_builtin_function_or_method, is_overridden))
         self.body.generate_execution_code(code)
         code.putln('}')
-        code.put_decref_clear(self.func_node.result_code, PyrexTypes.py_object_type)
+        code.put_decref_clear(self.func_node.result(), PyrexTypes.py_object_type)
         code.putln("}")
 
 class ClassDefNode(StatNode, BlockNode):
@@ -2208,8 +2208,8 @@ class PyClassDefNode(ClassDefNode):
         self.classobj.analyse_expressions(env)
         genv = env.global_scope()
         cenv = self.scope
-        cenv.class_dict_cname = self.dict.result_code
-        cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result_code
+        cenv.class_dict_cname = self.dict.result()
+        cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
         self.body.analyse_expressions(cenv)
         self.target.analyse_target_expression(env, self.classobj)
         self.dict.release_temp(env)
@@ -2418,8 +2418,8 @@ class ExprStatNode(StatNode):
     
     def generate_execution_code(self, code):
         self.expr.generate_evaluation_code(code)
-        if not self.expr.is_temp and self.expr.result_code:
-            code.putln("%s;" % self.expr.result_code)
+        if not self.expr.is_temp and self.expr.result():
+            code.putln("%s;" % self.expr.result())
         self.expr.generate_disposal_code(code)
 
     def annotate(self, code):
@@ -2673,8 +2673,8 @@ class InPlaceAssignmentNode(AssignmentNode):
         elif self.rhs.type.is_pyobject:
             self.rhs = self.rhs.coerce_to(self.lhs.type, env)
         if self.lhs.type.is_pyobject:
-             self.result = ExprNodes.PyTempNode(self.pos, env).coerce_to(self.lhs.type, env)
-             self.result.allocate_temps(env)
+             self.result_value = ExprNodes.PyTempNode(self.pos, env).coerce_to(self.lhs.type, env)
+             self.result_value.allocate_temps(env)
 #        if use_temp:
 #            self.rhs = self.rhs.coerce_to_temp(env)
         self.rhs.allocate_temps(env)
@@ -2689,7 +2689,7 @@ class InPlaceAssignmentNode(AssignmentNode):
             self.dup.release_subexpr_temps(env)
 #        self.rhs.release_temp(env)
         if self.lhs.type.is_pyobject:
-            self.result.release_temp(env)
+            self.result_value.release_temp(env)
 
     def generate_execution_code(self, code):
         self.rhs.generate_evaluation_code(code)
@@ -2706,16 +2706,16 @@ class InPlaceAssignmentNode(AssignmentNode):
             self.dup.generate_result_code(code)
             code.putln(
                 "%s = %s(%s, %s%s); %s" % (
-                    self.result.result_code
+                    self.result_value.result()
                     self.py_operation_function(), 
                     self.dup.py_result(),
                     self.rhs.py_result(),
                     extra,
-                    code.error_goto_if_null(self.result.py_result(), self.pos)))
-            self.result.generate_evaluation_code(code) # May be a type check...
+                    code.error_goto_if_null(self.result_value.py_result(), self.pos)))
+            self.result_value.generate_evaluation_code(code) # May be a type check...
             self.rhs.generate_disposal_code(code)
             self.dup.generate_disposal_code(code)
-            self.lhs.generate_assignment_code(self.result, code)
+            self.lhs.generate_assignment_code(self.result_value, code)
         else: 
             c_op = self.operator
             if c_op == "//":
@@ -2730,7 +2730,7 @@ class InPlaceAssignmentNode(AssignmentNode):
                 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
             else:
                 self.dup.generate_result_code(code)
-                code.putln("%s %s= %s;" % (self.lhs.result_code, c_op, self.rhs.result_code) )
+                code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
             self.rhs.generate_disposal_code(code)
         if self.dup.is_temp:
             self.dup.generate_subexpr_disposal_code(code)
@@ -3090,7 +3090,7 @@ class AssertStatNode(StatNode):
         self.cond.generate_evaluation_code(code)
         code.putln(
             "if (unlikely(!%s)) {" %
-                self.cond.result_code)
+                self.cond.result())
         if self.value:
             self.value.generate_evaluation_code(code)
             code.putln(
@@ -3185,7 +3185,7 @@ class IfClauseNode(Node):
         self.condition.generate_evaluation_code(code)
         code.putln(
             "if (%s) {" %
-                self.condition.result_code)
+                self.condition.result())
         self.body.generate_execution_code(code)
         #code.putln(
         #      "goto %s;" %
@@ -3283,7 +3283,7 @@ class WhileStatNode(LoopNode, StatNode):
         self.condition.generate_evaluation_code(code)
         code.putln(
             "if (!%s) break;" %
-                self.condition.result_code)
+                self.condition.result())
         self.body.generate_execution_code(code)
         code.put_label(code.continue_label)
         code.putln("}")
@@ -3480,7 +3480,7 @@ class ForFromStatNode(LoopNode, StatNode):
             c_loopvar_node = ExprNodes.TempNode(self.pos, 
                 PyrexTypes.c_long_type, env)
             c_loopvar_node.allocate_temps(env)
-            self.loopvar_name = c_loopvar_node.result_code
+            self.loopvar_name = c_loopvar_node.result()
             self.py_loopvar_node = \
                 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
         self.bound1.allocate_temps(env)
@@ -3509,12 +3509,12 @@ class ForFromStatNode(LoopNode, StatNode):
         offset, incop = self.relation_table[self.relation1]
         if self.step is not None:
             self.step.generate_evaluation_code(code)
-            incop = "%s=%s" % (incop[0], self.step.result_code)
+            incop = "%s=%s" % (incop[0], self.step.result())
         code.putln(
             "for (%s = %s%s; %s %s %s; %s%s) {" % (
                 self.loopvar_name,
-                self.bound1.result_code, offset,
-                self.loopvar_name, self.relation2, self.bound2.result_code,
+                self.bound1.result(), offset,
+                self.loopvar_name, self.relation2, self.bound2.result(),
                 self.loopvar_name, incop))
         if self.py_loopvar_node:
             self.py_loopvar_node.generate_evaluation_code(code)
@@ -4180,10 +4180,10 @@ class FromImportStatNode(StatNode):
         for cname, target in self.interned_items:
             code.putln(
                 '%s = PyObject_GetAttr(%s, %s); %s' % (
-                    self.item.result_code
+                    self.item.result()
                     self.module.py_result(),
                     cname,
-                    code.error_goto_if_null(self.item.result_code, self.pos)))
+                    code.error_goto_if_null(self.item.result(), self.pos)))
             target.generate_assignment_code(self.item, code)
         self.module.generate_disposal_code(code)