new js api
[org.ibex.core.git] / src / org / ibex / js / JSArray.java
index 168bab3..d9ffad1 100644 (file)
@@ -11,7 +11,7 @@ public class JSArray extends JS.BT {
     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,72 +21,73 @@ public class JSArray extends JS.BT {
         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)
-        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);
+    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
         }
-        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);
     }
         
-    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)
-        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
+        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
+        }
         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);
@@ -95,8 +96,16 @@ public class JSArray extends JS.BT {
                 insertElementAt(val,i);
             }
         }
+        if(isString(key)) {
+            if (JS.toString(key).equals("length")) {
+                setSize(JS.toInt(val));
+                return;
+            }
+        }
+        super.put(key,val);
     }
 
+    // FIXME: Needs to include super's keys
     public Enumeration keys() {
         return new Enumeration() {
                 private int n = size();
@@ -116,56 +125,55 @@ public class JSArray extends JS.BT {
     }
     
     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);
+        JS o = (JS) getNode(i);
         return o == NULL ? null : 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);
+        JS o = (JS) deleteNode(i);
         return o == NULL ? null : 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;
@@ -181,23 +189,25 @@ public class JSArray extends JS.BT {
     
     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) {
+                // FIXME: See emca about this
+                throw new RuntimeException(e.toString());
+            }
         }
     };
-    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());
+                        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());
                     }
                 }
             });
@@ -208,7 +218,7 @@ public class JSArray extends JS.BT {
         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 +268,5 @@ public class JSArray extends JS.BT {
         }
     }
     
-    public String toString() { return JS.toString(join(",")); }
+    String coerceToString() throws JSExn { return JS.toString(join(",")); }
 }