KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > armedbear > lisp > SimpleVector


1 /*
2  * SimpleVector.java
3  *
4  * Copyright (C) 2002-2004 Peter Graves
5  * $Id: SimpleVector.java,v 1.14 2004/07/14 17:01:10 piso Exp $
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */

21
22 package org.armedbear.lisp;
23
24 // "The type of a vector that is not displaced to another array, has no fill
25
// pointer, is not expressly adjustable and is able to hold elements of any
26
// type is a subtype of type SIMPLE-VECTOR."
27
public final class SimpleVector extends AbstractVector
28 {
29     private int capacity;
30     private LispObject[] elements;
31
32     public SimpleVector(int capacity)
33     {
34         elements = new LispObject[capacity];
35         for (int i = capacity; i-- > 0;)
36             elements[i] = NIL;
37         this.capacity = capacity;
38     }
39
40     public SimpleVector(LispObject list) throws ConditionThrowable
41     {
42         elements = list.copyToArray();
43         capacity = elements.length;
44     }
45
46     public SimpleVector(LispObject[] array)
47     {
48         elements = array;
49         capacity = array.length;
50     }
51
52     public LispObject typeOf()
53     {
54         return list2(Symbol.SIMPLE_VECTOR, new Fixnum(capacity));
55     }
56
57     public LispClass classOf()
58     {
59         return BuiltInClass.SIMPLE_VECTOR;
60     }
61
62     public LispObject getDescription()
63     {
64         StringBuffer JavaDoc sb = new StringBuffer JavaDoc("A simple vector with ");
65         sb.append(capacity);
66         sb.append(" elements");
67         return new SimpleString(sb);
68     }
69
70     public LispObject typep(LispObject type) throws ConditionThrowable
71     {
72         if (type == Symbol.SIMPLE_VECTOR)
73             return T;
74         if (type == Symbol.SIMPLE_ARRAY)
75             return T;
76         if (type == BuiltInClass.SIMPLE_VECTOR)
77             return T;
78         if (type == BuiltInClass.SIMPLE_ARRAY)
79             return T;
80         return super.typep(type);
81     }
82
83     public LispObject getElementType()
84     {
85         return T;
86     }
87
88     public boolean isSimpleVector()
89     {
90         return true;
91     }
92
93     public boolean hasFillPointer()
94     {
95         return false;
96     }
97
98     public boolean isAdjustable()
99     {
100         return false;
101     }
102
103     public int capacity()
104     {
105         return capacity;
106     }
107
108     public int length()
109     {
110         return capacity;
111     }
112
113     public LispObject elt(int index) throws ConditionThrowable
114     {
115         try {
116             return elements[index];
117         }
118         catch (ArrayIndexOutOfBoundsException JavaDoc e) {
119             badIndex(index, capacity);
120             return NIL; // Not reached.
121
}
122     }
123
124     // Ignores fill pointer.
125
public LispObject AREF(LispObject index) throws ConditionThrowable
126     {
127         try {
128             return elements[((Fixnum)index).value];
129         }
130         catch (ClassCastException JavaDoc e) {
131             return signal(new TypeError(index, Symbol.FIXNUM));
132         }
133         catch (ArrayIndexOutOfBoundsException JavaDoc e) {
134             badIndex(Fixnum.getValue(index), elements.length);
135             return NIL; // Not reached.
136
}
137     }
138
139     public LispObject getRowMajor(int index) throws ConditionThrowable
140     {
141         try {
142             return elements[index];
143         }
144         catch (ArrayIndexOutOfBoundsException JavaDoc e) {
145             badIndex(index, capacity);
146             return NIL; // Not reached.
147
}
148     }
149
150     public void setRowMajor(int index, LispObject newValue) throws ConditionThrowable
151     {
152         try {
153             elements[index] = newValue;
154         }
155         catch (ArrayIndexOutOfBoundsException JavaDoc e) {
156             badIndex(index, capacity);
157         }
158     }
159
160     public LispObject subseq(int start, int end) throws ConditionThrowable
161     {
162         SimpleVector v = new SimpleVector(end - start);
163         int i = start, j = 0;
164         try {
165             while (i < end)
166                 v.elements[j++] = elements[i++];
167             return v;
168         }
169         catch (ArrayIndexOutOfBoundsException JavaDoc e) {
170             return signal(new TypeError("Array index out of bounds: " + i + "."));
171         }
172     }
173
174     public void fill(LispObject obj) throws ConditionThrowable
175     {
176         for (int i = capacity; i-- > 0;)
177             elements[i] = obj;
178     }
179
180     public void shrink(int n) throws ConditionThrowable
181     {
182         if (n < capacity) {
183             LispObject[] newArray = new LispObject[n];
184             System.arraycopy(elements, 0, newArray, 0, n);
185             elements = newArray;
186             capacity = n;
187             return;
188         }
189         if (n == capacity)
190             return;
191         signal(new LispError());
192     }
193
194     public LispObject reverse() throws ConditionThrowable
195     {
196         SimpleVector result = new SimpleVector(capacity);
197         int i, j;
198         for (i = 0, j = capacity - 1; i < capacity; i++, j--)
199             result.elements[i] = elements[j];
200         return result;
201     }
202
203     public LispObject nreverse() throws ConditionThrowable
204     {
205         int i = 0;
206         int j = capacity - 1;
207         while (i < j) {
208             LispObject temp = elements[i];
209             elements[i] = elements[j];
210             elements[j] = temp;
211             ++i;
212             --j;
213         }
214         return this;
215     }
216
217     public AbstractVector adjustVector(int newCapacity,
218                                        LispObject initialElement,
219                                        LispObject initialContents)
220         throws ConditionThrowable
221     {
222         if (initialContents != NIL) {
223             LispObject[] newElements = new LispObject[newCapacity];
224             if (initialContents.listp()) {
225                 LispObject list = initialContents;
226                 for (int i = 0; i < newCapacity; i++) {
227                     newElements[i] = list.car();
228                     list = list.cdr();
229                 }
230             } else if (initialContents.vectorp()) {
231                 for (int i = 0; i < newCapacity; i++)
232                     newElements[i] = initialContents.elt(i);
233             } else
234                 signal(new TypeError(initialContents, Symbol.SEQUENCE));
235             return new SimpleVector(newElements);
236         }
237         if (capacity != newCapacity) {
238             LispObject[] newElements = new LispObject[newCapacity];
239             System.arraycopy(elements, 0, newElements, 0,
240                              Math.min(capacity, newCapacity));
241             for (int i = capacity; i < newCapacity; i++)
242                 newElements[i] = initialElement;
243             return new SimpleVector(newElements);
244         }
245         // No change.
246
return this;
247     }
248
249     public AbstractVector adjustVector(int newCapacity,
250                                        AbstractArray displacedTo,
251                                        int displacement)
252     {
253         return new ComplexVector(newCapacity, displacedTo, displacement);
254     }
255
256     // ### svref
257
// svref simple-vector index => element
258
private static final Primitive2 SVREF =
259         new Primitive2("svref", "simple-vector index")
260     {
261         public LispObject execute(LispObject first, LispObject second)
262             throws ConditionThrowable
263         {
264             try {
265                 return ((SimpleVector)first).elements[((Fixnum)second).value];
266             }
267             catch (ClassCastException JavaDoc e) {
268                 if (first instanceof SimpleVector)
269                     return signal(new TypeError(second, Symbol.FIXNUM));
270                 else
271                     return signal(new TypeError(first, Symbol.SIMPLE_VECTOR));
272             }
273         }
274     };
275
276     // ### %svset
277
// %svset simple-vector index new-value => new-value
278
private static final Primitive3 _SVSET =
279         new Primitive3("%svset", PACKAGE_SYS, false, "simple-vector index new-value")
280     {
281         public LispObject execute(LispObject first, LispObject second,
282                                   LispObject third)
283             throws ConditionThrowable
284         {
285             try {
286                 ((SimpleVector)first).elements[((Fixnum)second).value] = third;
287                 return third;
288             }
289             catch (ClassCastException JavaDoc e) {
290                 if (first instanceof SimpleVector)
291                     return signal(new TypeError(second, Symbol.FIXNUM));
292                 else
293                     return signal(new TypeError(first, Symbol.SIMPLE_VECTOR));
294             }
295             catch (ArrayIndexOutOfBoundsException JavaDoc e) {
296                 int index = ((Fixnum)second).value;
297                 int capacity = ((SimpleVector)first).capacity;
298                 ((SimpleVector)first).badIndex(index, capacity);
299                 // Not reached.
300
return NIL;
301             }
302         }
303     };
304 }
305
Popular Tags