source: trunk/abcl/src/org/armedbear/lisp/BasicVector_UnsignedByte8.java

Last change on this file was 15734, checked in by Mark Evenson, 8 months ago

Implement vector-to-vector REPLACE as a primitive

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 8.3 KB
Line 
1/*
2 * BasicVector_UnsignedByte8.java
3 *
4 * Copyright (C) 2002-2006 Peter Graves
5 * $Id: BasicVector_UnsignedByte8.java 15734 2023-09-01 06:28:20Z mevenson $
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
38// A basic vector is a specialized vector that is not displaced to another
39// array, has no fill pointer, and is not expressly adjustable.
40public final class BasicVector_UnsignedByte8 extends AbstractVector
41{
42  private int capacity;
43  private byte[] elements;
44
45  public BasicVector_UnsignedByte8(int capacity)
46  {
47    elements = new byte[capacity];
48    this.capacity = capacity;
49  }
50
51  public BasicVector_UnsignedByte8(byte[] array)
52  {
53    capacity = array.length;
54    elements = new byte[capacity];
55    System.arraycopy(array, 0, elements, 0, capacity);
56  }
57
58
59  public BasicVector_UnsignedByte8(LispObject[] array)
60  {
61    capacity = array.length;
62    elements = new byte[capacity];
63    for (int i = array.length; i-- > 0;)
64      elements[i] = coerceToJavaByte(array[i]);
65  }
66
67  @Override
68  public LispObject typeOf()
69  {
70    return list(Symbol.SIMPLE_ARRAY, UNSIGNED_BYTE_8, new Cons(Fixnum.getInstance(capacity)));
71  }
72
73  @Override
74  public LispObject classOf()
75  {
76    return BuiltInClass.VECTOR;
77  }
78
79  @Override
80  public LispObject typep(LispObject type)
81  {
82    if (type == Symbol.SIMPLE_ARRAY)
83      return T;
84    if (type == BuiltInClass.SIMPLE_ARRAY)
85      return T;
86    return super.typep(type);
87  }
88
89  @Override
90  public LispObject getElementType()
91  {
92    return UNSIGNED_BYTE_8;
93  }
94
95  @Override
96  public boolean isSimpleVector()
97  {
98    return false;
99  }
100
101  @Override
102  public boolean hasFillPointer()
103  {
104    return false;
105  }
106
107  @Override
108  public boolean isAdjustable()
109  {
110    return false;
111  }
112
113  @Override
114  public int capacity()
115  {
116    return capacity;
117  }
118
119  @Override
120  public int length()
121  {
122    return capacity;
123  }
124
125  @Override
126  public LispObject elt(int index)
127  {
128    try
129      {
130        return coerceFromJavaByte(elements[index]);
131      }
132    catch (ArrayIndexOutOfBoundsException e)
133      {
134        badIndex(index, capacity);
135        return NIL; // Not reached.
136      }
137  }
138
139  @Override
140  public int aref(int index)
141  {
142    try
143      {
144        return (((int)elements[index]) & 0xff);
145      }
146    catch (ArrayIndexOutOfBoundsException e)
147      {
148        badIndex(index, elements.length);
149        // Not reached.
150        return 0;
151      }
152  }
153
154  @Override
155  public LispObject AREF(int index)
156  {
157    try
158      {
159        return coerceFromJavaByte(elements[index]);
160      }
161    catch (ArrayIndexOutOfBoundsException e)
162      {
163        badIndex(index, elements.length);
164        return NIL; // Not reached.
165      }
166  }
167
168  @Override
169  public void aset(int index, int n)
170  {
171    try
172      {
173        elements[index] = (byte) n;
174      }
175    catch (ArrayIndexOutOfBoundsException e)
176      {
177        badIndex(index, capacity);
178      }
179  }
180
181  @Override
182  public void aset(int index, LispObject value)
183  {
184    try
185      {
186        elements[index] = coerceToJavaByte(value);
187      }
188    catch (ArrayIndexOutOfBoundsException e)
189      {
190        badIndex(index, capacity);
191      }
192  }
193
194  @Override
195  public LispObject subseq(int start, int end)
196  {
197    BasicVector_UnsignedByte8 v = new BasicVector_UnsignedByte8(end - start);
198    int i = start, j = 0;
199    try
200      {
201        while (i < end)
202          v.elements[j++] = elements[i++];
203        return v;
204      }
205    catch (ArrayIndexOutOfBoundsException e)
206      {
207        return error(new TypeError("Array index out of bounds: " + i + "."));
208      }
209  }
210
211  @Override
212  public void fill(LispObject obj)
213  {
214    if (!(obj instanceof Fixnum)) {
215      type_error(obj, Symbol.FIXNUM);
216      // Not reached.
217      return;
218    }
219    int n = ((Fixnum) obj).value;
220    if (n < 0 || n > 255) {
221      type_error(obj, UNSIGNED_BYTE_8);
222      // Not reached.
223      return;
224    }
225    for (int i = capacity; i-- > 0;)
226      elements[i] = (byte) n;
227  }
228
229  @Override
230  public void shrink(int n)
231  {
232    if (n < capacity)
233      {
234        byte[] newArray = new byte[n];
235        System.arraycopy(elements, 0, newArray, 0, n);
236        elements = newArray;
237        capacity = n;
238        return;
239      }
240    if (n == capacity)
241      return;
242    error(new LispError());
243  }
244
245  @Override
246  public LispObject reverse()
247  {
248    BasicVector_UnsignedByte8 result = new BasicVector_UnsignedByte8(capacity);
249    int i, j;
250    for (i = 0, j = capacity - 1; i < capacity; i++, j--)
251      result.elements[i] = elements[j];
252    return result;
253  }
254
255  @Override
256  public LispObject nreverse()
257  {
258    int i = 0;
259    int j = capacity - 1;
260    while (i < j)
261      {
262        byte temp = elements[i];
263        elements[i] = elements[j];
264        elements[j] = temp;
265        ++i;
266        --j;
267      }
268    return this;
269  }
270
271  @Override
272  public AbstractVector adjustArray(int newCapacity,
273                                     LispObject initialElement,
274                                     LispObject initialContents)
275
276  {
277    if (initialContents != null)
278      {
279        LispObject[] newElements = new LispObject[newCapacity];
280        if (initialContents.listp())
281          {
282            LispObject list = initialContents;
283            for (int i = 0; i < newCapacity; i++)
284              {
285                newElements[i] = list.car();
286                list = list.cdr();
287              }
288          }
289        else if (initialContents.vectorp())
290          {
291            for (int i = 0; i < newCapacity; i++)
292              newElements[i] = initialContents.elt(i);
293          }
294        else
295          type_error(initialContents, Symbol.SEQUENCE);
296        return new BasicVector_UnsignedByte8(newElements);
297      }
298    if (capacity != newCapacity)
299      {
300        byte[] newElements = new byte[newCapacity];
301        System.arraycopy(elements, 0, newElements, 0,
302                         Math.min(capacity, newCapacity));
303        if (initialElement != null) {
304            byte initValue = (byte)(initialElement.intValue() & 0xFF);
305            for (int i = capacity; i < newCapacity; i++)
306                newElements[i] = initValue;
307        }
308        return new BasicVector_UnsignedByte8(newElements);
309      }
310    // No change.
311    return this;
312  }
313
314  @Override
315  public AbstractVector adjustArray(int newCapacity,
316                                     AbstractArray displacedTo,
317                                     int displacement)
318  {
319    return new ComplexVector(newCapacity, displacedTo, displacement);
320  }
321
322  @Override
323  public AbstractVector replace(AbstractVector source,
324                                int targetStart, int targetEnd,
325                                int sourceStart, int sourceEnd)
326  {
327    if (source instanceof BasicVector_UnsignedByte8) {
328      System.arraycopy(((BasicVector_UnsignedByte8)source).elements, sourceStart,
329                       elements, targetStart,
330                       Math.min(targetEnd - targetStart, sourceEnd - sourceStart));
331      return this;
332    } else {
333      return super.replace(source, targetStart, targetEnd, sourceStart, sourceEnd);
334    }
335  }
336}
Note: See TracBrowser for help on using the repository browser.