cython.cdiv and cython.cmod for CEP 516
authorRobert Bradshaw <robertwb@math.washington.edu>
Thu, 26 Mar 2009 03:38:19 +0000 (20:38 -0700)
committerRobert Bradshaw <robertwb@math.washington.edu>
Thu, 26 Mar 2009 03:38:19 +0000 (20:38 -0700)
Cython/Compiler/ExprNodes.py
Cython/Compiler/ParseTreeTransforms.py
tests/run/cdivision_CEP_516.pyx

index 5c998ebe0cc96c2ea2fdd50214dde90d693e7b69..beb6236140dc590e2466669885afab6968b6a9fb 100644 (file)
@@ -4232,12 +4232,16 @@ class MulNode(NumBinopNode):
 class DivNode(NumBinopNode):
     #  '/' or '//' operator.
     
+    cdivision = None
+    
     def generate_evaluation_code(self, code):
-        self.cdivision = (code.globalstate.directives['cdivision'] 
-                            or not self.type.signed
-                            or self.type.is_float)
-        if not self.cdivision:
-            code.globalstate.use_utility_code(div_utility_code.specialize(self.type))
+        if not self.type.is_pyobject:
+            if self.cdivision is None:
+                self.cdivision = (code.globalstate.directives['cdivision'] 
+                                    or not self.type.signed
+                                    or self.type.is_float)
+            if not self.cdivision:
+                code.globalstate.use_utility_code(div_utility_code.specialize(self.type))
         NumBinopNode.generate_evaluation_code(self, code)
     
     def calculate_result_code(self):
@@ -4254,6 +4258,8 @@ class DivNode(NumBinopNode):
 
 class ModNode(NumBinopNode):
     #  '%' operator.
+
+    cdivision = None
     
     def is_py_operation(self):
         return (self.operand1.type.is_string
@@ -4261,12 +4267,14 @@ class ModNode(NumBinopNode):
             or NumBinopNode.is_py_operation(self))
 
     def generate_evaluation_code(self, code):
-        self.cdivision = code.globalstate.directives['cdivision'] or not self.type.signed
-        if not self.cdivision:
-            math_h_modifier = getattr(self.type, 'math_h_modifier', '__Pyx_INT')
-            if self.type.is_int:
-                code.globalstate.use_utility_code(mod_int_helper_macro)
-            code.globalstate.use_utility_code(mod_utility_code.specialize(self.type, math_h_modifier=math_h_modifier))
+        if not self.type.is_pyobject:
+            if self.cdivision is None:
+                self.cdivision = code.globalstate.directives['cdivision'] or not self.type.signed
+            if not self.cdivision:
+                math_h_modifier = getattr(self.type, 'math_h_modifier', '__Pyx_INT')
+                if self.type.is_int:
+                    code.globalstate.use_utility_code(mod_int_helper_macro)
+                code.globalstate.use_utility_code(mod_utility_code.specialize(self.type, math_h_modifier=math_h_modifier))
         NumBinopNode.generate_evaluation_code(self, code)
     
     def calculate_result_code(self):
index 21bb7b07e00093fccd4e44839d7085c13a846dcb..58475e3a73f2b82390cfe518457a6c2d9c6a2846 100644 (file)
@@ -951,6 +951,18 @@ class TransformBuiltinMethods(EnvTransform):
                     error(node.function.pos, u"sizeof takes exactly one argument" % function)
                 else:
                     node = AmpersandNode(node.function.pos, operand=node.args[0])
+            elif function == 'cmod':
+                if len(node.args) != 2:
+                    error(node.function.pos, u"cmod takes exactly one argument" % function)
+                else:
+                    node = binop_node(node.function.pos, '%', node.args[0], node.args[1])
+                    node.cdivision = True
+            elif function == 'cdiv':
+                if len(node.args) != 2:
+                    error(node.function.pos, u"cmod takes exactly one argument" % function)
+                else:
+                    node = binop_node(node.function.pos, '/', node.args[0], node.args[1])
+                    node.cdivision = True
             else:
                 error(node.function.pos, u"'%s' not a valid cython language construct" % function)
         
index 163fc2b3451ea5e6095dd7d99aacd40bc893f186..b0b05c441bc9437e5366e997ce8b4842d643643f 100644 (file)
@@ -23,6 +23,9 @@ True
 [1, -2, 1, -2]
 >>> [div_int_c(a, b) for a, b in v]
 [1, -1, 1, -1]
+
+>>> [test_cdiv_cmod(a, b) for a, b in v]
+[(1, 7), (-1, -7), (1, -7), (-1, 7)]
 """
 
 cimport cython
@@ -64,3 +67,9 @@ def div_int_py(int a, int b):
 def div_int_c(int a, int b):
     return a // b
 
+
+@cython.cdivision(False)
+def test_cdiv_cmod(short a, short b):
+    cdef short q = cython.cdiv(a, b)
+    cdef short r = cython.cmod(a, b)
+    return q, r