1 // Copyright 2003 Adam Megacz, see the COPYING file for licensing [GPL]
8 /** A JavaScript JSArray */
9 public class JSArray extends JS {
10 private Vec vec = new Vec();
12 public JSArray(int size) { vec.setSize(size); }
13 private static int intVal(Object o) {
14 if (o instanceof Number) {
15 int intVal = ((Number)o).intValue();
16 if (intVal == ((Number)o).doubleValue()) return intVal;
17 return Integer.MIN_VALUE;
19 if (!(o instanceof String)) return Integer.MIN_VALUE;
21 for(int i=0; i<s.length(); i++) if (s.charAt(i) < '0' || s.charAt(i) > '9') return Integer.MIN_VALUE;
22 return Integer.parseInt(s);
25 public Object callMethod(Object method, Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
27 case "pop": return vec.pop();
28 case "reverse": return reverse();
29 case "toString": return join(",");
31 if(length() == 0) return null;
32 Object o = vec.elementAt(0);
33 vec.removeElementAt(0);
36 return join(nargs == 0 ? "," : JS.toString(a0));
38 return sort(nargs < 1 ? null : a0);
40 int start = toInt(nargs < 1 ? null : a0);
41 int end = nargs < 2 ? length() : toInt(a1);
42 return slice(start, end);
44 for(int i=0; i<nargs; i++) vec.push(i==0?a0:i==1?a1:i==2?a2:rest[i-3]);
47 for(int i=0; i<nargs; i++) vec.insertElementAt(i==0?a0:i==1?a1:i==2?a2:rest[i-3], i);
50 JSArray array = new JSArray();
51 for(int i=0; i<nargs; i++) array.addElement(i==0?a0:i==1?a1:i==2?a2:rest[i-3]);
54 return super.callMethod(method, a0, a1, a2, rest, nargs);
57 public Object get(Object key) throws JSExn {
58 if (key instanceof Number) {
60 if (i == Integer.MIN_VALUE) return super.get(key);
62 return vec.elementAt(i);
63 } catch (ArrayIndexOutOfBoundsException e) {
68 case "pop": return METHOD;
69 case "reverse": return METHOD;
70 case "toString": return METHOD;
71 case "shift": return METHOD;
72 case "join": return METHOD;
73 case "sort": return METHOD;
74 case "slice": return METHOD;
75 case "push": return METHOD;
76 case "unshift": return METHOD;
77 case "splice": return METHOD;
78 case "length": return N(vec.size());
80 return super.get(key);
83 public void put(Object key, Object val) throws JSExn {
84 if (key.equals("length")) vec.setSize(toNumber(val).intValue());
86 if (i == Integer.MIN_VALUE) super.put(key, val);
88 if (i >= vec.size()) vec.setSize(i+1);
89 vec.setElementAt(val, i);
93 public Enumeration keys() {
94 return new Enumeration() {
96 public boolean hasMoreElements() { return cur >= vec.size(); }
97 public Object nextElement() {
98 if (cur >= vec.size()) throw new NoSuchElementException();
99 return new Integer(cur++);
104 public void setSize(int i) { vec.setSize(i); }
105 public int length() { return vec.size(); }
106 public Object elementAt(int i) { return vec.elementAt(i); }
107 public void addElement(Object o) { vec.addElement(o); }
108 public void setElementAt(Object o, int i) { vec.setElementAt(o, i); }
109 public int size() { return vec.size(); }
110 public String typeName() { return "array"; }
112 private Object join(String sep) {
113 int length = vec.size();
114 if(length == 0) return "";
115 StringBuffer sb = new StringBuffer(64);
118 Object o = elementAt(i);
119 if(o != null) sb.append(JS.toString(o));
120 if(++i == length) break;
123 return sb.toString();
126 private Object reverse() {
128 int size = oldVec.size();
129 if(size < 2) return this;
131 for(int i=size-1;i>=0;i--) vec.addElement(oldVec.elementAt(i));
135 private Object slice(int start, int end) {
136 int length = length();
137 if(start < 0) start = length+start;
138 if(end < 0) end = length+end;
139 if(start < 0) start = 0;
141 if(start > length) start = length;
142 if(end > length) end = length;
143 JSArray a = new JSArray(end-start);
144 for(int i=0;i<end-start;i++)
145 a.setElementAt(elementAt(start+i),i);
149 private static final Vec.CompareFunc defaultSort = new Vec.CompareFunc() {
150 public int compare(Object a, Object b) {
151 return JS.toString(a).compareTo(JS.toString(b));
154 private Object sort(Object tmp) throws JSExn {
155 if(tmp instanceof JS) {
156 final JSArray funcArgs = new JSArray(2);
157 final JS jsFunc = (JS) tmp;
158 vec.sort(new Vec.CompareFunc() {
159 public int compare(Object a, Object b) {
161 funcArgs.setElementAt(a,0);
162 funcArgs.setElementAt(b,1);
163 return JS.toInt(jsFunc.call(a, b, null, null, 2));
164 } catch (Exception e) {
166 throw new JSRuntimeExn(e.toString());
171 vec.sort(defaultSort);
176 private Object splice(JSArray args) {
177 int oldLength = length();
178 int start = JS.toInt(args.length() < 1 ? null : args.elementAt(0));
179 int deleteCount = JS.toInt(args.length() < 2 ? null : args.elementAt(1));
180 int newCount = args.length() - 2;
181 if(newCount < 0) newCount = 0;
182 if(start < 0) start = oldLength+start;
183 if(start < 0) start = 0;
184 if(start > oldLength) start = oldLength;
185 if(deleteCount < 0) deleteCount = 0;
186 if(deleteCount > oldLength-start) deleteCount = oldLength-start;
187 int newLength = oldLength - deleteCount + newCount;
188 int lengthChange = newLength - oldLength;
189 JSArray ret = new JSArray(deleteCount);
190 for(int i=0;i<deleteCount;i++)
191 ret.setElementAt(elementAt(start+i),i);
192 if(lengthChange > 0) {
194 for(int i=newLength-1;i>=start+newCount;i--)
195 setElementAt(elementAt(i-lengthChange),i);
196 } else if(lengthChange < 0) {
197 for(int i=start+newCount;i<newLength;i++)
198 setElementAt(elementAt(i-lengthChange),i);
201 for(int i=0;i<newCount;i++)
202 setElementAt(args.elementAt(i+2),start+i);
206 public String coerceToString() { return JS.toString(join(",")); }