From: Robert Bradshaw Date: Thu, 26 Mar 2009 03:38:19 +0000 (-0700) Subject: cython.cdiv and cython.cmod for CEP 516 X-Git-Tag: 0.11.1.alpha~34 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=8c9d947ef37a4b9f25d1b59e893c75a20c6f3458;p=cython.git cython.cdiv and cython.cmod for CEP 516 --- diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index 5c998ebe..beb62361 100644 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -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): diff --git a/Cython/Compiler/ParseTreeTransforms.py b/Cython/Compiler/ParseTreeTransforms.py index 21bb7b07..58475e3a 100644 --- a/Cython/Compiler/ParseTreeTransforms.py +++ b/Cython/Compiler/ParseTreeTransforms.py @@ -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) diff --git a/tests/run/cdivision_CEP_516.pyx b/tests/run/cdivision_CEP_516.pyx index 163fc2b3..b0b05c44 100644 --- a/tests/run/cdivision_CEP_516.pyx +++ b/tests/run/cdivision_CEP_516.pyx @@ -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