001: /*
002: * SimpleBitVector.java
003: *
004: * Copyright (C) 2004 Peter Graves
005: * $Id: SimpleBitVector.java,v 1.9 2004/03/15 19:29:02 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 bit vector that is not displaced to another array, has no
025: // fill pointer, and is not expressly adjustable is a subtype of type SIMPLE-
026: // BIT-VECTOR."
027: public final class SimpleBitVector extends AbstractBitVector {
028: public SimpleBitVector(int capacity) // throws ConditionThrowable
029: {
030: this .capacity = capacity;
031: int size = capacity >>> 6;
032: if ((capacity & LONG_MASK) != 0)
033: ++size;
034: bits = new long[size];
035: }
036:
037: public SimpleBitVector(String s) throws ConditionThrowable {
038: this (s.length());
039: for (int i = capacity; i-- > 0;) {
040: char c = s.charAt(i);
041: if (c == '0')
042: ;
043: else if (c == '1')
044: setBit(i);
045: else
046: Debug.assertTrue(false);
047: }
048: }
049:
050: public LispObject typeOf() {
051: return list2(Symbol.SIMPLE_BIT_VECTOR, new Fixnum(capacity));
052: }
053:
054: public LispClass classOf() {
055: return BuiltInClass.SIMPLE_BIT_VECTOR;
056: }
057:
058: public LispObject typep(LispObject type) throws ConditionThrowable {
059: if (type == Symbol.SIMPLE_BIT_VECTOR)
060: return T;
061: if (type == Symbol.SIMPLE_ARRAY)
062: return T;
063: if (type == BuiltInClass.SIMPLE_BIT_VECTOR)
064: return T;
065: if (type == BuiltInClass.SIMPLE_ARRAY)
066: return T;
067: return super .typep(type);
068: }
069:
070: public boolean hasFillPointer() {
071: return false;
072: }
073:
074: public boolean isAdjustable() {
075: return false;
076: }
077:
078: public boolean isSimpleVector() {
079: return true;
080: }
081:
082: public int length() {
083: return capacity;
084: }
085:
086: public LispObject elt(int index) throws ConditionThrowable {
087: if (index < 0 || index >= length())
088: badIndex(index, length());
089: int offset = index >> 6;
090: return (bits[offset] & (1L << index)) != 0 ? Fixnum.ONE
091: : Fixnum.ZERO;
092: }
093:
094: public LispObject getRowMajor(int index) throws ConditionThrowable {
095: if (index < 0 || index >= capacity)
096: badIndex(index, capacity);
097: int offset = index >> 6;
098: return (bits[offset] & (1L << index)) != 0 ? Fixnum.ONE
099: : Fixnum.ZERO;
100: }
101:
102: public void setRowMajor(int index, LispObject newValue)
103: throws ConditionThrowable {
104: if (index < 0 || index >= capacity)
105: badIndex(index, capacity);
106: final int offset = index >> 6;
107: try {
108: switch (((Fixnum) newValue).value) {
109: case 0:
110: bits[offset] &= ~(1L << index);
111: return;
112: case 1:
113: bits[offset] |= 1L << index;
114: return;
115: }
116: } catch (ClassCastException e) {
117: // Fall through...
118: }
119: signal(new TypeError(newValue, Symbol.BIT));
120: }
121:
122: protected int getBit(int index) {
123: int offset = index >> 6;
124: return (bits[offset] & (1L << index)) != 0 ? 1 : 0;
125: }
126:
127: protected void setBit(int index) {
128: int offset = index >> 6;
129: bits[offset] |= 1L << index;
130: }
131:
132: protected void clearBit(int index) {
133: int offset = index >> 6;
134: bits[offset] &= ~(1L << index);
135: }
136:
137: public void shrink(int n) throws ConditionThrowable {
138: if (n < capacity) {
139: int size = n >>> 6;
140: if ((n & LONG_MASK) != 0)
141: ++size;
142: if (size < bits.length) {
143: long[] newbits = new long[size];
144: System.arraycopy(bits, 0, newbits, 0, size);
145: bits = newbits;
146: }
147: capacity = n;
148: return;
149: }
150: if (n == capacity)
151: return;
152: signal(new LispError());
153: }
154:
155: public AbstractVector adjustVector(int newCapacity,
156: LispObject initialElement, LispObject initialContents)
157: throws ConditionThrowable {
158: if (initialContents != NIL) {
159: SimpleBitVector v = new SimpleBitVector(newCapacity);
160: if (initialContents.listp()) {
161: LispObject list = initialContents;
162: for (int i = 0; i < newCapacity; i++) {
163: v.setRowMajor(i, list.car());
164: list = list.cdr();
165: }
166: } else if (initialContents.vectorp()) {
167: for (int i = 0; i < newCapacity; i++)
168: v.setRowMajor(i, initialContents.elt(i));
169: } else
170: signal(new TypeError(initialContents, Symbol.SEQUENCE));
171: return v;
172: }
173: if (capacity != newCapacity) {
174: SimpleBitVector v = new SimpleBitVector(newCapacity);
175: final int limit = Math.min(capacity, newCapacity);
176: for (int i = limit; i-- > 0;) {
177: if (getBit(i) == 1)
178: v.setBit(i);
179: else
180: v.clearBit(i);
181: }
182: if (initialElement != NIL && capacity < newCapacity) {
183: int n = Fixnum.getValue(initialElement);
184: if (n == 1)
185: for (int i = capacity; i < newCapacity; i++)
186: v.setBit(i);
187: else
188: for (int i = capacity; i < newCapacity; i++)
189: v.clearBit(i);
190: }
191: return v;
192: }
193: // No change.
194: return this ;
195: }
196:
197: public AbstractVector adjustVector(int newCapacity,
198: AbstractArray displacedTo, int displacement)
199: throws ConditionThrowable {
200: return new ComplexBitVector(newCapacity, displacedTo,
201: displacement);
202: }
203: }
|