Commit 4e3b2f43 authored by Robert Bradshaw's avatar Robert Bradshaw

Cython bang operator overloading.

parent 1a6fcd39
...@@ -7021,6 +7021,20 @@ class CUnopNode(UnopNode): ...@@ -7021,6 +7021,20 @@ class CUnopNode(UnopNode):
def is_py_operation(self): def is_py_operation(self):
return False return False
class BangNode(CUnopNode):
# unary ! operator
operator = '!'
def analyse_c_operation(self, env):
if self.operand.type.is_ptr or self.operand.type.is_numeric:
self.type = PyrexTypes.c_bint_type
else:
self.type_error()
def calculate_result_code(self):
return "(!%s)" % self.operand.result()
class DereferenceNode(CUnopNode): class DereferenceNode(CUnopNode):
# unary * operator # unary * operator
......
...@@ -73,7 +73,7 @@ def make_lexicon(): ...@@ -73,7 +73,7 @@ def make_lexicon():
deco = Str("@") deco = Str("@")
bra = Any("([{") bra = Any("([{")
ket = Any(")]}") ket = Any(")]}")
punct = Any(":,;+-*/|&<>=.%`~^?") punct = Any(":,;+-*/|&<>=.%`~^?!")
diphthong = Str("==", "<>", "!=", "<=", ">=", "<<", ">>", "**", "//", diphthong = Str("==", "<>", "!=", "<=", ">=", "<<", ">>", "**", "//",
"+=", "-=", "*=", "/=", "%=", "|=", "^=", "&=", "+=", "-=", "*=", "/=", "%=", "|=", "^=", "&=",
"<<=", ">>=", "**=", "//=", "->") "<<=", ">>=", "**=", "//=", "->")
......
...@@ -614,6 +614,7 @@ class InterpretCompilerDirectives(CythonTransform, SkipDeclarations): ...@@ -614,6 +614,7 @@ class InterpretCompilerDirectives(CythonTransform, SkipDeclarations):
'typeof': ExprNodes.TypeofNode, 'typeof': ExprNodes.TypeofNode,
'operator.address': ExprNodes.AmpersandNode, 'operator.address': ExprNodes.AmpersandNode,
'operator.bang': ExprNodes.BangNode,
'operator.dereference': ExprNodes.DereferenceNode, 'operator.dereference': ExprNodes.DereferenceNode,
'operator.preincrement' : ExprNodes.inc_dec_constructor(True, '++'), 'operator.preincrement' : ExprNodes.inc_dec_constructor(True, '++'),
'operator.predecrement' : ExprNodes.inc_dec_constructor(True, '--'), 'operator.predecrement' : ExprNodes.inc_dec_constructor(True, '--'),
......
...@@ -2297,7 +2297,7 @@ supported_overloaded_operators = set([ ...@@ -2297,7 +2297,7 @@ supported_overloaded_operators = set([
'+', '-', '*', '/', '%', '+', '-', '*', '/', '%',
'++', '--', '~', '|', '&', '^', '<<', '>>', ',', '++', '--', '~', '|', '&', '^', '<<', '>>', ',',
'==', '!=', '>=', '>', '<=', '<', '==', '!=', '>=', '>', '<=', '<',
'[]', '()', '[]', '()', '!',
]) ])
def p_c_simple_declarator(s, ctx, empty, is_type, cmethod_flag, def p_c_simple_declarator(s, ctx, empty, is_type, cmethod_flag,
...@@ -2345,7 +2345,7 @@ def p_c_simple_declarator(s, ctx, empty, is_type, cmethod_flag, ...@@ -2345,7 +2345,7 @@ def p_c_simple_declarator(s, ctx, empty, is_type, cmethod_flag,
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 [1 for c in op if c in '+-*/<=>!%&|([^~,']: if [1 for c in op if c in '+-*/<=>!%&|([^~,!']:
s.next() s.next()
# Handle diphthong operators. # Handle diphthong operators.
if op == '(': if op == '(':
......
...@@ -332,9 +332,11 @@ syntax as C++. Cython provides functions replacing these operators in ...@@ -332,9 +332,11 @@ syntax as C++. Cython provides functions replacing these operators in
a special module ``cython.operator``. The functions provided are: a special module ``cython.operator``. The functions provided are:
* ``cython.operator.dereference`` for dereferencing. ``dereference(foo)`` * ``cython.operator.dereference`` for dereferencing. ``dereference(foo)``
will produce the C++ code ``*foo`` will produce the C++ code ``*(foo)``
* ``cython.operator.bang`` for not. ``bang(foo)``
will produce the C++ code ``!(foo)``
* ``cython.operator.preincrement`` for pre-incrementation. ``preincrement(foo)`` * ``cython.operator.preincrement`` for pre-incrementation. ``preincrement(foo)``
will produce the C++ code ``++foo`` will produce the C++ code ``++(foo)``
* ... * ...
These functions need to be cimported. Of course, one can use a These functions need to be cimported. Of course, one can use a
......
...@@ -13,6 +13,7 @@ cdef extern from "cpp_operators_helper.h": ...@@ -13,6 +13,7 @@ cdef extern from "cpp_operators_helper.h":
char* operator-() char* operator-()
char* operator*() char* operator*()
char* operator~() char* operator~()
char* operator!()
char* operator++() char* operator++()
char* operator--() char* operator--()
...@@ -50,12 +51,14 @@ def test_unops(): ...@@ -50,12 +51,14 @@ def test_unops():
unary - unary -
unary ~ unary ~
unary * unary *
unary !
""" """
cdef TestOps* t = new TestOps() cdef TestOps* t = new TestOps()
out(+t[0]) out(+t[0])
out(-t[0]) out(-t[0])
out(~t[0]) out(~t[0])
out(deref(t[0])) out(deref(t[0]))
out(cython.operator.bang(t[0]))
del t del t
def test_incdec(): def test_incdec():
......
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