source: branches/0.19.x/abcl/src/org/armedbear/lisp/SimpleVector.java

Last change on this file was 12513, checked in by ehuelsmann, 15 years ago

Remove 'private' keyword to eliminate the Java requirement

for the compiler to generate synthetic accessors: functions that
don't appear in the source but do appear in the class file.

Patch by: Douglas Miles <dmiles _at_ users.sf.net>

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 10.6 KB
Line 
1/*
2 * SimpleVector.java
3 *
4 * Copyright (C) 2002-2007 Peter Graves
5 * $Id: SimpleVector.java 12513 2010-03-02 22:35:36Z 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 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// "The type of a vector that is not displaced to another array, has no fill
39// pointer, is not expressly adjustable and is able to hold elements of any
40// type is a subtype of type SIMPLE-VECTOR."
41public final class SimpleVector extends AbstractVector
42{
43  int capacity;
44  LispObject[] data;
45
46  public SimpleVector(int capacity)
47  {
48    data = new LispObject[capacity];
49    for (int i = capacity; i-- > 0;)
50      data[i] = Fixnum.ZERO;
51    this.capacity = capacity;
52  }
53
54  public SimpleVector(LispObject obj)
55  {
56    if (obj.listp())
57      {
58        data = obj.copyToArray();
59        capacity = data.length;
60      }
61    else if (obj instanceof AbstractVector)
62      {
63        capacity = obj.length();
64        data = new LispObject[capacity];
65        for (int i = 0; i < capacity; i++)
66          data[i] = obj.elt(i);
67      }
68    else
69      Debug.assertTrue(false);
70  }
71
72  public SimpleVector(LispObject[] array)
73  {
74    data = array;
75    capacity = array.length;
76  }
77
78  @Override
79  public LispObject typeOf()
80  {
81    return list(Symbol.SIMPLE_VECTOR, Fixnum.getInstance(capacity));
82  }
83
84  @Override
85  public LispObject classOf()
86  {
87    return BuiltInClass.SIMPLE_VECTOR;
88  }
89
90  @Override
91  public LispObject getDescription()
92  {
93    StringBuffer sb = new StringBuffer("A simple vector with ");
94    sb.append(capacity);
95    sb.append(" elements");
96    return new SimpleString(sb);
97  }
98
99  @Override
100  public LispObject typep(LispObject type)
101  {
102    if (type == Symbol.SIMPLE_VECTOR)
103      return T;
104    if (type == Symbol.SIMPLE_ARRAY)
105      return T;
106    if (type == BuiltInClass.SIMPLE_VECTOR)
107      return T;
108    if (type == BuiltInClass.SIMPLE_ARRAY)
109      return T;
110    return super.typep(type);
111  }
112
113  @Override
114  public LispObject getElementType()
115  {
116    return T;
117  }
118
119  @Override
120  public boolean isSimpleVector()
121  {
122    return true;
123  }
124
125  @Override
126  public boolean hasFillPointer()
127  {
128    return false;
129  }
130
131  @Override
132  public boolean isAdjustable()
133  {
134    return false;
135  }
136
137  @Override
138  public int capacity()
139  {
140    return capacity;
141  }
142
143  @Override
144  public int length()
145  {
146    return capacity;
147  }
148
149  @Override
150  public LispObject elt(int index)
151  {
152    try
153      {
154        return data[index];
155      }
156    catch (ArrayIndexOutOfBoundsException e)
157      {
158        badIndex(index, capacity);
159        return NIL; // Not reached.
160      }
161  }
162
163  @Override
164  public LispObject AREF(int index)
165  {
166    try
167      {
168        return data[index];
169      }
170    catch (ArrayIndexOutOfBoundsException e)
171      {
172        badIndex(index, data.length);
173        return NIL; // Not reached.
174      }
175  }
176
177  @Override
178  public LispObject AREF(LispObject index)
179  {
180        int idx = Fixnum.getValue(index);
181    try
182      {
183        return data[idx];
184      }
185    catch (ArrayIndexOutOfBoundsException e)
186      {
187        badIndex(idx, data.length);
188        return NIL; // Not reached.
189      }
190  }
191
192  @Override
193  public void aset(int index, LispObject newValue)
194  {
195    try
196      {
197        data[index] = newValue;
198      }
199    catch (ArrayIndexOutOfBoundsException e)
200      {
201        badIndex(index, capacity);
202      }
203  }
204
205  @Override
206  public LispObject SVREF(int index)
207  {
208    try
209      {
210        return data[index];
211      }
212    catch (ArrayIndexOutOfBoundsException e)
213      {
214        badIndex(index, data.length);
215        return NIL; // Not reached.
216      }
217  }
218
219  @Override
220  public void svset(int index, LispObject newValue)
221  {
222    try
223      {
224        data[index] = newValue;
225      }
226    catch (ArrayIndexOutOfBoundsException e)
227      {
228        badIndex(index, capacity);
229      }
230  }
231
232  @Override
233  public LispObject subseq(int start, int end)
234  {
235    SimpleVector v = new SimpleVector(end - start);
236    int i = start, j = 0;
237    try
238      {
239        while (i < end)
240          v.data[j++] = data[i++];
241        return v;
242      }
243    catch (ArrayIndexOutOfBoundsException e)
244      {
245        return error(new TypeError("Array index out of bounds: " + i + "."));
246      }
247  }
248
249  @Override
250  public void fill(LispObject obj)
251  {
252    for (int i = capacity; i-- > 0;)
253      data[i] = obj;
254  }
255
256  @Override
257  public LispObject deleteEq(LispObject item)
258  {
259    final int limit = capacity;
260    int i = 0;
261    int j = 0;
262    while (i < limit)
263      {
264        LispObject obj = data[i++];
265        if (obj != item)
266          data[j++] = obj;
267      }
268    if (j < limit)
269      shrink(j);
270    return this;
271  }
272
273  @Override
274  public LispObject deleteEql(LispObject item)
275  {
276    final int limit = capacity;
277    int i = 0;
278    int j = 0;
279    while (i < limit)
280      {
281        LispObject obj = data[i++];
282        if (!obj.eql(item))
283          data[j++] = obj;
284      }
285    if (j < limit)
286      shrink(j);
287    return this;
288  }
289
290  @Override
291  public void shrink(int n)
292  {
293    if (n < capacity)
294      {
295        LispObject[] newData = new LispObject[n];
296        System.arraycopy(data, 0, newData, 0, n);
297        data = newData;
298        capacity = n;
299        return;
300      }
301    if (n == capacity)
302      return;
303    error(new LispError());
304  }
305
306  @Override
307  public LispObject reverse()
308  {
309    SimpleVector result = new SimpleVector(capacity);
310    int i, j;
311    for (i = 0, j = capacity - 1; i < capacity; i++, j--)
312      result.data[i] = data[j];
313    return result;
314  }
315
316  @Override
317  public LispObject nreverse()
318  {
319    int i = 0;
320    int j = capacity - 1;
321    while (i < j)
322      {
323        LispObject temp = data[i];
324        data[i] = data[j];
325        data[j] = temp;
326        ++i;
327        --j;
328      }
329    return this;
330  }
331
332  @Override
333  public AbstractVector adjustArray(int newCapacity,
334                                     LispObject initialElement,
335                                     LispObject initialContents)
336
337  {
338    if (initialContents != null)
339      {
340        LispObject[] newData = new LispObject[newCapacity];
341        if (initialContents.listp())
342          {
343            LispObject list = initialContents;
344            for (int i = 0; i < newCapacity; i++)
345              {
346                newData[i] = list.car();
347                list = list.cdr();
348              }
349          }
350        else if (initialContents.vectorp())
351          {
352            for (int i = 0; i < newCapacity; i++)
353              newData[i] = initialContents.elt(i);
354          }
355        else
356          error(new TypeError(initialContents, Symbol.SEQUENCE));
357        return new SimpleVector(newData);
358      }
359    if (capacity != newCapacity)
360      {
361        LispObject[] newData = new LispObject[newCapacity];
362        System.arraycopy(data, 0, newData, 0,
363                         Math.min(capacity, newCapacity));
364        if (initialElement != null)
365            for (int i = capacity; i < newCapacity; i++)
366                newData[i] = initialElement;
367        return new SimpleVector(newData);
368      }
369    // No change.
370    return this;
371  }
372
373  @Override
374  public AbstractVector adjustArray(int newCapacity,
375                                     AbstractArray displacedTo,
376                                     int displacement)
377  {
378    return new ComplexVector(newCapacity, displacedTo, displacement);
379  }
380
381  // ### svref
382  // svref simple-vector index => element
383  private static final Primitive SVREF =
384    new Primitive("svref", "simple-vector index")
385    {
386      @Override
387      public LispObject execute(LispObject first, LispObject second)
388
389      {
390                        if (first instanceof SimpleVector) {
391                                final SimpleVector sv = (SimpleVector)first;
392                    int index = Fixnum.getValue(second);
393                                try {
394                                        return sv.data[index];
395                                } catch (ArrayIndexOutOfBoundsException e) {
396                                        int capacity = sv.capacity;
397                                         sv.badIndex(index, capacity);
398                                        // Not reached.
399                                        return NIL;
400                                }
401                        }
402                        return type_error(first, Symbol.SIMPLE_VECTOR);
403                }
404    };
405
406  // ### svset simple-vector index new-value => new-value
407  private static final Primitive SVSET =
408    new Primitive("svset", PACKAGE_SYS, true, "simple-vector index new-value")
409    {
410      @Override
411      public LispObject execute(LispObject first, LispObject second,
412                                LispObject third)
413
414      {
415                        if (first instanceof SimpleVector) {
416                                final SimpleVector sv = (SimpleVector)first;
417                    int index = Fixnum.getValue(second);
418                                try {
419                                        sv.data[index] = third;
420                                        return third;
421                                } catch (ArrayIndexOutOfBoundsException e) {
422                                        int capacity = sv.capacity;
423                                         sv.badIndex(index, capacity);
424                                        // Not reached.
425                                        return NIL;
426                                }
427                        }
428                        return type_error(first, Symbol.SIMPLE_VECTOR);
429      }
430    };
431}
Note: See TracBrowser for help on using the repository browser.