[pypy-svn] r65213 - pypy/branch/js-refactoring/pypy/lang/js

jandem at codespeak.net jandem at codespeak.net
Mon May 11 15:06:49 CEST 2009


Author: jandem
Date: Mon May 11 15:06:47 2009
New Revision: 65213

Modified:
   pypy/branch/js-refactoring/pypy/lang/js/astbuilder.py
   pypy/branch/js-refactoring/pypy/lang/js/interpreter.py
Log:
Add Array.prototype.sort. Two Array tests failures remaining (missing Date and a lexer bug)


Modified: pypy/branch/js-refactoring/pypy/lang/js/astbuilder.py
==============================================================================
--- pypy/branch/js-refactoring/pypy/lang/js/astbuilder.py	(original)
+++ pypy/branch/js-refactoring/pypy/lang/js/astbuilder.py	Mon May 11 15:06:47 2009
@@ -37,7 +37,7 @@
         'in': operations.In,
     }
     UNOP_TO_CLS = {
-        #'~': operations.BitwiseNot,
+        '~': operations.BitwiseNot,
         '!': operations.Not,
         '+': operations.UPlus,
         '-': operations.UMinus,

Modified: pypy/branch/js-refactoring/pypy/lang/js/interpreter.py
==============================================================================
--- pypy/branch/js-refactoring/pypy/lang/js/interpreter.py	(original)
+++ pypy/branch/js-refactoring/pypy/lang/js/interpreter.py	Mon May 11 15:06:47 2009
@@ -13,6 +13,7 @@
 from pypy.lang.js.jscode import JsCode
 from pypy.rlib.rarithmetic import NAN, INFINITY, isnan, isinf, r_uint
 from pypy.rlib.objectmodel import specialize
+from pypy.rlib.listsort import TimSort
 
 ASTBUILDER = ASTBuilder()
 
@@ -522,6 +523,7 @@
     return sep.join(l)
 
 class W_ArrayToString(W_NewBuiltin):
+    length = 0
     def Call(self, ctx, args=[], this=None):
         return W_String(common_join(ctx, this, sep=','))
 
@@ -558,6 +560,70 @@
         
         return this
 
+class Sorter(TimSort):
+    def __init__(self, list, listlength=None, compare_fn=None, ctx=None):
+        TimSort.__init__(self, list, listlength)
+        self.compare_fn = compare_fn
+        self.ctx = ctx
+    
+    def lt(self, a, b):
+        if self.compare_fn:
+            result = self.compare_fn.Call(self.ctx, [a, b]).ToInt32(self.ctx)
+            return result == -1
+        return a.ToString(self.ctx) < b.ToString(self.ctx)
+
+class W_ArraySort(W_NewBuiltin):
+    length = 1
+    #XXX: further optimize this function
+    def Call(self, ctx, args=[], this=None):
+        length = this.Get(ctx, 'length').ToUInt32(ctx)
+        
+        # According to ECMA-262 15.4.4.11, non-existing properties always come after
+        # existing values. Undefined is always greater than any other value.
+        # So we create a list of non-undefined values, sort them, and append undefined again.
+        values = []
+        undefs = r_uint(0)
+        
+        for i in range(length):
+            P = str(i)
+            
+            if not this.HasProperty(P):
+                # non existing property
+                continue
+            
+            obj = this.Get(ctx, str(i))
+            if obj is w_Undefined:
+                undefs += 1
+                continue
+            
+            values.append(obj)
+        
+        # sort all values
+        if len(args) > 0:
+            sorter = Sorter(values, compare_fn=args[0], ctx=ctx)
+        else:
+            sorter = Sorter(values, ctx=ctx)
+        sorter.sort()
+        
+        # put sorted values back
+        values = sorter.list
+        for i in range(len(values)):
+            this.Put(ctx, str(i), values[i])
+        
+        # append undefined values
+        newlength = len(values)
+        while undefs > 0:
+            undefs -= 1
+            this.Put(ctx, str(newlength), w_Undefined)
+            newlength += 1
+        
+        # delete non-existing elements on the end
+        while length > newlength:
+            this.Delete(str(newlength))
+            newlength += 1
+        
+        return this
+
 class W_DateFake(W_NewBuiltin): # XXX This is temporary
     def Call(self, ctx, args=[], this=None):
         return create_object(ctx, 'Object')
@@ -710,6 +776,7 @@
             'toString': W_ArrayToString(ctx),
             'join': W_ArrayJoin(ctx),
             'reverse': W_ArrayReverse(ctx),
+            'sort': W_ArraySort(ctx),
         })
         
         w_Array.Put(ctx, 'prototype', w_ArrPrototype, flags = allon)



More information about the Pypy-commit mailing list