import java.io.*;
import java.util.*;
+// FIXME: could use some cleaning up...
+
/** A JavaScript Array */
class ArrayImpl extends JS.Obj {
private Vec vec = new Vec();
public ArrayImpl() { }
public ArrayImpl(int size) { vec.setSize(size); }
private static int intVal(Object o) {
- if (o instanceof Number) {
- int intVal = ((Number)o).intValue();
- if (intVal == ((Number)o).doubleValue()) return intVal;
- return Integer.MIN_VALUE;
- }
- if (!(o instanceof String)) return Integer.MIN_VALUE;
- 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);
+ if (o instanceof Number) {
+ int intVal = ((Number)o).intValue();
+ if (intVal == ((Number)o).doubleValue()) return intVal;
+ return Integer.MIN_VALUE;
+ }
+ if (!(o instanceof String)) return Integer.MIN_VALUE;
+ 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 get(Object key) throws JS.Exn {
- // FIXME: HACK!
- if (key.equals("cascade")) return org.xwt.Trap.cascadeFunction;
- if (key.equals("trapee")) return org.xwt.Trap.currentTrapee();
- if (key.equals("length")) return new Long(vec.size());
- int i = intVal(key);
- if (i == Integer.MIN_VALUE) return super.get(key);
- try {
- return vec.elementAt(i);
- } catch (ArrayIndexOutOfBoundsException e) {
- return null;
- }
+ // we use _get instead of get solely to work around a GCJ bug
+ public Object _get(Object key) throws JS.Exn {
+ if (key.equals("length")) return new Long(vec.size());
+ if (key.equals("push")) return new JS.Callable() {
+ public Object call(JS.Array args) {
+ for(int i=0;i<args.length();i++)
+ vec.push(args.elementAt(i));
+ return new Long(vec.size());
+ }
+ };
+ if (key.equals("pop")) return new JS.Callable() {
+ public Object call(JS.Array args) {
+ return vec.pop(); // this'll return null on size()==0
+ }
+ };
+
+ int i = intVal(key);
+ if (i == Integer.MIN_VALUE) return super.get(key);
+ try {
+ return vec.elementAt(i);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ return null;
+ }
}
- public void put(Object key, Object val) {
- if (key.equals("length")) vec.setSize(toNumber(val).intValue());
- int i = intVal(key);
- if (i == Integer.MIN_VALUE) super.put(key, val);
- else {
- if (i >= vec.size()) vec.setSize(i+1);
- vec.setElementAt(val, i);
- }
+ // we use _put instead of put solely to work around a GCJ bug
+ public void _put(Object key, Object val) {
+ if (key.equals("length")) vec.setSize(toNumber(val).intValue());
+ int i = intVal(key);
+ if (i == Integer.MIN_VALUE) super.put(key, val);
+ else {
+ if (i >= vec.size()) vec.setSize(i+1);
+ vec.setElementAt(val, i);
+ }
}
public Object[] keys() {
- Object[] sup = super.keys();
- Object[] ret = new Object[vec.size() + 1 + sup.length];
- System.arraycopy(sup, 0, ret, vec.size(), sup.length);
- for(int i=0; i<vec.size(); i++) ret[i] = new Integer(i);
- ret[vec.size()] = "length";
- return ret;
+ Object[] sup = super.keys();
+ Object[] ret = new Object[vec.size() + 1 + sup.length];
+ System.arraycopy(sup, 0, ret, vec.size(), sup.length);
+ for(int i=0; i<vec.size(); i++) ret[i] = new Integer(i);
+ ret[vec.size()] = "length";
+ return ret;
}
public void setSize(int i) { vec.setSize(i); }
public int length() { return vec.size(); }
public Object elementAt(int i) { return vec.elementAt(i); }
public void addElement(Object o) { vec.addElement(o); }
public void setElementAt(Object o, int i) { vec.setElementAt(o, i); }
+
+ public String typeName() { return "array"; }
}