001: /*
002: * AbstractVector.java
003: *
004: * Copyright (C) 2003 Peter Graves
005: *
006: * This program is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU General Public License
008: * as published by the Free Software Foundation; either version 2
009: * of the License, or (at your option) any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
019: */
020:
021: package org.armedbear.lisp;
022:
023: public abstract class AbstractVector extends AbstractArray {
024: protected int fillPointer = -1; // -1 indicates no fill pointer.
025:
026: public LispObject typep(LispObject type) throws ConditionThrowable {
027: if (type == Symbol.VECTOR)
028: return T;
029: if (type == BuiltInClass.VECTOR)
030: return T;
031: if (type == Symbol.SEQUENCE)
032: return T;
033: if (type == BuiltInClass.SEQUENCE)
034: return T;
035: if (type == Symbol.SIMPLE_VECTOR)
036: return isSimpleVector() ? T : NIL;
037: if (type == Symbol.SIMPLE_ARRAY)
038: return fillPointer < 0 ? T : NIL;
039: return super .typep(type);
040: }
041:
042: public final boolean vectorp() {
043: return true;
044: }
045:
046: public boolean equalp(LispObject obj) throws ConditionThrowable {
047: if (obj instanceof AbstractVector) {
048: if (length() != obj.length())
049: return false;
050: AbstractVector v = (AbstractVector) obj;
051: for (int i = length(); i-- > 0;)
052: if (!get(i).equalp(v.get(i)))
053: return false;
054: return true;
055: }
056: return false;
057: }
058:
059: public int getRank() {
060: return 1;
061: }
062:
063: public final LispObject getDimensions() {
064: return new Cons(new Fixnum(capacity()));
065: }
066:
067: public final int getDimension(int n) throws ConditionThrowable {
068: if (n != 0)
069: throw new ConditionThrowable(new TypeError(
070: "bad dimension for vector"));
071: return capacity();
072: }
073:
074: public final int getTotalSize() {
075: return capacity();
076: }
077:
078: public abstract int capacity();
079:
080: public abstract void ensureCapacity(int minCapacity);
081:
082: public abstract LispObject get(int index) throws ConditionThrowable;
083:
084: public abstract void set(int index, LispObject newValue)
085: throws ConditionThrowable;
086:
087: public abstract LispObject subseq(int start, int end)
088: throws ConditionThrowable;
089:
090: public abstract void fill(LispObject obj) throws ConditionThrowable;
091:
092: public abstract void shrink(int n) throws ConditionThrowable;
093:
094: public int checkIndex(int index) throws ConditionThrowable {
095: if (index < 0 || index >= capacity())
096: badIndex(index, capacity());
097: return index;
098: }
099:
100: public int checkIndex(LispObject index) throws ConditionThrowable {
101: int i = Fixnum.getValue(index);
102: if (i < 0 || i >= capacity())
103: badIndex(i, capacity());
104: return i;
105: }
106:
107: protected void badIndex(int index, int limit)
108: throws ConditionThrowable {
109: StringBuffer sb = new StringBuffer("invalid array index ");
110: sb.append(index);
111: sb.append(" for ");
112: sb.append(toString());
113: if (limit > 0) {
114: sb.append(" (should be >= 0 and < ");
115: sb.append(limit);
116: sb.append(')');
117: }
118: throw new ConditionThrowable(new TypeError(sb.toString()));
119: }
120:
121: public int getFillPointer() {
122: return fillPointer;
123: }
124:
125: public void setFillPointer(int n) {
126: fillPointer = n;
127: }
128:
129: public void setFillPointer(LispObject obj)
130: throws ConditionThrowable {
131: if (obj == T)
132: fillPointer = capacity();
133: else {
134: int n = Fixnum.getValue(obj);
135: if (n > capacity()) {
136: StringBuffer sb = new StringBuffer(
137: "the new fill pointer (");
138: sb.append(n);
139: sb.append(") exceeds the capacity of the vector (");
140: sb.append(capacity());
141: sb.append(")");
142: throw new ConditionThrowable(new LispError(sb
143: .toString()));
144: }
145: if (n < 0) {
146: StringBuffer sb = new StringBuffer(
147: "the new fill pointer (");
148: sb.append(n);
149: sb.append(") is negative");
150: throw new ConditionThrowable(new LispError(sb
151: .toString()));
152: }
153: fillPointer = n;
154: }
155: }
156:
157: public boolean isSimpleVector() {
158: return false;
159: }
160:
161: public abstract LispObject reverse() throws ConditionThrowable;
162:
163: public LispObject nreverse() throws ConditionThrowable {
164: int i = 0;
165: int j = length() - 1;
166: while (i < j) {
167: LispObject temp = get(i);
168: set(i, get(j));
169: set(j, temp);
170: ++i;
171: --j;
172: }
173: return this;
174: }
175: }
|