From 8c9d947ef37a4b9f25d1b59e893c75a20c6f3458 Mon Sep 17 00:00:00 2001 From: Robert Bradshaw Date: Wed, 25 Mar 2009 20:38:19 -0700 Subject: [PATCH] cython.cdiv and cython.cmod for CEP 516 --- Cython/Compiler/ExprNodes.py | 30 ++++++++++++++++---------- Cython/Compiler/ParseTreeTransforms.py | 12 +++++++++++ tests/run/cdivision_CEP_516.pyx | 9 ++++++++ 3 files changed, 40 insertions(+), 11 deletions(-) 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 -- 2.26.2