renamed Script to JSU
[org.ibex.js.git] / src / org / ibex / js / JSArray.java
index 5d6738e..8e2fdd2 100644 (file)
@@ -5,12 +5,10 @@
 package org.ibex.js; 
 
 import java.io.InputStream;
-import java.util.*;
 import org.ibex.util.*; 
-import org.ibex.util.Collections;
 
 /** A JavaScript JSArray */
-class JSArray extends ArrayList implements JS, Comparator {
+class JSArray extends Basket.Array implements JS, Basket.CompareFunc {
     private static final JS.Method METHOD = new JS.Method();
     private static final String[] empty = new String[0];
 
@@ -20,10 +18,16 @@ class JSArray extends ArrayList implements JS, Comparator {
     JSArray(JS arg) { super(1); add(arg); }
 
     public JS unclone() { return this; }
-    public JS.Enumeration keys() throws JSExn { return new Enumeration.RandomAccessList(null, this); }
+    public JS.Enumeration keys() throws JSExn {
+        return new Enumeration(null) {
+            private int n = 0;
+            public boolean _hasNext() { return n < size(); }
+            public JS _next() { return JSU.N(n++); }
+        };
+    }
     public JS get(JS key) throws JSExn {
         if (key == null || !(key instanceof JSNumber.I)) {
-            //#switch(Script.str(key))
+            //#switch(JSU.str(key))
             case "pop": return METHOD;
             case "reverse": return METHOD;
             case "toString": return METHOD;
@@ -34,20 +38,20 @@ class JSArray extends ArrayList implements JS, Comparator {
             case "push": return METHOD;
             case "unshift": return METHOD;
             case "splice": return METHOD;
-            case "length": return Script.N(size());
+            case "length": return JSU.N(size());
             //#end
-            throw new JSExn("arrays only support positive integer keys, can not use: "+Script.str(key));
+            throw new JSExn("arrays only support positive integer keys, can not use: "+JSU.str(key));
         }
         return (JS)get(((JSNumber.I)key).toInt());
     }
     public void put(JS key, JS val) throws JSExn {
-        if (Script.str(key).equals("length")) { setSize(Script.toInt(val)); }
+        if (JSU.str(key).equals("length")) { setSize(JSU.toInt(val)); }
 
         if (key == null || !(key instanceof JSNumber.I)) throw new JSExn(
-            "arrays only support positive integer keys, can not use: "+Script.str(key));
+            "arrays only support positive integer keys, can not use: "+JSU.str(key));
         int i = ((JSNumber.I)key).toInt();
         if (i < 0) throw new JSExn("arrays can not use negative integer keys "+i);
-        ensureCapacity(i + 1); while (size() < i) add(null);
+        size(i + 1); while (size() < i) add(null);
         set(i, val);
     }
     public InputStream getInputStream() { return null; }
@@ -65,25 +69,25 @@ class JSArray extends ArrayList implements JS, Comparator {
     public void pause() throws NotPausableException { throw new NotPausableException(); }
     public JS call(JS[] args) throws JSExn { throw new JSExn("can not call an array as a function"); }
     public JS call(JS method, JS[] args) throws JSExn {
-        //#switch(Script.str(method))
+        //#switch(JSU.str(method))
         case "pop": return size() == 0 ? null : (JS)remove(size() - 1);
-        case "push": addAll(args); return Script.N(size());
-        case "reverse": Collections.reverse(this); return this;
+        case "push": addAll(args); return JSU.N(size());
+        case "reverse": reverse(); return this;
         case "toString": return join(",");
         case "shift": return size() == 0 ? null : (JS)remove(0);
-        case "join": return join(args.length == 0 ? "," : Script.str(args[0]));
+        case "join": return join(args.length == 0 ? "," : JSU.str(args[0]));
         case "sort": return sort(args.length == 0 ? null : args[0]);
         case "slice":
-            int start = Script.toInt(args.length < 1 ? null : args[0]);
-            int end = args.length < 2 ? size() : Script.toInt(args[1]);
+            int start = JSU.toInt(args.length < 1 ? null : args[0]);
+            int end = args.length < 2 ? size() : JSU.toInt(args[1]);
             return slice(start, end);
         case "unshift":
             for (int i=0; i < args.length; i++) add(i, args[i]);
-            return Script.N(size());
+            return JSU.N(size());
         case "splice": return splice(args);
         //#end
 
-        throw new JSExn("arrays have no function: "+Script.str(method));
+        throw new JSExn("arrays have no function: "+JSU.str(method));
     }
 
     public JS putAndTriggerTraps(JS key, JS val) throws JSExn { put(key, val); return val; }
@@ -98,7 +102,7 @@ class JSArray extends ArrayList implements JS, Comparator {
     public void addAll(JS[] entries) { for (int i=0; i < entries.length; i++) add(entries[i]); }
 
     public void setSize(int newSize) {
-        ensureCapacity(newSize);
+        size(newSize);
         for (int i=size(); i < newSize; i++) add(null);
         for (int i=size() - 1; i >= newSize; i--) remove(i);
     }
@@ -108,16 +112,16 @@ class JSArray extends ArrayList implements JS, Comparator {
 
     private JS join(String sep) throws JSExn {
         int length = size();
-        if(length == 0) return JS.S("");
+        if(length == 0) return JSU.S("");
         StringBuffer sb = new StringBuffer(64);
         int i=0;
         while(true) {
             JS o = (JS)get(i);
-            if(o != null) sb.append(Script.toString(o));
+            if(o != null) sb.append(JSU.toString(o));
             if(++i == length) break;
             sb.append(sep);
         }
-        return JS.S(sb.toString());
+        return JSU.S(sb.toString());
     }
  
     private JS slice(int start, int end) {
@@ -136,8 +140,8 @@ class JSArray extends ArrayList implements JS, Comparator {
 
     private JS splice(JS[] args) throws JSExn {
         int oldLength = size();
-        int start = Script.toInt(args.length < 1 ? null : args[0]);
-        int deleteCount = Script.toInt(args.length < 2 ? null : args[1]);
+        int start = JSU.toInt(args.length < 1 ? null : args[0]);
+        int deleteCount = JSU.toInt(args.length < 2 ? null : args[1]);
         int newCount = args.length - 2;
         if(newCount < 0) newCount = 0;
         if(start < 0) start = oldLength+start;
@@ -164,20 +168,27 @@ class JSArray extends ArrayList implements JS, Comparator {
         return ret;
     }
 
+    private static final Basket.CompareFunc defaultSort = new Basket.CompareFunc() {
+        public int compare(Object a, Object b) {
+            try { return JSU.toString((JS)a).compareTo(JSU.toString((JS)b)); }
+            catch (JSExn e) { throw new JSExn.Wrapper(e); }
+        }
+    };
     private JS sort(JS comparator) throws JSExn {
         try {
-            if (comparator == null) Collections.sort(this);
-            else { sort = comparator; Collections.sort(this, this); }
+            if (comparator == null) sort(defaultSort);
+            else { sort = comparator; sort((CompareFunc)this); }
             return this;
-        } catch (JSExn.Wrapper w) { throw w.unwrap(); }
+        } catch (JSExn.Wrapper w) { throw w.unwrap();
+        } finally { sort = null; }
     }
 
     private JS sort = null;
     private final JS[] sortargs = new JS[2];
-    public int compare(java.lang.Object a, java.lang.Object b) throws JSExn.Wrapper {
+    public int compare(Object a, Object b) throws JSExn.Wrapper {
         try {
             sortargs[0] = (JS)a; sortargs[1] = (JS)b;
-            return Script.toInt(sort.call(sortargs));
+            return JSU.toInt(sort.call(sortargs));
         } catch (JSExn e) { throw new JSExn.Wrapper(e);
         } finally { sortargs[0] = null; sortargs[1] = null; }
     }