From f53e00e3d50311e1264eb9bb66c4dda425e043f8 Mon Sep 17 00:00:00 2001 From: Robert Bradshaw Date: Sun, 31 Jan 2010 03:44:15 -0800 Subject: [PATCH] Make sure new can be used as a non-keyword. --- Cython/Compiler/Parsing.py | 2 +- Cython/Compiler/PyrexTypes.py | 30 +++++++++++++++++++++++----- Cython/Compiler/Scanning.py | 8 ++++++++ Cython/Compiler/Symtab.py | 2 +- Demos/setup.py | 3 ++- tests/run/new_as_nonkeyword.pyx | 35 +++++++++++++++++++++++++++++++++ 6 files changed, 72 insertions(+), 8 deletions(-) create mode 100644 tests/run/new_as_nonkeyword.pyx diff --git a/Cython/Compiler/Parsing.py b/Cython/Compiler/Parsing.py index a2bab288..388ad353 100644 --- a/Cython/Compiler/Parsing.py +++ b/Cython/Compiler/Parsing.py @@ -300,7 +300,7 @@ def p_yield_expression(s): #power: atom trailer* ('**' factor)* def p_power(s): - if s.systring == 'new': + if s.systring == 'new' and s.peek()[0] == 'IDENT': return p_new_expr(s) n1 = p_atom(s) while s.sy in ('(', '[', '.'): diff --git a/Cython/Compiler/PyrexTypes.py b/Cython/Compiler/PyrexTypes.py index 0b7592fb..e60ced01 100755 --- a/Cython/Compiler/PyrexTypes.py +++ b/Cython/Compiler/PyrexTypes.py @@ -2194,14 +2194,34 @@ modifiers_and_name_to_type = { (1, 0, "bint"): c_bint_type, } -def is_promotion(type, other_type): - if type.is_numeric and other_type.is_numeric: - return (type.is_int and type.is_int and type.signed == other_type.signed) \ - or (type.is_float and other_type.is_float) \ - or (type.is_enum and other_type.is_int) +def is_promotion0(src_type, dst_type): + if src_type.is_numeric and dst_type.is_numeric: + if src_type.is_int and dst_type.is_int: + if src_type.is_enum: + return True + elif src_type.signed: + return dst_type.signed and src_type.rank <= dst_type.rank + elif dst_type.signed: # and not src_type.signed + src_type.rank < dst_type.rank + else: + return src_type.rank <= dst_type.rank + elif src_type.is_float and dst_type.is_float: + return src_type.rank <= dst_type.rank + else: + return False else: return False +def is_promotion(src_type, dst_type): + # It's hard to find a hard definition of promotion, but empirical + # evidence suggests that the below is all that's allowed. + if src_type.is_numeric: + if dst_type.same_as(c_int_type): + return src_type.is_enum or (src_type.is_int and (not src_type.signed) + src_type.rank < dst_type.rank) + elif dst_type.same_as(c_double_type): + return src_type.is_float and src_type.rank <= dst_type.rank + return False + def best_match(args, functions, pos=None): """ Finds the best function to be called diff --git a/Cython/Compiler/Scanning.py b/Cython/Compiler/Scanning.py index 4e23bafd..6a3d2314 100644 --- a/Cython/Compiler/Scanning.py +++ b/Cython/Compiler/Scanning.py @@ -473,6 +473,14 @@ class PyrexScanner(Scanner): t = "%s %s" % (self.sy, self.systring) print("--- %3d %2d %s" % (line, col, t)) + def peek(self): + saved = self.sy, self.systring + self.next() + next = self.sy, self.systring + self.unread(*next) + self.sy, self.systring = saved + return next + def put_back(self, sy, systring): self.unread(self.sy, self.systring) self.sy = sy diff --git a/Cython/Compiler/Symtab.py b/Cython/Compiler/Symtab.py index 6ad9906f..162acb9f 100644 --- a/Cython/Compiler/Symtab.py +++ b/Cython/Compiler/Symtab.py @@ -470,7 +470,7 @@ class Scope(object): if visibility == 'extern' and entry.visibility == 'extern': if self.is_cpp(): temp = self.add_cfunction(name, type, pos, cname, visibility, modifiers) - entry.overloaded_alternatives.append(temp) + temp.overloaded_alternatives = entry.all_alternatives() entry = temp else: warning(pos, "Function signature does not match previous declaration", 1) diff --git a/Demos/setup.py b/Demos/setup.py index 60cbeb81..c32949ae 100644 --- a/Demos/setup.py +++ b/Demos/setup.py @@ -13,10 +13,11 @@ except: ext_modules=[ Extension("primes", ["primes.pyx"]), Extension("spam", ["spam.pyx"]), + Extension("square", ["square.pyx"], language="c++"), ] for file in glob.glob("*.pyx"): - if file != "numeric_demo.pyx": + if file != "numeric_demo.pyx" and file != "square.pyx": ext_modules.append(Extension(file[:-4], [file], include_dirs = numpy_include_dirs)) setup( diff --git a/tests/run/new_as_nonkeyword.pyx b/tests/run/new_as_nonkeyword.pyx new file mode 100644 index 00000000..abbc3360 --- /dev/null +++ b/tests/run/new_as_nonkeyword.pyx @@ -0,0 +1,35 @@ +cdef extern from *: + int new(int new) + +def new(x): + """ + >>> new(3) + 3 + """ + cdef int new = x + return new + +def x(new): + """ + >>> x(10) + 110 + >>> x(1) + 1 + """ + if new*new != new: + return new + new**2 + return new + +class A: + def new(self, n): + """ + >>> a = A() + >>> a.new(3) + 6 + >>> a.new(5) + 120 + """ + if n <= 1: + return 1 + else: + return n * self.new(n-1) -- 2.26.2