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