source: branches/0.17.x/abcl/src/org/armedbear/lisp/AbstractBitVector.java

Last change on this file was 12255, checked in by ehuelsmann, 16 years ago

Rename ConditionThrowable? to ControlTransfer? and remove

try/catch blocks which don't have anything to do with
non-local transfer of control.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 6.5 KB
Line 
1/*
2 * AbstractBitVector.java
3 *
4 * Copyright (C) 2004-2005 Peter Graves
5 * $Id: AbstractBitVector.java 12255 2009-11-06 22:36:32Z ehuelsmann $
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 * As a special exception, the copyright holders of this library give you
22 * permission to link this library with independent modules to produce an
23 * executable, regardless of the license terms of these independent
24 * modules, and to copy and distribute the resulting executable under
25 * terms of your choice, provided that you also meet, for each linked
26 * independent module, the terms and conditions of the license of that
27 * module.  An independent module is a module which is not derived from
28 * or based on this library.  If you modify this library, you may extend
29 * this exception to your version of the library, but you are not
30 * obligated to do so.  If you do not wish to do so, delete this
31 * exception statement from your version.
32 */
33
34package org.armedbear.lisp;
35
36public abstract class AbstractBitVector extends AbstractVector
37{
38    protected static final int LONG_MASK = 0x3f;
39
40    protected int capacity;
41
42    // For non-displaced bit-vectors.
43    protected long[] bits;
44
45    @Override
46    public LispObject typep(LispObject type)
47    {
48        if (type == Symbol.BIT_VECTOR)
49            return T;
50        if (type == BuiltInClass.BIT_VECTOR)
51            return T;
52        return super.typep(type);
53    }
54
55    @Override
56    public LispObject classOf()
57    {
58        return BuiltInClass.BIT_VECTOR;
59    }
60
61    @Override
62    public final int capacity()
63    {
64        return capacity;
65    }
66
67    @Override
68    public final LispObject getElementType()
69    {
70        return Symbol.BIT;
71    }
72
73    @Override
74    public boolean equal(LispObject obj)
75    {
76        if (this == obj)
77            return true;
78        if (obj instanceof AbstractBitVector) {
79            AbstractBitVector v = (AbstractBitVector) obj;
80            if (length() != v.length())
81                return false;
82            for (int i = length(); i-- > 0;) {
83                if (getBit(i) != v.getBit(i))
84                    return false;
85            }
86            return true;
87        }
88        return false;
89    }
90
91    @Override
92    public boolean equalp(LispObject obj)
93    {
94        if (this == obj)
95            return true;
96        if (obj instanceof AbstractBitVector) {
97            AbstractBitVector v = (AbstractBitVector) obj;
98            if (length() != v.length())
99                return false;
100            for (int i = length(); i-- > 0;) {
101                if (getBit(i) != v.getBit(i))
102                    return false;
103            }
104            return true;
105        }
106        if (obj instanceof AbstractString)
107            return false;
108        if (obj instanceof AbstractVector)
109            return ((AbstractVector)obj).equalp(this);
110        return false;
111    }
112
113    @Override
114    public void fill(LispObject obj)
115    {
116        if (obj instanceof Fixnum) {
117            switch (((Fixnum)obj).value) {
118                case 0:
119                    if (bits != null) {
120                        for (int i = bits.length; i-- > 0;)
121                            bits[i] = 0;
122                    } else {
123                        for (int i = capacity; i-- > 0;)
124                            clearBit(i);
125                    }
126                    return;
127                case 1:
128                    if (bits != null) {
129                        for (int i = bits.length; i-- > 0;)
130                            bits[i] = -1L;
131                    } else {
132                        for (int i = capacity; i-- > 0;)
133                            setBit(i);
134                    }
135                    return;
136            }
137            // Fall through...
138        }
139        error(new TypeError(obj, Symbol.BIT));
140    }
141
142    @Override
143    public LispObject subseq(int start, int end)
144    {
145        SimpleBitVector v = new SimpleBitVector(end - start);
146        int i = start, j = 0;
147        try {
148            while (i < end) {
149                if (getBit(i++) == 0)
150                    v.clearBit(j++);
151                else
152                    v.setBit(j++);
153            }
154            return v;
155        }
156        catch (ArrayIndexOutOfBoundsException e) {
157            return error(new TypeError("Array index out of bounds: " + i + "."));
158        }
159    }
160
161    @Override
162    public int hashCode()
163    {
164        int hashCode = 1;
165        // Consider first 64 bits only.
166        final int limit = Math.min(length(), 64);
167        for (int i = 0; i < limit; i++)
168            hashCode = hashCode * 31 + getBit(i);
169        return hashCode;
170    }
171
172    @Override
173    public String writeToString()
174    {
175        final LispThread thread = LispThread.currentThread();
176        final int length = length();
177        if (Symbol.PRINT_READABLY.symbolValue(thread) != NIL ||
178            Symbol.PRINT_ARRAY.symbolValue(thread) != NIL)
179        {
180            StringBuilder sb = new StringBuilder(length + 2);
181            sb.append("#*");
182            for (int i = 0; i < length; i++)
183                sb.append(getBit(i) == 1 ? '1' : '0');
184            return sb.toString();
185        } else {
186            final String str = "(%sBIT-VECTOR %d)";
187            final String pre = (this instanceof SimpleBitVector) ? "SIMPLE-" : "";
188            return unreadableString(String.format(str, pre, length));
189        }
190    }
191
192    // Ignores fill pointer.
193    @Override
194    public LispObject AREF(LispObject index)
195    {
196        return AREF(Fixnum.getValue(index));
197    }
198
199    @Override
200    public LispObject reverse()
201    {
202        int length = length();
203        SimpleBitVector result = new SimpleBitVector(length);
204        int i, j;
205        for (i = 0, j = length - 1; i < length; i++, j--) {
206            if (getBit(j) == 1)
207                result.setBit(i);
208            else
209                result.clearBit(i);
210        }
211        return result;
212    }
213
214    protected abstract int getBit(int index);
215
216    protected abstract void setBit(int index);
217
218    protected abstract void clearBit(int index);
219}
Note: See TracBrowser for help on using the repository browser.