import java.util.*;
/** A JavaScript JSArray */
-public class JSArray extends JS {
-
+public class JSArray extends JS.O {
private static final Object NULL = new Object();
- private Vec vec = new Vec();
-
+ private final BalancedTree bt = new BalancedTree();
+
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)
+ public JS callMethod(JS method, JS a0, JS a1, JS a2, JS[] rest, int nargs) throws JSExn {
+ //#switch(JS.toString(method))
case "pop": {
int oldSize = size();
if(oldSize == 0) return null;
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)
+ //#switch(JS.toString(key))
case "pop": return METHOD;
case "reverse": return METHOD;
case "toString": return METHOD;
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() {
- 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++);
}
};
}
}
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 = vec.elementAt(i);
- return o == NULL ? null : o;
+ Object o = bt.getNode(i);
+ return o == NULL ? (JS)null : (JS)o;
}
- public final void addElement(Object o) {
- vec.insertElementAt(o==null ? NULL : o, size());
+ public final void addElement(JS o) {
+ bt.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);
- vec.setElementAt(o==null ? NULL : o,i);
+ bt.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);
- vec.insertElementAt(o==null ? NULL : o, i);
+ bt.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 = vec.elementAt(i);
- vec.removeElementAt(i);
- return o == NULL ? null : o;
+ Object o = bt.deleteNode(i);
+ return o == NULL ? (JS)null : (JS)o;
}
- public final int size() { return vec.size(); }
- public String typeName() { return "array"; }
-
- private Object join(String sep) {
+ public final int size() { return bt.treeSize(); }
+
+ 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();
- vec.removeAllElements();
- for(int i=size-1,j=0;i>=0;i--,j++) insertElementAt(vec.elementAt(i),j);
+ bt.clear();
+ 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));
return ret;
}
- public Vec toVec() { return (Vec)vec.clone(); }
- public void setFromVec(Vec vec) { this.vec = (Vec)vec.clone(); }
- public String toString() { return JS.toString(join(",")); }
+ protected Vec toVec() {
+ int count = size();
+ Vec vec = new Vec();
+ vec.setSize(count);
+ for(int i=0;i<count;i++) {
+ Object o = bt.getNode(i);
+ vec.setElementAt(o == NULL ? null : o,i);
+ }
+ return vec;
+ }
+
+ protected void setFromVec(Vec vec) {
+ int count = vec.size();
+ bt.clear();
+ for(int i=0;i<count;i++) {
+ Object o = vec.elementAt(i);
+ bt.insertNode(i,o==null ? NULL : o);
+ }
+ }
+
+ String coerceToString() throws JSExn { return JS.toString(join(",")); }
}