Commit 532074a2 authored by Robert Bradshaw's avatar Robert Bradshaw

support for comma operator

parent c5560a14
...@@ -5279,6 +5279,28 @@ class BinopNode(ExprNode): ...@@ -5279,6 +5279,28 @@ class BinopNode(ExprNode):
self.type = PyrexTypes.error_type self.type = PyrexTypes.error_type
class CBinopNode(BinopNode):
def analyse_types(self, env):
BinopNode.analyse_types(self, env)
if self.is_py_operation():
self.type = PyrexTypes.error_type
def py_operation_function():
return ""
def calculate_result_code(self):
return "(%s %s %s)" % (
self.operand1.result(),
self.operator,
self.operand2.result())
def c_binop_constructor(operator):
def make_binop_node(pos, **operands):
return CBinopNode(pos, operator=operator, **operands)
return make_binop_node
class NumBinopNode(BinopNode): class NumBinopNode(BinopNode):
# Binary operation taking numeric arguments. # Binary operation taking numeric arguments.
......
...@@ -577,10 +577,14 @@ class InterpretCompilerDirectives(CythonTransform, SkipDeclarations): ...@@ -577,10 +577,14 @@ class InterpretCompilerDirectives(CythonTransform, SkipDeclarations):
'operator.predecrement' : inc_dec_constructor(True, '--'), 'operator.predecrement' : inc_dec_constructor(True, '--'),
'operator.postincrement': inc_dec_constructor(False, '++'), 'operator.postincrement': inc_dec_constructor(False, '++'),
'operator.postdecrement': inc_dec_constructor(False, '--'), 'operator.postdecrement': inc_dec_constructor(False, '--'),
# For backwards compatability. # For backwards compatability.
'address': AmpersandNode, 'address': AmpersandNode,
} }
binop_method_nodes = {
'operator.comma' : c_binop_constructor(','),
}
special_methods = set(['declare', 'union', 'struct', 'typedef', 'sizeof', special_methods = set(['declare', 'union', 'struct', 'typedef', 'sizeof',
'cast', 'pointer', 'compiled', 'NULL'] 'cast', 'pointer', 'compiled', 'NULL']
...@@ -1385,6 +1389,11 @@ class TransformBuiltinMethods(EnvTransform): ...@@ -1385,6 +1389,11 @@ class TransformBuiltinMethods(EnvTransform):
error(node.function.pos, u"%s() takes exactly one argument" % function) error(node.function.pos, u"%s() takes exactly one argument" % function)
else: else:
node = InterpretCompilerDirectives.unop_method_nodes[function](node.function.pos, operand=node.args[0]) node = InterpretCompilerDirectives.unop_method_nodes[function](node.function.pos, operand=node.args[0])
elif function in InterpretCompilerDirectives.binop_method_nodes:
if len(node.args) != 2:
error(node.function.pos, u"%s() takes exactly two arguments" % function)
else:
node = InterpretCompilerDirectives.binop_method_nodes[function](node.function.pos, operand1=node.args[0], operand2=node.args[1])
elif function == u'cast': elif function == u'cast':
if len(node.args) != 2: if len(node.args) != 2:
error(node.function.pos, u"cast() takes exactly two arguments") error(node.function.pos, u"cast() takes exactly two arguments")
......
...@@ -2056,7 +2056,7 @@ def p_c_func_declarator(s, pos, ctx, base, cmethod_flag): ...@@ -2056,7 +2056,7 @@ def p_c_func_declarator(s, pos, ctx, base, cmethod_flag):
supported_overloaded_operators = cython.set([ supported_overloaded_operators = cython.set([
'+', '-', '*', '/', '%', '+', '-', '*', '/', '%',
'++', '--', '~', '|', '&', '^', '<<', '>>', '++', '--', '~', '|', '&', '^', '<<', '>>', ',',
'==', '!=', '>=', '>', '<=', '<', '==', '!=', '>=', '>', '<=', '<',
'[]', '()', '[]', '()',
]) ])
...@@ -2102,12 +2102,11 @@ def p_c_simple_declarator(s, ctx, empty, is_type, cmethod_flag, ...@@ -2102,12 +2102,11 @@ def p_c_simple_declarator(s, ctx, empty, is_type, cmethod_flag,
error(s.position(), "Empty declarator") error(s.position(), "Empty declarator")
name = "" name = ""
cname = None cname = None
print pos, ctx.__dict__
if cname is None and ctx.namespace is not None: if cname is None and ctx.namespace is not None:
cname = ctx.namespace + "::" + name cname = ctx.namespace + "::" + name
if name == 'operator' and ctx.visibility == 'extern' and nonempty: if name == 'operator' and ctx.visibility == 'extern' and nonempty:
op = s.sy op = s.sy
if op in '+-*/<=>!%&|([^~,': if [c in '+-*/<=>!%&|([^~,' for c in op]:
s.next() s.next()
# Handle diphthong operators. # Handle diphthong operators.
if op == '(': if op == '(':
......
...@@ -26,6 +26,7 @@ cdef extern from "cpp_operators_helper.h": ...@@ -26,6 +26,7 @@ cdef extern from "cpp_operators_helper.h":
char* operator|(int) char* operator|(int)
char* operator&(int) char* operator&(int)
char* operator^(int) char* operator^(int)
char* operator,(int)
char* operator<<(int) char* operator<<(int)
char* operator>>(int) char* operator>>(int)
...@@ -83,6 +84,7 @@ def test_binop(): ...@@ -83,6 +84,7 @@ def test_binop():
binary ^ binary ^
binary << binary <<
binary >> binary >>
binary COMMA
""" """
cdef TestOps* t = new TestOps() cdef TestOps* t = new TestOps()
out(t[0] + 1) out(t[0] + 1)
...@@ -97,6 +99,8 @@ def test_binop(): ...@@ -97,6 +99,8 @@ def test_binop():
out(t[0] << 1) out(t[0] << 1)
out(t[0] >> 1) out(t[0] >> 1)
out(cython.operator.comma(t[0], 1))
del t del t
def test_cmp(): def test_cmp():
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
#define POST_UN_OP(op) const char* operator op (int x) { return "post "#op; } #define POST_UN_OP(op) const char* operator op (int x) { return "post "#op; }
#define BIN_OP(op) const char* operator op (int x) { return "binary "#op; } #define BIN_OP(op) const char* operator op (int x) { return "binary "#op; }
#define COMMA ,
class TestOps { class TestOps {
public: public:
...@@ -30,6 +32,7 @@ public: ...@@ -30,6 +32,7 @@ public:
BIN_OP(|); BIN_OP(|);
BIN_OP(&); BIN_OP(&);
BIN_OP(^); BIN_OP(^);
BIN_OP(COMMA);
BIN_OP(==); BIN_OP(==);
BIN_OP(!=); BIN_OP(!=);
......
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