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

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

Remove 'throws ConditionThrowable?' method annotations:

it's an unchecked exception now, so no need to declare it thrown.

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