source: trunk/abcl/src/org/armedbear/lisp/SimpleArray_UnsignedByte32.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.3 KB
Line 
1/*
2 * SimpleArray_UnsignedByte32.java
3 *
4 * Copyright (C) 2003-2005 Peter Graves
5 * $Id: SimpleArray_UnsignedByte32.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_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            error(new ProgramError(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                error(new ProgramError(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 writeToString()
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 writeToString(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.