local scope vars indexed by number
[org.ibex.core.git] / src / org / ibex / js / JSArray.java
index 305a5de..a9483d0 100644 (file)
@@ -5,8 +5,9 @@ import org.ibex.util.*;
 import java.util.*;
 
 /** A JavaScript JSArray */
-public class JSArray extends JS.BT {
+public class JSArray extends JS.O {
     private static final Object NULL = new Object();
+    private final BalancedTree bt = new BalancedTree();
     
     public JSArray() { }
     public JSArray(int size) { setSize(size); }
@@ -24,40 +25,38 @@ public class JSArray extends JS.BT {
     }*/
     
     public JS callMethod(JS method, JS a0, JS a1, JS a2, JS[] rest, int nargs) throws JSExn {
-        if(isString(method)) {
-            //#switch(JS.toString(method))
-            case "pop": {
-                int oldSize = size();
-                if(oldSize == 0) return null;
-                return removeElementAt(oldSize-1);
-            }
-            case "reverse": return reverse();
-            case "toString": return join(",");
-            case "shift":
-                if(length() == 0) return null;
-                return removeElementAt(0);
-            case "join":
-                return join(nargs == 0 ? "," : JS.toString(a0));
-            case "sort":
-                return sort(nargs < 1 ? null : a0);
-            case "slice":
-                int start = toInt(nargs < 1 ? null : a0);
-                int end = nargs < 2 ? length() : toInt(a1);
-                return slice(start, end);
-            case "push": {
-                int oldSize = size();
-                for(int i=0; i<nargs; i++) insertElementAt(i==0?a0:i==1?a1:i==2?a2:rest[i-3],oldSize+i);
-                return N(oldSize + nargs);
-            }
-            case "unshift":
-                for(int i=0; i<nargs; i++) insertElementAt(i==0?a0:i==1?a1:i==2?a2:rest[i-3],i);
-                return N(size());
-            case "splice":
-                JSArray array = new JSArray();
-                for(int i=0; i<nargs; i++) array.addElement(i==0?a0:i==1?a1:i==2?a2:rest[i-3]);
-                return splice(array);
-            //#end
+        //#jswitch(method)
+        case "pop": {
+            int oldSize = size();
+            if(oldSize == 0) return null;
+            return removeElementAt(oldSize-1);
         }
+        case "reverse": return reverse();
+        case "toString": return join(",");
+        case "shift":
+            if(length() == 0) return null;
+            return removeElementAt(0);
+        case "join":
+            return join(nargs == 0 ? "," : JS.toString(a0));
+        case "sort":
+            return sort(nargs < 1 ? null : a0);
+        case "slice":
+            int start = toInt(nargs < 1 ? null : a0);
+            int end = nargs < 2 ? length() : toInt(a1);
+            return slice(start, end);
+        case "push": {
+            int oldSize = size();
+            for(int i=0; i<nargs; i++) insertElementAt(i==0?a0:i==1?a1:i==2?a2:rest[i-3],oldSize+i);
+            return N(oldSize + nargs);
+        }
+        case "unshift":
+            for(int i=0; i<nargs; i++) insertElementAt(i==0?a0:i==1?a1:i==2?a2:rest[i-3],i);
+            return N(size());
+        case "splice":
+            JSArray array = new JSArray();
+            for(int i=0; i<nargs; i++) array.addElement(i==0?a0:i==1?a1:i==2?a2:rest[i-3]);
+            return splice(array);
+        //#end
         return super.callMethod(method, a0, a1, a2, rest, nargs);
     }
         
@@ -67,21 +66,19 @@ public class JSArray extends JS.BT {
             if (i < 0 || i >= size()) return null;
             return elementAt(i);
         }
-        if(isString(key)) {
-            //#switch(JS.toString(key))
-            case "pop": return METHOD;
-            case "reverse": return METHOD;
-            case "toString": return METHOD;
-            case "shift": return METHOD;
-            case "join": return METHOD;
-            case "sort": return METHOD;
-            case "slice": return METHOD;
-            case "push": return METHOD;
-            case "unshift": return METHOD;
-            case "splice": return METHOD;
-            case "length": return N(size());
-            //#end
-        }
+        //#jswitch(key)
+        case "pop": return METHOD;
+        case "reverse": return METHOD;
+        case "toString": return METHOD;
+        case "shift": return METHOD;
+        case "join": return METHOD;
+        case "sort": return METHOD;
+        case "slice": return METHOD;
+        case "push": return METHOD;
+        case "unshift": return METHOD;
+        case "splice": return METHOD;
+        case "length": return N(size());
+        //#end
         return super.get(key);
     }
 
@@ -95,6 +92,7 @@ public class JSArray extends JS.BT {
                 if(i > oldSize) setSize(i);
                 insertElementAt(val,i);
             }
+            return;
         }
         if(isString(key)) {
             if (JS.toString(key).equals("length")) {
@@ -105,14 +103,12 @@ public class JSArray extends JS.BT {
         super.put(key,val);
     }
 
-    // FIXME: Needs to include super's keys
-    public Enumeration keys() {
-        return new Enumeration() {
-                private int n = size();
-                public boolean hasMoreElements() { return n > 0; }
-                public Object nextElement() {
-                    if(n == 0) throw new NoSuchElementException();
-                    return new Integer(--n);
+    public Enumeration keys() throws JSExn {
+        return new Enumeration(super.keys()) {
+                private int n = 0;
+                public boolean _hasMoreElements() { return n < size(); }
+                public JS _nextElement() {
+                    return n >= size() ? null : JS.N(n++);
                 }
             };
     }
@@ -127,27 +123,27 @@ public class JSArray extends JS.BT {
     public final int length() { return size(); }
     public final JS elementAt(int i) { 
         if(i < 0 || i >= size()) throw new ArrayIndexOutOfBoundsException(i);
-        Object o = getNode(i);
+        Object o = bt.getNode(i);
         return o == NULL ? (JS)null : (JS)o;
     }
     public final void addElement(JS o) { 
-        insertNode(size(),o==null ? NULL : o);
+        bt.insertNode(size(),o==null ? NULL : o);
     }
     public final void setElementAt(JS o, int i) {
         if(i < 0 || i >= size()) throw new ArrayIndexOutOfBoundsException(i);
-        replaceNode(i,o==null ? NULL : o);
+        bt.replaceNode(i,o==null ? NULL : o);
     }
     public final void insertElementAt(JS o, int i) {
         if(i < 0 || i > size()) throw new ArrayIndexOutOfBoundsException(i);
-        insertNode(i,o==null ? NULL : o);
+        bt.insertNode(i,o==null ? NULL : o);
     }
     public final JS removeElementAt(int i) {
         if(i < 0 || i >= size()) throw new ArrayIndexOutOfBoundsException(i);
-        Object o = deleteNode(i);
+        Object o = bt.deleteNode(i);
         return o == NULL ? (JS)null : (JS)o;
     }
     
-    public final int size() { return treeSize(); }
+    public final int size() { return bt.treeSize(); }
     
     private JS join(String sep) throws JSExn {
         int length = size();
@@ -168,7 +164,7 @@ public class JSArray extends JS.BT {
         int size = size();
         if(size < 2) return this;
         Vec vec = toVec();
-        clear();
+        bt.clear();
         for(int i=size-1,j=0;i>=0;i--,j++) insertElementAt((JS)vec.elementAt(i),j);
         return this;
     }
@@ -186,33 +182,31 @@ public class JSArray extends JS.BT {
             a.setElementAt(elementAt(start+i),i);
         return a;
     }
-    
+        
     private static final Vec.CompareFunc defaultSort = new Vec.CompareFunc() {
         public int compare(Object a, Object b) {
             try {
                 return JS.toString((JS)a).compareTo(JS.toString((JS)b));
-            } catch(JSExn e) {
-                // FIXME: See emca about this
-                throw new RuntimeException(e.toString());
-            }
+            } catch(JSExn e) { throw new JSExn.Wrapper(e); }
         }
     };
     private JS sort(JS tmp) throws JSExn {
         Vec vec = toVec();
-        if(tmp instanceof JS) {
-            final JS jsFunc = (JS) tmp;
-            vec.sort(new Vec.CompareFunc() {
-                public int compare(Object a, Object b) {
-                    try {
-                        return JS.toInt(jsFunc.call((JS)a, (JS)b, null, null, 2));
-                    } catch (JSExn e) {
-                        // FIXME: Check ecma to see what we should do here
-                        throw new RuntimeException(e.toString());
+        try {
+            if(tmp instanceof JS) {
+                final JS jsFunc = (JS) tmp;
+                vec.sort(new Vec.CompareFunc() {
+                    public int compare(Object a, Object b) {
+                        try {
+                            return JS.toInt(jsFunc.call((JS)a, (JS)b, null, null, 2));
+                        } catch(JSExn e) { throw new JSExn.Wrapper(e); }
                     }
-                }
-            });
-        } else {
-            vec.sort(defaultSort);
+                });
+            } else {
+                vec.sort(defaultSort);
+            }
+        } catch(JSExn.Wrapper e) {
+            throw e.refill();
         }
         setFromVec(vec);
         return this;
@@ -253,7 +247,7 @@ public class JSArray extends JS.BT {
         Vec vec = new Vec();
         vec.setSize(count);
         for(int i=0;i<count;i++) {
-            Object o = getNode(i);
+            Object o = bt.getNode(i);
             vec.setElementAt(o == NULL ? null : o,i);
         }
         return vec;
@@ -261,10 +255,10 @@ public class JSArray extends JS.BT {
     
     protected void setFromVec(Vec vec) {
         int count = vec.size();
-        clear();
+        bt.clear();
         for(int i=0;i<count;i++) {
             Object o = vec.elementAt(i);
-            insertNode(i,o==null ? NULL : o);
+            bt.insertNode(i,o==null ? NULL : o);
         }
     }