Commit 8c9d947e authored by Robert Bradshaw's avatar Robert Bradshaw

cython.cdiv and cython.cmod for CEP 516

parent a60c7801
......@@ -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):
......
......@@ -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)
......
......@@ -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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment