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): ...@@ -4232,12 +4232,16 @@ class MulNode(NumBinopNode):
class DivNode(NumBinopNode): class DivNode(NumBinopNode):
# '/' or '//' operator. # '/' or '//' operator.
cdivision = None
def generate_evaluation_code(self, code): def generate_evaluation_code(self, code):
self.cdivision = (code.globalstate.directives['cdivision'] if not self.type.is_pyobject:
or not self.type.signed if self.cdivision is None:
or self.type.is_float) self.cdivision = (code.globalstate.directives['cdivision']
if not self.cdivision: or not self.type.signed
code.globalstate.use_utility_code(div_utility_code.specialize(self.type)) 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) NumBinopNode.generate_evaluation_code(self, code)
def calculate_result_code(self): def calculate_result_code(self):
...@@ -4254,6 +4258,8 @@ class DivNode(NumBinopNode): ...@@ -4254,6 +4258,8 @@ class DivNode(NumBinopNode):
class ModNode(NumBinopNode): class ModNode(NumBinopNode):
# '%' operator. # '%' operator.
cdivision = None
def is_py_operation(self): def is_py_operation(self):
return (self.operand1.type.is_string return (self.operand1.type.is_string
...@@ -4261,12 +4267,14 @@ class ModNode(NumBinopNode): ...@@ -4261,12 +4267,14 @@ class ModNode(NumBinopNode):
or NumBinopNode.is_py_operation(self)) or NumBinopNode.is_py_operation(self))
def generate_evaluation_code(self, code): def generate_evaluation_code(self, code):
self.cdivision = code.globalstate.directives['cdivision'] or not self.type.signed if not self.type.is_pyobject:
if not self.cdivision: if self.cdivision is None:
math_h_modifier = getattr(self.type, 'math_h_modifier', '__Pyx_INT') self.cdivision = code.globalstate.directives['cdivision'] or not self.type.signed
if self.type.is_int: if not self.cdivision:
code.globalstate.use_utility_code(mod_int_helper_macro) math_h_modifier = getattr(self.type, 'math_h_modifier', '__Pyx_INT')
code.globalstate.use_utility_code(mod_utility_code.specialize(self.type, math_h_modifier=math_h_modifier)) 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) NumBinopNode.generate_evaluation_code(self, code)
def calculate_result_code(self): def calculate_result_code(self):
......
...@@ -951,6 +951,18 @@ class TransformBuiltinMethods(EnvTransform): ...@@ -951,6 +951,18 @@ class TransformBuiltinMethods(EnvTransform):
error(node.function.pos, u"sizeof takes exactly one argument" % function) error(node.function.pos, u"sizeof takes exactly one argument" % function)
else: else:
node = AmpersandNode(node.function.pos, operand=node.args[0]) 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: else:
error(node.function.pos, u"'%s' not a valid cython language construct" % function) error(node.function.pos, u"'%s' not a valid cython language construct" % function)
......
...@@ -23,6 +23,9 @@ True ...@@ -23,6 +23,9 @@ True
[1, -2, 1, -2] [1, -2, 1, -2]
>>> [div_int_c(a, b) for a, b in v] >>> [div_int_c(a, b) for a, b in v]
[1, -1, 1, -1] [1, -1, 1, -1]
>>> [test_cdiv_cmod(a, b) for a, b in v]
[(1, 7), (-1, -7), (1, -7), (-1, 7)]
""" """
cimport cython cimport cython
...@@ -64,3 +67,9 @@ def div_int_py(int a, int b): ...@@ -64,3 +67,9 @@ def div_int_py(int a, int b):
def div_int_c(int a, int b): def div_int_c(int a, int b):
return a // 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