Support increment/decrement via Cython special methods. (May not be +/-1 for C++.)
authorRobert Bradshaw <robertwb@math.washington.edu>
Thu, 14 Jan 2010 23:40:39 +0000 (15:40 -0800)
committerRobert Bradshaw <robertwb@math.washington.edu>
Thu, 14 Jan 2010 23:40:39 +0000 (15:40 -0800)
Cython/Compiler/ExprNodes.py
Cython/Compiler/ParseTreeTransforms.py

index a9de0ceee683a9e0f58274c5c8d3426d4417ad2c..571756619c86ca94d39ad0397e85141bb09c7f0a 100755 (executable)
@@ -4261,12 +4261,14 @@ class TildeNode(UnopNode):
         return "(~%s)" % self.operand.result()
 
 
-class DereferenceNode(UnopNode):
-    #  unary '*' operator
-    
+class CUnopNode(UnopNode):
+
     def is_py_operation(self):
         return False
 
+class DereferenceNode(CUnopNode):
+    #  unary * operator
+    
     def analyse_c_operation(self, env):
         if self.operand.type.is_ptr:
             self.type = self.operand.type.base_type
@@ -4277,6 +4279,25 @@ class DereferenceNode(UnopNode):
         return "(*%s)" % self.operand.result()
 
 
+class DecrementIncrementNode(CUnopNode):
+    #  unary ++/-- operator
+    
+    def analyse_c_operation(self, env):
+        if self.operand.type.is_ptr or self.operand.type.is_numeric:
+            self.type = self.operand.type
+        else:
+            self.type_error()
+
+    def calculate_result_code(self):
+        if self.is_prefix:
+            return "(%s%s)" % (self.operator, self.operand.result())
+        else:
+            return "(%s%s)" % (self.operand.result(), self.operator)
+
+def inc_dec_constructor(is_prefix, operator):
+    return lambda pos, **kwds: DecrementIncrementNode(pos, is_prefix=is_prefix, operator=operator, **kwds)
+
+
 class AmpersandNode(ExprNode):
     #  The C address-of operator.
     #
index 87963075230844ac187c7bd04b04935f35d8e1a0..f8da55b0732f05fc7a6c2903cdb556436675bbc2 100644 (file)
@@ -327,6 +327,10 @@ class InterpretCompilerDirectives(CythonTransform, SkipDeclarations):
         'typeof': TypeofNode,
         'address': AmpersandNode,
         'dereference': DereferenceNode,
+        'preincrement' : inc_dec_constructor(True, '++'),
+        'predecrement' : inc_dec_constructor(True, '--'),
+        'postincrement': inc_dec_constructor(False, '++'),
+        'postdecrement': inc_dec_constructor(False, '--'),
     }
     
     special_methods = set(['declare', 'union', 'struct', 'typedef', 'sizeof', 'cast', 'pointer', 'compiled', 'NULL']