source: trunk/abcl/src/org/armedbear/lisp/SimpleArray_UnsignedByte16.java @ 12559

Last change on this file since 12559 was 12288, checked in by vvoutilainen, 15 years ago

Don't extend Lisp in LispObject, static import Lisp wherever
necessary. Patch by Douglas R. Miles.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 10.6 KB
Line 
1/*
2 * SimpleArray_UnsignedByte16.java
3 *
4 * Copyright (C) 2003-2005 Peter Graves
5 * $Id: SimpleArray_UnsignedByte16.java 12288 2009-11-29 22:00:12Z vvoutilainen $
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 final class SimpleArray_UnsignedByte16 extends AbstractArray
39{
40    private final int[] dimv;
41    private final int totalSize;
42    private final int[] data;
43
44    public SimpleArray_UnsignedByte16(int[] dimv)
45    {
46        this.dimv = dimv;
47        totalSize = computeTotalSize(dimv);
48        data = new int[totalSize];
49    }
50
51    public SimpleArray_UnsignedByte16(int[] dimv, LispObject initialContents)
52
53    {
54        this.dimv = dimv;
55        final int rank = dimv.length;
56        LispObject rest = initialContents;
57        for (int i = 0; i < rank; i++) {
58            dimv[i] = rest.length();
59            rest = rest.elt(0);
60        }
61        totalSize = computeTotalSize(dimv);
62        data = new int[totalSize];
63        setInitialContents(0, dimv, initialContents, 0);
64    }
65
66    public SimpleArray_UnsignedByte16(int rank, LispObject initialContents)
67
68    {
69        if (rank < 2)
70            Debug.assertTrue(false);
71        dimv = new int[rank];
72        LispObject rest = initialContents;
73        for (int i = 0; i < rank; i++) {
74            dimv[i] = rest.length();
75            if (rest == NIL || rest.length() == 0)
76                break;
77            rest = rest.elt(0);
78        }
79        totalSize = computeTotalSize(dimv);
80        data = new int[totalSize];
81        setInitialContents(0, dimv, initialContents, 0);
82    }
83
84    private int setInitialContents(int axis, int[] dims, LispObject contents,
85                                   int index)
86
87    {
88        if (dims.length == 0) {
89            try {
90                data[index] = coerceLispObjectToJavaByte(contents);
91            }
92            catch (ArrayIndexOutOfBoundsException e) {
93                error(new LispError("Bad initial contents for array."));
94                return -1;
95            }
96            ++index;
97        } else {
98            int dim = dims[0];
99            if (dim != contents.length()) {
100                error(new LispError("Bad initial contents for array."));
101                return -1;
102            }
103            int[] newDims = new int[dims.length-1];
104            for (int i = 1; i < dims.length; i++)
105                newDims[i-1] = dims[i];
106            if (contents.listp()) {
107                for (int i = contents.length();i-- > 0;) {
108                    LispObject content = contents.car();
109                    index =
110                        setInitialContents(axis + 1, newDims, content, index);
111                    contents = contents.cdr();
112                }
113            } else {
114                AbstractVector v = checkVector(contents);
115                final int length = v.length();
116                for (int i = 0; i < length; i++) {
117                    LispObject content = v.AREF(i);
118                    index =
119                        setInitialContents(axis + 1, newDims, content, index);
120                }
121            }
122        }
123        return index;
124    }
125
126    @Override
127    public LispObject typeOf()
128    {
129        return list(Symbol.SIMPLE_ARRAY, UNSIGNED_BYTE_16, getDimensions());
130    }
131
132    @Override
133    public LispObject classOf()
134    {
135        return BuiltInClass.SIMPLE_ARRAY;
136    }
137
138    @Override
139    public LispObject typep(LispObject typeSpecifier)
140    {
141        if (typeSpecifier == Symbol.SIMPLE_ARRAY)
142            return T;
143        if (typeSpecifier == BuiltInClass.SIMPLE_ARRAY)
144            return T;
145        return super.typep(typeSpecifier);
146    }
147
148    @Override
149    public int getRank()
150    {
151        return dimv.length;
152    }
153
154    @Override
155    public LispObject getDimensions()
156    {
157        LispObject result = NIL;
158        for (int i = dimv.length; i-- > 0;)
159            result = new Cons(Fixnum.getInstance(dimv[i]), result);
160        return result;
161    }
162
163    @Override
164    public int getDimension(int n)
165    {
166        try {
167            return dimv[n];
168        }
169        catch (ArrayIndexOutOfBoundsException e) {
170            error(new TypeError("Bad array dimension " + n + "."));
171            return -1;
172        }
173    }
174
175    @Override
176    public LispObject getElementType()
177    {
178        return UNSIGNED_BYTE_16;
179    }
180
181    @Override
182    public int getTotalSize()
183    {
184        return totalSize;
185    }
186
187    @Override
188    public boolean isAdjustable()
189    {
190        return false;
191    }
192
193    @Override
194    public int aref(int index)
195    {
196        try {
197            return data[index];
198        }
199        catch (ArrayIndexOutOfBoundsException e) {
200            error(new TypeError("Bad row major index " + index + "."));
201            // Not reached.
202            return 0;
203        }
204    }
205
206    @Override
207    public LispObject AREF(int index)
208    {
209        try {
210            return Fixnum.getInstance(data[index]);
211        }
212        catch (ArrayIndexOutOfBoundsException e) {
213            return error(new TypeError("Bad row major index " + index + "."));
214        }
215    }
216
217    @Override
218    public void aset(int index, LispObject obj)
219    {
220        try {
221            data[index] = Fixnum.getValue(obj);
222        }
223        catch (ArrayIndexOutOfBoundsException e) {
224            error(new TypeError("Bad row major index " + index + "."));
225        }
226    }
227
228    @Override
229    public int getRowMajorIndex(int[] subscripts)
230    {
231        final int rank = dimv.length;
232        if (rank != subscripts.length) {
233            StringBuffer sb = new StringBuffer("Wrong number of subscripts (");
234            sb.append(subscripts.length);
235            sb.append(") for array of rank ");
236            sb.append(rank);
237            sb.append('.');
238            error(new ProgramError(sb.toString()));
239        }
240        int sum = 0;
241        int size = 1;
242        for (int i = rank; i-- > 0;) {
243            final int dim = dimv[i];
244            final int lastSize = size;
245            size *= dim;
246            int n = subscripts[i];
247            if (n < 0 || n >= dim) {
248                StringBuffer sb = new StringBuffer("Invalid index ");
249                sb.append(n);
250                sb.append(" for array ");
251                sb.append(this);
252                sb.append('.');
253                error(new ProgramError(sb.toString()));
254            }
255            sum += n * lastSize;
256        }
257        return sum;
258    }
259
260    @Override
261    public LispObject get(int[] subscripts)
262    {
263        try {
264            return Fixnum.getInstance(data[getRowMajorIndex(subscripts)]);
265        }
266        catch (ArrayIndexOutOfBoundsException e) {
267            return error(new TypeError("Bad row major index " +
268                                        getRowMajorIndex(subscripts) + "."));
269        }
270    }
271
272    @Override
273    public void set(int[] subscripts, LispObject obj)
274
275    {
276        try {
277            data[getRowMajorIndex(subscripts)] = Fixnum.getValue(obj);
278        }
279        catch (ArrayIndexOutOfBoundsException e) {
280            error(new TypeError("Bad row major index " +
281                                 getRowMajorIndex(subscripts) + "."));
282        }
283    }
284
285    @Override
286    public void fill(LispObject obj)
287    {
288        int n = Fixnum.getValue(obj);
289        for (int i = totalSize; i-- > 0;)
290            data[i] = n;
291    }
292
293    @Override
294    public String writeToString()
295    {
296        if (Symbol.PRINT_READABLY.symbolValue() != NIL) {
297            error(new PrintNotReadable(list(Keyword.OBJECT, this)));
298            // Not reached.
299            return null;
300        }
301        return writeToString(dimv);
302    }
303
304    public AbstractArray adjustArray(int[] dimv, LispObject initialElement,
305                                     LispObject initialContents)
306
307    {
308        if (initialContents != null)
309            return new SimpleArray_UnsignedByte16(dimv, initialContents);
310        for (int i = 0; i < dimv.length; i++) {
311            if (dimv[i] != this.dimv[i]) {
312                SimpleArray_UnsignedByte16 newArray =
313                    new SimpleArray_UnsignedByte16(dimv);
314                if (initialElement != null)
315                    newArray.fill(initialElement);
316                copyArray(this, newArray);
317                return newArray;
318            }
319        }
320        // New dimensions are identical to old dimensions.
321        return this;
322    }
323
324    // Copy a1 to a2 for index tuples that are valid for both arrays.
325    private static void copyArray(AbstractArray a1, AbstractArray a2)
326
327    {
328        Debug.assertTrue(a1.getRank() == a2.getRank());
329        int[] subscripts = new int[a1.getRank()];
330        int axis = 0;
331        copySubArray(a1, a2, subscripts, axis);
332    }
333
334    private static void copySubArray(AbstractArray a1, AbstractArray a2,
335                                     int[] subscripts, int axis)
336
337    {
338        if (axis < subscripts.length) {
339            final int limit =
340                Math.min(a1.getDimension(axis), a2.getDimension(axis));
341            for (int i = 0; i < limit; i++) {
342                subscripts[axis] = i;
343                copySubArray(a1, a2, subscripts, axis + 1);
344            }
345        } else {
346            int i1 = a1.getRowMajorIndex(subscripts);
347            int i2 = a2.getRowMajorIndex(subscripts);
348            a2.aset(i2, a1.AREF(i1));
349        }
350    }
351
352    public AbstractArray adjustArray(int[] dimv, AbstractArray displacedTo,
353                                     int displacement)
354    {
355        return new ComplexArray(dimv, displacedTo, displacement);
356    }
357}
Note: See TracBrowser for help on using the repository browser.