source: branches/1.1.x/src/org/armedbear/lisp/AbstractVector.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: 8.3 KB
Line 
1/*
2 * AbstractVector.java
3 *
4 * Copyright (C) 2003-2006 Peter Graves
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 *
20 * As a special exception, the copyright holders of this library give you
21 * permission to link this library with independent modules to produce an
22 * executable, regardless of the license terms of these independent
23 * modules, and to copy and distribute the resulting executable under
24 * terms of your choice, provided that you also meet, for each linked
25 * independent module, the terms and conditions of the license of that
26 * module.  An independent module is a module which is not derived from
27 * or based on this library.  If you modify this library, you may extend
28 * this exception to your version of the library, but you are not
29 * obligated to do so.  If you do not wish to do so, delete this
30 * exception statement from your version.
31 */
32
33package org.armedbear.lisp;
34
35import static org.armedbear.lisp.Lisp.*;
36
37public abstract class AbstractVector extends AbstractArray
38{
39  @Override
40  public LispObject typep(LispObject type)
41  {
42    if (type == Symbol.VECTOR)
43      return T;
44    if (type == BuiltInClass.VECTOR)
45      return T;
46    if (type == Symbol.SEQUENCE)
47      return T;
48    if (type == BuiltInClass.SEQUENCE)
49      return T;
50    return super.typep(type);
51  }
52
53  @Override
54  public final boolean vectorp()
55  {
56    return true;
57  }
58
59  @Override
60  public boolean equalp(LispObject obj)
61  {
62    if (obj instanceof AbstractVector)
63      {
64        if (length() != obj.length())
65          return false;
66        AbstractVector v = (AbstractVector) obj;
67        for (int i = length(); i-- > 0;)
68          if (!AREF(i).equalp(v.AREF(i)))
69            return false;
70        return true;
71      }
72    return false;
73  }
74
75  @Override
76  public final int getRank()
77  {
78    return 1;
79  }
80
81  @Override
82  public final LispObject getDimensions()
83  {
84    return new Cons(Fixnum.getInstance(capacity()));
85  }
86
87  @Override
88  public final int getDimension(int n)
89  {
90    if (n != 0)
91      {
92        error(new TypeError("bad dimension for vector"));
93        // Not reached.
94        return 0;
95      }
96    return capacity();
97  }
98
99  @Override
100  public final int getTotalSize()
101  {
102    return capacity();
103  }
104
105  public abstract int capacity();
106
107  public abstract LispObject subseq(int start, int end);
108
109  public LispObject deleteEq(LispObject item)
110  {
111    final int limit = length();
112    int i = 0;
113    int j = 0;
114    while (i < limit)
115      {
116        LispObject obj = AREF(i++);
117        if (obj != item)
118          aset(j++, obj);
119      }
120    final int newLength = j;
121    if (newLength < capacity())
122      shrink(newLength);
123    return this;
124  }
125
126  public LispObject deleteEql(LispObject item)
127  {
128    final int limit = length();
129    int i = 0;
130    int j = 0;
131    while (i < limit)
132      {
133        LispObject obj = AREF(i++);
134        if (!obj.eql(item))
135          aset(j++, obj);
136      }
137    final int newLength = j;
138    if (newLength < capacity())
139      shrink(newLength);
140    return this;
141  }
142
143  public abstract void shrink(int n);
144
145  public int checkIndex(int index)
146  {
147    if (index < 0 || index >= capacity())
148      badIndex(index, capacity());
149    return index;
150  }
151
152  protected void badIndex(int index, int limit)
153  {
154    StringBuilder sb = new StringBuilder("Invalid array index ");
155    sb.append(index);
156    sb.append(" for ");
157    sb.append(princToString());
158    if (limit > 0)
159      {
160        sb.append(" (should be >= 0 and < ");
161        sb.append(limit);
162        sb.append(").");
163      }
164    error(new TypeError(sb.toString(),
165                         Fixnum.getInstance(index),
166                         list(Symbol.INTEGER,
167                               Fixnum.ZERO,
168                               Fixnum.getInstance(limit - 1))));
169
170  }
171
172  public void setFillPointer(int n)
173  {
174    noFillPointer();
175  }
176
177  public void setFillPointer(LispObject obj)
178  {
179    noFillPointer();
180  }
181
182  public boolean isSimpleVector()
183  {
184    return false;
185  }
186
187  @Override
188  public abstract LispObject reverse();
189
190  @Override
191  public LispObject nreverse()
192  {
193    int i = 0;
194    int j = length() - 1;
195    while (i < j)
196      {
197        LispObject temp = AREF(i);
198        aset(i, AREF(j));
199        aset(j, temp);
200        ++i;
201        --j;
202      }
203    return this;
204  }
205
206  @Override
207  public String printObject()
208  {
209    final LispThread thread = LispThread.currentThread();
210    if (Symbol.PRINT_READABLY.symbolValue(thread) != NIL)
211      {
212        StringBuilder sb = new StringBuilder("#(");
213        final int limit = length();
214        for (int i = 0; i < limit; i++)
215          {
216            if (i > 0)
217              sb.append(' ');
218            sb.append(AREF(i).printObject());
219          }
220        sb.append(')');
221        return sb.toString();
222      }
223    else if (Symbol.PRINT_ARRAY.symbolValue(thread) != NIL)
224      {
225        int maxLevel = Integer.MAX_VALUE;
226        final LispObject printLevel =
227          Symbol.PRINT_LEVEL.symbolValue(thread);
228        if (printLevel instanceof Fixnum)
229          maxLevel = ((Fixnum)printLevel).value;
230        LispObject currentPrintLevel =
231          _CURRENT_PRINT_LEVEL_.symbolValue(thread);
232        int currentLevel = Fixnum.getValue(currentPrintLevel);
233        if (currentLevel < maxLevel)
234          {
235            StringBuffer sb = new StringBuffer("#(");
236            int maxLength = Integer.MAX_VALUE;
237            final LispObject printLength =
238              Symbol.PRINT_LENGTH.symbolValue(thread);
239            if (printLength instanceof Fixnum)
240              maxLength = ((Fixnum)printLength).value;
241            final int length = length();
242            final int limit = Math.min(length, maxLength);
243            final SpecialBindingsMark mark = thread.markSpecialBindings();
244            thread.bindSpecial(_CURRENT_PRINT_LEVEL_, currentPrintLevel.incr());
245            try
246              {
247                for (int i = 0; i < limit; i++)
248                  {
249                    if (i > 0)
250                      sb.append(' ');
251                    sb.append(AREF(i).printObject());
252                  }
253              }
254            finally
255              {
256                thread.resetSpecialBindings(mark);
257              }
258            if (limit < length)
259              sb.append(limit > 0 ? " ..." : "...");
260            sb.append(')');
261            return sb.toString();
262          }
263        else
264          return "#";
265      }
266    else
267      {
268        StringBuffer sb = new StringBuffer();
269        sb.append(isSimpleVector() ? "SIMPLE-VECTOR " : "VECTOR ");
270        sb.append(capacity());
271        return unreadableString(sb.toString());
272      }
273  }
274
275  // For EQUALP hash tables.
276  @Override
277  public int psxhash()
278  {
279    final int length = length();
280    final int limit = length < 4 ? length : 4;
281    long result = 48920713; // Chosen at random.
282    for (int i = 0; i < limit; i++)
283      result = mix(result, AREF(i).psxhash());
284    return (int) (result & 0x7fffffff);
285  }
286
287  public abstract AbstractArray adjustArray(int size,
288                                              LispObject initialElement,
289                                              LispObject initialContents)
290   ;
291  public abstract AbstractArray adjustArray(int size,
292                                              AbstractArray displacedTo,
293                                              int displacement)
294   ;
295
296
297  public AbstractArray adjustArray(int[] dims,
298                                              LispObject initialElement,
299                                              LispObject initialContents)
300    {
301      return adjustArray(dims[0], initialElement, initialContents);
302  }
303
304  public AbstractArray adjustArray(int[] dims,
305                                              AbstractArray displacedTo,
306                                              int displacement)
307    {
308      return adjustArray(dims[0], displacedTo, displacement);
309  }
310}
Note: See TracBrowser for help on using the repository browser.