From bd9e529d487911d6d444766b81d697eb4a2b8621 Mon Sep 17 00:00:00 2001 From: Robert Bradshaw Date: Thu, 14 Jan 2010 18:24:31 -0800 Subject: [PATCH] C++ cmp operators. --- Cython/Compiler/ExprNodes.py | 15 +++++++++------ Cython/Compiler/Parsing.py | 6 +++++- tests/run/cpp_operators.pyx | 26 ++++++++++++++++++++++++++ tests/run/cpp_operators_helper.h | 9 ++++++++- 4 files changed, 48 insertions(+), 8 deletions(-) diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index 4f57ebe8..afbf2f8e 100755 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -5303,9 +5303,9 @@ class CmpNode(object): def is_cpp_comparison(self): type1 = self.operand1.type type2 = self.operand2.type - if type1.is_ptr: + if type1.is_reference: type1 = type1.base_type - if type2.is_ptr: + if type2.is_reference: type2 = type2.base_type return type1.is_cpp_class or type2.is_cpp_class @@ -5569,6 +5569,9 @@ class PrimaryCmpNode(ExprNode, CmpNode): self.operand2.analyse_types(env) if self.is_cpp_comparison(): self.analyse_cpp_comparison(env) + if self.cascade: + error(self.pos, "Cascading comparison not yet supported for cpp types.") + return if self.cascade: self.cascade.analyse_types(env) @@ -5601,9 +5604,9 @@ class PrimaryCmpNode(ExprNode, CmpNode): def analyse_cpp_comparison(self, env): type1 = self.operand1.type type2 = self.operand2.type - if type1.is_ptr: + if type1.is_reference: type1 = type1.base_type - if type2.is_ptr: + if type2.is_reference: type2 = type2.base_type entry = env.lookup(type1.name) function = entry.type.scope.lookup("operator%s" % self.operator) @@ -5611,12 +5614,12 @@ class PrimaryCmpNode(ExprNode, CmpNode): error(self.pos, "Invalid types for '%s' (%s, %s)" % (self.operator, type1, type2)) return - entry = PyrexTypes.best_match([self.operand1, self.operand2], function.all_alternatives(), self.pos) + entry = PyrexTypes.best_match([self.operand2], function.all_alternatives(), self.pos) if entry is None: self.type = PyrexTypes.error_type self.result_code = "" return - if (entry.type.is_ptr): + if entry.type.is_ptr: self.type = entry.type.base_type.return_type else: self.type = entry.type.return_type diff --git a/Cython/Compiler/Parsing.py b/Cython/Compiler/Parsing.py index a683ed81..64102410 100644 --- a/Cython/Compiler/Parsing.py +++ b/Cython/Compiler/Parsing.py @@ -2058,7 +2058,11 @@ def p_c_func_declarator(s, pos, ctx, base, cmethod_flag): exception_value = exc_val, exception_check = exc_check, nogil = nogil or ctx.nogil or with_gil, with_gil = with_gil) -supported_overloaded_operators = set(['+', '-', '*', '/', '%', '++', '--', '~', '|', '&', '^', '<<', '>>' ]) +supported_overloaded_operators = set([ + '+', '-', '*', '/', '%', + '++', '--', '~', '|', '&', '^', '<<', '>>', + '==', '!=', '>=', '>', '<=', '<', +]) def p_c_simple_declarator(s, ctx, empty, is_type, cmethod_flag, assignable, nonempty): diff --git a/tests/run/cpp_operators.pyx b/tests/run/cpp_operators.pyx index 380f3f7f..d1b85007 100644 --- a/tests/run/cpp_operators.pyx +++ b/tests/run/cpp_operators.pyx @@ -27,6 +27,13 @@ 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) + def test_unops(): """ >>> test_unops() @@ -85,3 +92,22 @@ def test_binop(): print t[0] << 1 print t[0] >> 1 del t + +def test_cmp(): + """ + >>> test_cmp() + binary == + binary != + binary >= + binary > + binary <= + binary < + """ + cdef TestOps* t = new TestOps() + print t[0] == 1 + print t[0] != 1 + print t[0] >= 1 + print t[0] > 1 + print t[0] <= 1 + print t[0] < 1 + del t diff --git a/tests/run/cpp_operators_helper.h b/tests/run/cpp_operators_helper.h index 769f3e7c..f85218e1 100644 --- a/tests/run/cpp_operators_helper.h +++ b/tests/run/cpp_operators_helper.h @@ -30,5 +30,12 @@ public: BIN_OP(|); BIN_OP(&); BIN_OP(^); - + + BIN_OP(==); + BIN_OP(!=); + BIN_OP(<=); + BIN_OP(<); + BIN_OP(>=); + BIN_OP(>); + }; -- 2.26.2