support for comma operator
authorRobert Bradshaw <robertwb@math.washington.edu>
Thu, 26 Aug 2010 07:20:49 +0000 (00:20 -0700)
committerRobert Bradshaw <robertwb@math.washington.edu>
Thu, 26 Aug 2010 07:20:49 +0000 (00:20 -0700)
Cython/Compiler/ExprNodes.py
Cython/Compiler/ParseTreeTransforms.py
Cython/Compiler/Parsing.py
tests/run/cpp_operators.pyx
tests/run/cpp_operators_helper.h

index c635d668eb4e640fd728b3db619da35889bacb03..549779b753bebeed8530ae96a275f1258a87ba00 100755 (executable)
@@ -5279,6 +5279,28 @@ class BinopNode(ExprNode):
         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):
     #  Binary operation taking numeric arguments.
     
index 64c29a0c488755db6bca44c8dc3a7b74869f1555..fccba1775450fb8fe4d4fa5a9a5b70ebc95f5b40 100644 (file)
@@ -577,10 +577,14 @@ class InterpretCompilerDirectives(CythonTransform, SkipDeclarations):
         'operator.predecrement' : inc_dec_constructor(True, '--'),
         'operator.postincrement': inc_dec_constructor(False, '++'),
         'operator.postdecrement': inc_dec_constructor(False, '--'),
-
+        
         # For backwards compatability.
         'address': AmpersandNode,
     }
+
+    binop_method_nodes = {
+        'operator.comma'        : c_binop_constructor(','),
+    }
     
     special_methods = set(['declare', 'union', 'struct', 'typedef', 'sizeof',
                            'cast', 'pointer', 'compiled', 'NULL']
@@ -1385,6 +1389,11 @@ class TransformBuiltinMethods(EnvTransform):
                     error(node.function.pos, u"%s() takes exactly one argument" % function)
                 else:
                     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':
                 if len(node.args) != 2:
                     error(node.function.pos, u"cast() takes exactly two arguments")
index 7b853018ad05e028fa76d462b315d0a76945108b..35f92d1cb88e9a6505c2739ecc3f569d5c79153a 100644 (file)
@@ -2056,7 +2056,7 @@ def p_c_func_declarator(s, pos, ctx, base, cmethod_flag):
 
 supported_overloaded_operators = cython.set([
     '+', '-', '*', '/', '%', 
-    '++', '--', '~', '|', '&', '^', '<<', '>>',
+    '++', '--', '~', '|', '&', '^', '<<', '>>', ',',
     '==', '!=', '>=', '>', '<=', '<',
     '[]', '()',
 ])
@@ -2102,12 +2102,11 @@ def p_c_simple_declarator(s, ctx, empty, is_type, cmethod_flag,
                 error(s.position(), "Empty declarator")
             name = ""
             cname = None
-        print pos, ctx.__dict__
         if cname is None and ctx.namespace is not None:
             cname = ctx.namespace + "::" + name
         if name == 'operator' and ctx.visibility == 'extern' and nonempty:
             op = s.sy
-            if op in '+-*/<=>!%&|([^~,':
+            if [c in '+-*/<=>!%&|([^~,' for c in op]:
                 s.next()
                 # Handle diphthong operators.
                 if op == '(':
index 9487dd45096e2e43a3e7379ed44d55744996c5a4..1b78248627de46fb0f007c35fc6f4bb7c7ecd209 100644 (file)
@@ -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)
@@ -83,6 +84,7 @@ def test_binop():
     binary ^
     binary <<
     binary >>
+    binary COMMA
     """
     cdef TestOps* t = new TestOps()
     out(t[0] + 1)
@@ -97,6 +99,8 @@ def test_binop():
     
     out(t[0] << 1)
     out(t[0] >> 1)
+
+    out(cython.operator.comma(t[0], 1))
     del t
 
 def test_cmp():
index b8372f2722705ec19cc8736854bc6ba7e12e47e0..231f4868bc9ccd0921c14c201ed0e6105722f760 100644 (file)
@@ -2,6 +2,8 @@
 #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 COMMA ,
+
 class TestOps {
 
 public:
@@ -30,6 +32,7 @@ public:
     BIN_OP(|);
     BIN_OP(&);
     BIN_OP(^);
+    BIN_OP(COMMA);
 
     BIN_OP(==);
     BIN_OP(!=);