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;
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);
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() {
- 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++);
}
};
}
}
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;
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));
}
}
- public String toString() { return JS.toString(join(",")); }
+ String coerceToString() throws JSExn { return JS.toString(join(",")); }
}