Make sure new can be used as a non-keyword.
authorRobert Bradshaw <robertwb@math.washington.edu>
Sun, 31 Jan 2010 11:44:15 +0000 (03:44 -0800)
committerRobert Bradshaw <robertwb@math.washington.edu>
Sun, 31 Jan 2010 11:44:15 +0000 (03:44 -0800)
Cython/Compiler/Parsing.py
Cython/Compiler/PyrexTypes.py
Cython/Compiler/Scanning.py
Cython/Compiler/Symtab.py
Demos/setup.py
tests/run/new_as_nonkeyword.pyx [new file with mode: 0644]

index a2bab2881cb6e1b9bf1ad58d6b782fc5ef63ea0c..388ad353aabf82e23aaa8cba0baaf49a64167f8a 100644 (file)
@@ -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 ('(', '[', '.'):
index 0b7592fb40a12372a78084f93f9d6543f61173e2..e60ced01a67731ad01e19ca5643adbb7bca3cfd7 100755 (executable)
@@ -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
index 4e23bafd1773b4129b5720a27925746da0dfcd44..6a3d2314fe2ab2799a1974c2ce9456d769a74886 100644 (file)
@@ -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
index 6ad9906f847d0da23f6b6ab704633a867316702f..162acb9fbf0865f953a97f7dc0c6f28760b3b0f3 100644 (file)
@@ -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)
index 60cbeb817a1bec070cdafdecae6c1c422e6c5c81..c32949ae1952e721b4fea5fccd4866dc9b1a9a5e 100644 (file)
@@ -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 (file)
index 0000000..abbc336
--- /dev/null
@@ -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)