001: /*
002: * SimpleVector.java
003: *
004: * Copyright (C) 2002-2004 Peter Graves
005: * $Id: SimpleVector.java,v 1.14 2004/07/14 17:01:10 piso Exp $
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: */
021:
022: package org.armedbear.lisp;
023:
024: // "The type of a vector that is not displaced to another array, has no fill
025: // pointer, is not expressly adjustable and is able to hold elements of any
026: // type is a subtype of type SIMPLE-VECTOR."
027: public final class SimpleVector extends AbstractVector {
028: private int capacity;
029: private LispObject[] elements;
030:
031: public SimpleVector(int capacity) {
032: elements = new LispObject[capacity];
033: for (int i = capacity; i-- > 0;)
034: elements[i] = NIL;
035: this .capacity = capacity;
036: }
037:
038: public SimpleVector(LispObject list) throws ConditionThrowable {
039: elements = list.copyToArray();
040: capacity = elements.length;
041: }
042:
043: public SimpleVector(LispObject[] array) {
044: elements = array;
045: capacity = array.length;
046: }
047:
048: public LispObject typeOf() {
049: return list2(Symbol.SIMPLE_VECTOR, new Fixnum(capacity));
050: }
051:
052: public LispClass classOf() {
053: return BuiltInClass.SIMPLE_VECTOR;
054: }
055:
056: public LispObject getDescription() {
057: StringBuffer sb = new StringBuffer("A simple vector with ");
058: sb.append(capacity);
059: sb.append(" elements");
060: return new SimpleString(sb);
061: }
062:
063: public LispObject typep(LispObject type) throws ConditionThrowable {
064: if (type == Symbol.SIMPLE_VECTOR)
065: return T;
066: if (type == Symbol.SIMPLE_ARRAY)
067: return T;
068: if (type == BuiltInClass.SIMPLE_VECTOR)
069: return T;
070: if (type == BuiltInClass.SIMPLE_ARRAY)
071: return T;
072: return super .typep(type);
073: }
074:
075: public LispObject getElementType() {
076: return T;
077: }
078:
079: public boolean isSimpleVector() {
080: return true;
081: }
082:
083: public boolean hasFillPointer() {
084: return false;
085: }
086:
087: public boolean isAdjustable() {
088: return false;
089: }
090:
091: public int capacity() {
092: return capacity;
093: }
094:
095: public int length() {
096: return capacity;
097: }
098:
099: public LispObject elt(int index) throws ConditionThrowable {
100: try {
101: return elements[index];
102: } catch (ArrayIndexOutOfBoundsException e) {
103: badIndex(index, capacity);
104: return NIL; // Not reached.
105: }
106: }
107:
108: // Ignores fill pointer.
109: public LispObject AREF(LispObject index) throws ConditionThrowable {
110: try {
111: return elements[((Fixnum) index).value];
112: } catch (ClassCastException e) {
113: return signal(new TypeError(index, Symbol.FIXNUM));
114: } catch (ArrayIndexOutOfBoundsException e) {
115: badIndex(Fixnum.getValue(index), elements.length);
116: return NIL; // Not reached.
117: }
118: }
119:
120: public LispObject getRowMajor(int index) throws ConditionThrowable {
121: try {
122: return elements[index];
123: } catch (ArrayIndexOutOfBoundsException e) {
124: badIndex(index, capacity);
125: return NIL; // Not reached.
126: }
127: }
128:
129: public void setRowMajor(int index, LispObject newValue)
130: throws ConditionThrowable {
131: try {
132: elements[index] = newValue;
133: } catch (ArrayIndexOutOfBoundsException e) {
134: badIndex(index, capacity);
135: }
136: }
137:
138: public LispObject subseq(int start, int end)
139: throws ConditionThrowable {
140: SimpleVector v = new SimpleVector(end - start);
141: int i = start, j = 0;
142: try {
143: while (i < end)
144: v.elements[j++] = elements[i++];
145: return v;
146: } catch (ArrayIndexOutOfBoundsException e) {
147: return signal(new TypeError("Array index out of bounds: "
148: + i + "."));
149: }
150: }
151:
152: public void fill(LispObject obj) throws ConditionThrowable {
153: for (int i = capacity; i-- > 0;)
154: elements[i] = obj;
155: }
156:
157: public void shrink(int n) throws ConditionThrowable {
158: if (n < capacity) {
159: LispObject[] newArray = new LispObject[n];
160: System.arraycopy(elements, 0, newArray, 0, n);
161: elements = newArray;
162: capacity = n;
163: return;
164: }
165: if (n == capacity)
166: return;
167: signal(new LispError());
168: }
169:
170: public LispObject reverse() throws ConditionThrowable {
171: SimpleVector result = new SimpleVector(capacity);
172: int i, j;
173: for (i = 0, j = capacity - 1; i < capacity; i++, j--)
174: result.elements[i] = elements[j];
175: return result;
176: }
177:
178: public LispObject nreverse() throws ConditionThrowable {
179: int i = 0;
180: int j = capacity - 1;
181: while (i < j) {
182: LispObject temp = elements[i];
183: elements[i] = elements[j];
184: elements[j] = temp;
185: ++i;
186: --j;
187: }
188: return this ;
189: }
190:
191: public AbstractVector adjustVector(int newCapacity,
192: LispObject initialElement, LispObject initialContents)
193: throws ConditionThrowable {
194: if (initialContents != NIL) {
195: LispObject[] newElements = new LispObject[newCapacity];
196: if (initialContents.listp()) {
197: LispObject list = initialContents;
198: for (int i = 0; i < newCapacity; i++) {
199: newElements[i] = list.car();
200: list = list.cdr();
201: }
202: } else if (initialContents.vectorp()) {
203: for (int i = 0; i < newCapacity; i++)
204: newElements[i] = initialContents.elt(i);
205: } else
206: signal(new TypeError(initialContents, Symbol.SEQUENCE));
207: return new SimpleVector(newElements);
208: }
209: if (capacity != newCapacity) {
210: LispObject[] newElements = new LispObject[newCapacity];
211: System.arraycopy(elements, 0, newElements, 0, Math.min(
212: capacity, newCapacity));
213: for (int i = capacity; i < newCapacity; i++)
214: newElements[i] = initialElement;
215: return new SimpleVector(newElements);
216: }
217: // No change.
218: return this ;
219: }
220:
221: public AbstractVector adjustVector(int newCapacity,
222: AbstractArray displacedTo, int displacement) {
223: return new ComplexVector(newCapacity, displacedTo, displacement);
224: }
225:
226: // ### svref
227: // svref simple-vector index => element
228: private static final Primitive2 SVREF = new Primitive2("svref",
229: "simple-vector index") {
230: public LispObject execute(LispObject first, LispObject second)
231: throws ConditionThrowable {
232: try {
233: return ((SimpleVector) first).elements[((Fixnum) second).value];
234: } catch (ClassCastException e) {
235: if (first instanceof SimpleVector)
236: return signal(new TypeError(second, Symbol.FIXNUM));
237: else
238: return signal(new TypeError(first,
239: Symbol.SIMPLE_VECTOR));
240: }
241: }
242: };
243:
244: // ### %svset
245: // %svset simple-vector index new-value => new-value
246: private static final Primitive3 _SVSET = new Primitive3("%svset",
247: PACKAGE_SYS, false, "simple-vector index new-value") {
248: public LispObject execute(LispObject first, LispObject second,
249: LispObject third) throws ConditionThrowable {
250: try {
251: ((SimpleVector) first).elements[((Fixnum) second).value] = third;
252: return third;
253: } catch (ClassCastException e) {
254: if (first instanceof SimpleVector)
255: return signal(new TypeError(second, Symbol.FIXNUM));
256: else
257: return signal(new TypeError(first,
258: Symbol.SIMPLE_VECTOR));
259: } catch (ArrayIndexOutOfBoundsException e) {
260: int index = ((Fixnum) second).value;
261: int capacity = ((SimpleVector) first).capacity;
262: ((SimpleVector) first).badIndex(index, capacity);
263: // Not reached.
264: return NIL;
265: }
266: }
267: };
268: }
|