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

Last change on this file was 13440, checked in by ehuelsmann, 13 years ago

Rename writeToString() to printObject() since that's what it's being used for.
Additionally, create princToString() for use in error messages, making the

required replacement where appropriate.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 6.4 KB
Line 
1/*
2 * AbstractBitVector.java
3 *
4 * Copyright (C) 2004-2005 Peter Graves
5 * $Id: AbstractBitVector.java 13440 2011-08-05 21:25:10Z 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
36import static org.armedbear.lisp.Lisp.*;
37
38public abstract class AbstractBitVector extends AbstractVector
39{
40    protected static final int LONG_MASK = 0x3f;
41
42    protected int capacity;
43
44    // For non-displaced bit-vectors.
45    protected long[] bits;
46
47    @Override
48    public LispObject typep(LispObject type)
49    {
50        if (type == Symbol.BIT_VECTOR)
51            return T;
52        if (type == BuiltInClass.BIT_VECTOR)
53            return T;
54        return super.typep(type);
55    }
56
57    @Override
58    public LispObject classOf()
59    {
60        return BuiltInClass.BIT_VECTOR;
61    }
62
63    @Override
64    public final int capacity()
65    {
66        return capacity;
67    }
68
69    @Override
70    public final LispObject getElementType()
71    {
72        return Symbol.BIT;
73    }
74
75    @Override
76    public boolean equal(LispObject obj)
77    {
78        if (this == obj)
79            return true;
80        if (obj instanceof AbstractBitVector) {
81            AbstractBitVector v = (AbstractBitVector) obj;
82            if (length() != v.length())
83                return false;
84            for (int i = length(); i-- > 0;) {
85                if (getBit(i) != v.getBit(i))
86                    return false;
87            }
88            return true;
89        }
90        return false;
91    }
92
93    @Override
94    public boolean equalp(LispObject obj)
95    {
96        if (this == obj)
97            return true;
98        if (obj instanceof AbstractBitVector) {
99            AbstractBitVector v = (AbstractBitVector) obj;
100            if (length() != v.length())
101                return false;
102            for (int i = length(); i-- > 0;) {
103                if (getBit(i) != v.getBit(i))
104                    return false;
105            }
106            return true;
107        }
108        if (obj instanceof AbstractString)
109            return false;
110        if (obj instanceof AbstractVector)
111            return ((AbstractVector)obj).equalp(this);
112        return false;
113    }
114
115    @Override
116    public void fill(LispObject obj)
117    {
118        if (obj instanceof Fixnum) {
119            switch (((Fixnum)obj).value) {
120                case 0:
121                    if (bits != null) {
122                        for (int i = bits.length; i-- > 0;)
123                            bits[i] = 0;
124                    } else {
125                        for (int i = capacity; i-- > 0;)
126                            clearBit(i);
127                    }
128                    return;
129                case 1:
130                    if (bits != null) {
131                        for (int i = bits.length; i-- > 0;)
132                            bits[i] = -1L;
133                    } else {
134                        for (int i = capacity; i-- > 0;)
135                            setBit(i);
136                    }
137                    return;
138            }
139            // Fall through...
140        }
141        error(new TypeError(obj, Symbol.BIT));
142    }
143
144    @Override
145    public LispObject subseq(int start, int end)
146    {
147        SimpleBitVector v = new SimpleBitVector(end - start);
148        int i = start, j = 0;
149        try {
150            while (i < end) {
151                if (getBit(i++) == 0)
152                    v.clearBit(j++);
153                else
154                    v.setBit(j++);
155            }
156            return v;
157        }
158        catch (ArrayIndexOutOfBoundsException e) {
159            return error(new TypeError("Array index out of bounds: " + i + "."));
160        }
161    }
162
163    @Override
164    public int hashCode()
165    {
166        int hashCode = 1;
167        // Consider first 64 bits only.
168        final int limit = Math.min(length(), 64);
169        for (int i = 0; i < limit; i++)
170            hashCode = hashCode * 31 + getBit(i);
171        return hashCode;
172    }
173
174    @Override
175    public String printObject()
176    {
177        final LispThread thread = LispThread.currentThread();
178        final int length = length();
179        if (Symbol.PRINT_READABLY.symbolValue(thread) != NIL ||
180            Symbol.PRINT_ARRAY.symbolValue(thread) != NIL)
181        {
182            StringBuilder sb = new StringBuilder(length + 2);
183            sb.append("#*");
184            for (int i = 0; i < length; i++)
185                sb.append(getBit(i) == 1 ? '1' : '0');
186            return sb.toString();
187        } else {
188            final String str = "(%sBIT-VECTOR %d)";
189            final String pre = (this instanceof SimpleBitVector) ? "SIMPLE-" : "";
190            return unreadableString(String.format(str, pre, length));
191        }
192    }
193
194    @Override
195    public LispObject reverse()
196    {
197        int length = length();
198        SimpleBitVector result = new SimpleBitVector(length);
199        int i, j;
200        for (i = 0, j = length - 1; i < length; i++, j--) {
201            if (getBit(j) == 1)
202                result.setBit(i);
203            else
204                result.clearBit(i);
205        }
206        return result;
207    }
208
209    protected abstract int getBit(int index);
210
211    protected abstract void setBit(int index);
212
213    protected abstract void clearBit(int index);
214}
Note: See TracBrowser for help on using the repository browser.