jswitch
[org.ibex.core.git] / src / org / ibex / js / JSArray.java
index bf54947..d0cd550 100644 (file)
@@ -5,13 +5,13 @@ import org.ibex.util.*;
 import java.util.*;
 
 /** A JavaScript JSArray */
-public class JSArray extends JS {
+public class JSArray extends JS.BT {
     private static final Object NULL = new Object();
     
     public JSArray() { }
     public JSArray(int size) { setSize(size); }
     
-    private static int intVal(Object o) {
+    /*private static int intVal(Object o) {
         if (o instanceof Number) {
             int intVal = ((Number)o).intValue();
             if (intVal == ((Number)o).doubleValue()) return intVal;
@@ -21,10 +21,10 @@ public class JSArray extends JS {
         String s = (String)o;
         for(int i=0; i<s.length(); i++) if (s.charAt(i) < '0' || s.charAt(i) > '9') return Integer.MIN_VALUE;
         return Integer.parseInt(s);
-    }
+    }*/
     
-    public Object callMethod(Object method, Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
-        //#switch(method)
+    public JS callMethod(JS method, JS a0, JS a1, JS a2, JS[] rest, int nargs) throws JSExn {
+        //#jswitch(method)
         case "pop": {
             int oldSize = size();
             if(oldSize == 0) return null;
@@ -59,13 +59,13 @@ public class JSArray extends JS {
         return super.callMethod(method, a0, a1, a2, rest, nargs);
     }
         
-    public Object get(Object key) throws JSExn {
-        int i = intVal(key);
-        if (i != Integer.MIN_VALUE) {
+    public JS get(JS key) throws JSExn {
+        if (isInt(key)) {
+            int i = toInt(key);
             if (i < 0 || i >= size()) return null;
             return elementAt(i);
         }
-        //#switch(key)
+        //#jswitch(key)
         case "pop": return METHOD;
         case "reverse": return METHOD;
         case "toString": return METHOD;
@@ -81,12 +81,9 @@ public class JSArray extends JS {
         return super.get(key);
     }
 
-    public void put(Object key, Object val) throws JSExn {
-        if (key.equals("length")) setSize(toInt(val));
-        int i = intVal(key);
-        if (i == Integer.MIN_VALUE)
-            super.put(key, val);
-        else {
+    public void put(JS key, JS val) throws JSExn {
+        if (isInt(key)) {
+            int i = toInt(key);
             int oldSize = size();
             if(i < oldSize) {
                 setElementAt(val,i);
@@ -94,16 +91,23 @@ public class JSArray extends JS {
                 if(i > oldSize) setSize(i);
                 insertElementAt(val,i);
             }
+            return;
+        }
+        if(isString(key)) {
+            if (JS.toString(key).equals("length")) {
+                setSize(JS.toInt(val));
+                return;
+            }
         }
+        super.put(key,val);
     }
 
-    public Enumeration keys() {
-        return new Enumeration() {
-                private int cur = 0;
-                public boolean hasMoreElements() { return cur < size(); }
-                public Object nextElement() {
-                    if (cur >= size()) throw new NoSuchElementException();
-                    return new Integer(cur++);
+    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++);
                 }
             };
     }
@@ -116,56 +120,55 @@ public class JSArray extends JS {
     }
     
     public final int length() { return size(); }
-    public final Object elementAt(int i) { 
+    public final JS elementAt(int i) { 
         if(i < 0 || i >= size()) throw new ArrayIndexOutOfBoundsException(i);
         Object o = getNode(i);
-        return o == NULL ? null : o;
+        return o == NULL ? (JS)null : (JS)o;
     }
-    public final void addElement(Object o) { 
+    public final void addElement(JS o) { 
         insertNode(size(),o==null ? NULL : o);
     }
-    public final void setElementAt(Object o, int i) {
+    public final void setElementAt(JS o, int i) {
         if(i < 0 || i >= size()) throw new ArrayIndexOutOfBoundsException(i);
         replaceNode(i,o==null ? NULL : o);
     }
-    public final void insertElementAt(Object o, int i) {
+    public final void insertElementAt(JS o, int i) {
         if(i < 0 || i > size()) throw new ArrayIndexOutOfBoundsException(i);
         insertNode(i,o==null ? NULL : o);
     }
-    public final Object removeElementAt(int i) {
+    public final JS removeElementAt(int i) {
         if(i < 0 || i >= size()) throw new ArrayIndexOutOfBoundsException(i);
         Object o = deleteNode(i);
-        return o == NULL ? null : o;
+        return o == NULL ? (JS)null : (JS)o;
     }
     
     public final int size() { return treeSize(); }
-    public String typeName() { return "array"; }
-        
-    private Object join(String sep) {
+    
+    private JS join(String sep) throws JSExn {
         int length = size();
-        if(length == 0) return "";
+        if(length == 0) return JS.S("");
         StringBuffer sb = new StringBuffer(64);
         int i=0;
         while(true) {
-            Object o = elementAt(i);
+            JS o = elementAt(i);
             if(o != null) sb.append(JS.toString(o));
             if(++i == length) break;
             sb.append(sep);
         }
-        return sb.toString();
+        return JS.S(sb.toString());
     }
     
     // FEATURE: Implement this more efficiently
-    private Object reverse() {
+    private JS reverse() {
         int size = size();
         if(size < 2) return this;
         Vec vec = toVec();
         clear();
-        for(int i=size-1,j=0;i>=0;i--,j++) insertElementAt(vec.elementAt(i),j);
+        for(int i=size-1,j=0;i>=0;i--,j++) insertElementAt((JS)vec.elementAt(i),j);
         return this;
     }
     
-    private Object slice(int start, int end) {
+    private JS slice(int start, int end) {
         int length = length();
         if(start < 0) start = length+start;
         if(end < 0) end = length+end;
@@ -178,37 +181,37 @@ public class JSArray extends JS {
             a.setElementAt(elementAt(start+i),i);
         return a;
     }
-    
+        
     private static final Vec.CompareFunc defaultSort = new Vec.CompareFunc() {
         public int compare(Object a, Object b) {
-            return JS.toString(a).compareTo(JS.toString(b));
+            try {
+                return JS.toString((JS)a).compareTo(JS.toString((JS)b));
+            } catch(JSExn e) { throw new JSExn.Wrapper(e); }
         }
     };
-    private Object sort(Object tmp) throws JSExn {
+    private JS sort(JS tmp) throws JSExn {
         Vec vec = toVec();
-        if(tmp instanceof JS) {
-            final JSArray funcArgs = new JSArray(2);
-            final JS jsFunc = (JS) tmp;
-            vec.sort(new Vec.CompareFunc() {
-                public int compare(Object a, Object b) {
-                    try {
-                        funcArgs.setElementAt(a,0);
-                        funcArgs.setElementAt(b,1);
-                        return JS.toInt(jsFunc.call(a, b, null, null, 2));
-                    } catch (Exception e) {
-                        // FIXME
-                        throw new JSRuntimeExn(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;
     }
     
-    private Object splice(JSArray args) {
+    private JS splice(JSArray args) throws JSExn {
         int oldLength = length();
         int start = JS.toInt(args.length() < 1 ? null : args.elementAt(0));
         int deleteCount = JS.toInt(args.length() < 2 ? null : args.elementAt(1));
@@ -258,5 +261,5 @@ public class JSArray extends JS {
         }
     }
     
-    public String toString() { return JS.toString(join(",")); }
+    String coerceToString() throws JSExn { return JS.toString(join(",")); }
 }