source: trunk/abcl/src/org/armedbear/lisp/SimpleArray_UnsignedByte32.java @ 11714

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

Use the Fixnum factory instead of creating new Fixnums all over the place.

Patch by: Douglas Miles (logicmoo at gmail.com)

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