source: branches/streams/abcl/src/org/armedbear/lisp/SimpleArray_UnsignedByte16.java

Last change on this file was 14465, checked in by rschlatte, 12 years ago

new method program_error, analogous to type_error

  • 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 14465 2013-04-24 12:50:37Z rschlatte $
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            program_error(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                program_error(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 printObject()
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 printObject(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.