001: /*
002: * Vector.java
003: *
004: * Copyright (C) 2002-2003 Peter Graves
005: * $Id: Vector.java,v 1.6 2003/11/15 11:03:32 beedlem 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: public class Vector extends AbstractVector {
025: private LispObject[] elements;
026: private int capacity;
027:
028: public Vector(int capacity) {
029: elements = new LispObject[capacity];
030: for (int i = capacity; i-- > 0;)
031: elements[i] = NIL;
032: this .capacity = capacity;
033: }
034:
035: public Vector(LispObject list) throws ConditionThrowable {
036: elements = list.copyToArray();
037: capacity = elements.length;
038: }
039:
040: public Vector(LispObject[] array) {
041: elements = array;
042: capacity = array.length;
043: }
044:
045: public LispObject typeOf() {
046: return list3(Symbol.VECTOR, T, new Fixnum(capacity));
047: }
048:
049: public LispClass classOf() {
050: return BuiltInClass.VECTOR;
051: }
052:
053: public LispObject getElementType() {
054: return T;
055: }
056:
057: public boolean isSimpleVector() {
058: return fillPointer < 0;
059: }
060:
061: public int capacity() {
062: return capacity;
063: }
064:
065: public final void ensureCapacity(int minCapacity) {
066: if (elements.length < minCapacity) {
067: LispObject[] newArray = new LispObject[minCapacity];
068: System.arraycopy(elements, 0, newArray, 0, elements.length);
069: elements = newArray;
070: capacity = minCapacity;
071: }
072: }
073:
074: public Vector adjustArray(int size) {
075: if (elements.length != size) {
076: LispObject[] newArray = new LispObject[size];
077: System.arraycopy(elements, 0, newArray, 0, Math.min(
078: elements.length, size));
079: elements = newArray;
080: capacity = size;
081: }
082: return this ;
083: }
084:
085: public int length() {
086: return fillPointer >= 0 ? fillPointer : capacity;
087: }
088:
089: public LispObject elt(int index) throws ConditionThrowable {
090: final int limit = length();
091: if (index < 0 || index >= limit)
092: badIndex(index, limit);
093: return elements[index];
094: }
095:
096: // Ignores fill pointer.
097: public LispObject AREF(LispObject index) throws ConditionThrowable {
098: try {
099: return elements[Fixnum.getValue(index)];
100: } catch (ArrayIndexOutOfBoundsException e) {
101: badIndex(Fixnum.getValue(index), elements.length);
102: return NIL; // Not reached.
103: }
104: }
105:
106: public LispObject getRowMajor(int index) throws ConditionThrowable {
107: try {
108: return elements[index];
109: } catch (ArrayIndexOutOfBoundsException e) {
110: badIndex(index, elements.length);
111: return NIL; // Not reached.
112: }
113: }
114:
115: public void setRowMajor(int index, LispObject newValue)
116: throws ConditionThrowable {
117: try {
118: elements[index] = newValue;
119: } catch (ArrayIndexOutOfBoundsException e) {
120: badIndex(index, elements.length);
121: }
122: }
123:
124: public LispObject get(int index) throws ConditionThrowable {
125: try {
126: return elements[index];
127: } catch (ArrayIndexOutOfBoundsException e) {
128: badIndex(index, elements.length);
129: return NIL; // Not reached.
130: }
131: }
132:
133: public void set(int index, LispObject newValue)
134: throws ConditionThrowable {
135: try {
136: elements[index] = newValue;
137: } catch (ArrayIndexOutOfBoundsException e) {
138: badIndex(index, elements.length);
139: }
140: }
141:
142: public LispObject subseq(int start, int end)
143: throws ConditionThrowable {
144: Vector v = new Vector(end - start);
145: int i = start, j = 0;
146: while (i < end)
147: v.elements[j++] = elements[i++];
148: return v;
149: }
150:
151: public void fill(LispObject obj) throws ConditionThrowable {
152: for (int i = capacity; i-- > 0;)
153: elements[i] = obj;
154: }
155:
156: public void shrink(int n) throws ConditionThrowable {
157: if (n < elements.length) {
158: LispObject[] newArray = new LispObject[n];
159: System.arraycopy(elements, 0, newArray, 0, n);
160: elements = newArray;
161: capacity = n;
162: return;
163: }
164: if (n == elements.length)
165: return;
166: throw new ConditionThrowable(new LispError());
167: }
168:
169: public LispObject reverse() throws ConditionThrowable {
170: int length = length();
171: Vector result = new Vector(length);
172: int i, j;
173: for (i = 0, j = length - 1; i < length; 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 = length() - 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 String toString() {
192: StringBuffer sb = new StringBuffer("#(");
193: // FIXME The limit should be based on the value of *PRINT-LENGTH*.
194: final int limit = Math.min(length(), 10);
195: for (int i = 0; i < limit; i++) {
196: if (i > 0)
197: sb.append(' ');
198: sb.append(elements[i]);
199: }
200: if (limit < length())
201: sb.append(" ...");
202: sb.append(')');
203: return sb.toString();
204: }
205: }
|