source: branches/0.22.x/abcl/src/org/armedbear/lisp/ComplexArray.java

Last change on this file 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: 8.8 KB
Line 
1/*
2 * ComplexArray.java
3 *
4 * Copyright (C) 2003-2007 Peter Graves
5 * $Id: ComplexArray.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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 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 ComplexArray extends AbstractArray
39{
40    private final int[] dimv;
41    private final LispObject elementType;
42    private int totalSize;
43
44    // For non-displaced arrays.
45    private LispObject[] data;
46
47    // For displaced arrays.
48    private AbstractArray array;
49    private int displacement;
50
51    public ComplexArray(int[] dimv, LispObject elementType)
52    {
53        this.dimv = dimv;
54        this.elementType = elementType;
55        totalSize = computeTotalSize(dimv);
56        data = new LispObject[totalSize];
57        for (int i = totalSize; i-- > 0;)
58            data[i] = Fixnum.ZERO;
59    }
60
61    public ComplexArray(int[] dimv,
62                        LispObject elementType,
63                        LispObject initialContents)
64
65    {
66        this.dimv = dimv;
67        this.elementType = elementType;
68        final int rank = dimv.length;
69        LispObject rest = initialContents;
70        for (int i = 0; i < rank; i++) {
71            dimv[i] = rest.length();
72            rest = rest.elt(0);
73        }
74        totalSize = computeTotalSize(dimv);
75        data = new LispObject[totalSize];
76        setInitialContents(0, dimv, initialContents, 0);
77    }
78
79    public ComplexArray(int[] dimv, AbstractArray array, int displacement)
80    {
81        this.dimv = dimv;
82        this.elementType = array.getElementType();
83        this.array = array;
84        this.displacement = displacement;
85        totalSize = computeTotalSize(dimv);
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.ARRAY, elementType, getDimensions());
134    }
135
136    @Override
137    public LispObject classOf()
138    {
139        return BuiltInClass.ARRAY;
140    }
141
142    @Override
143    public int getRank()
144    {
145        return dimv.length;
146    }
147
148    @Override
149    public LispObject getDimensions()
150    {
151        LispObject result = NIL;
152        for (int i = dimv.length; i-- > 0;)
153            result = new Cons(Fixnum.getInstance(dimv[i]), result);
154        return result;
155    }
156
157    @Override
158    public int getDimension(int n)
159    {
160        try {
161            return dimv[n];
162        }
163        catch (ArrayIndexOutOfBoundsException e) {
164            error(new TypeError("Bad array dimension " + n + "."));
165            return -1;
166        }
167    }
168
169    @Override
170    public LispObject getElementType()
171    {
172        return elementType;
173    }
174
175    @Override
176    public int getTotalSize()
177    {
178        return totalSize;
179    }
180
181    @Override
182    public LispObject arrayDisplacement()
183    {
184        LispObject value1, value2;
185        if (array != null) {
186            value1 = array;
187            value2 = Fixnum.getInstance(displacement);
188        } else {
189            value1 = NIL;
190            value2 = Fixnum.ZERO;
191        }
192        return LispThread.currentThread().setValues(value1, value2);
193    }
194
195    @Override
196    public LispObject AREF(int index)
197    {
198        if (data != null) {
199            try {
200                return data[index];
201            }
202            catch (ArrayIndexOutOfBoundsException e) {
203                return error(new TypeError("Bad row major index " + index + "."));
204            }
205        } else
206            return array.AREF(index + displacement);
207    }
208
209    @Override
210    public void aset(int index, LispObject newValue)
211    {
212        if (data != null) {
213            try {
214                data[index] = newValue;
215            }
216            catch (ArrayIndexOutOfBoundsException e) {
217                error(new TypeError("Bad row major index " + index + "."));
218            }
219        } else
220            array.aset(index + displacement, newValue);
221    }
222
223    @Override
224    public void fill(LispObject obj)
225    {
226        if (data != null) {
227            for (int i = data.length; i-- > 0;)
228                data[i] = obj;
229        } else {
230            for (int i = totalSize; i-- > 0;)
231                aset(i, obj);
232        }
233    }
234
235    @Override
236    public String writeToString()
237    {
238        return writeToString(dimv);
239    }
240
241    @Override
242    public AbstractArray adjustArray(int[] dims,
243                                              LispObject initialElement,
244                                              LispObject initialContents)
245            {
246        if (isAdjustable()) {
247            if (initialContents != null)
248                setInitialContents(0, dims, initialContents, 0);
249            else {
250                //### FIXME Take the easy way out: we don't want to reorganize
251                // all of the array code yet
252                SimpleArray_T tempArray = new SimpleArray_T(dims, elementType);
253                if (initialElement != null)
254                    tempArray.fill(initialElement);
255                SimpleArray_T.copyArray(this, tempArray);
256                this.data = tempArray.data;
257
258                for (int i = 0; i < dims.length; i++)
259                    dimv[i] = dims[i];
260            }
261            return this;
262        } else {
263            if (initialContents != null)
264                return new ComplexArray(dims, elementType, initialContents);
265            else {
266                ComplexArray newArray = new ComplexArray(dims, elementType);
267                if (initialElement != null)
268                    newArray.fill(initialElement);
269                return newArray;
270            }
271        }
272    }
273
274    @Override
275    public AbstractArray adjustArray(int[] dims,
276                                              AbstractArray displacedTo,
277                                              int displacement)
278            {
279        if (isAdjustable()) {
280            for (int i = 0; i < dims.length; i++)
281                dimv[i] = dims[i];
282
283            this.data = null;
284            this.array = displacedTo;
285            this.displacement = displacement;
286            this.totalSize = computeTotalSize(dims);
287
288            return this;
289        } else {
290            ComplexArray a = new ComplexArray(dims, displacedTo, displacement);
291           
292            return a;
293        }
294    }
295}
Note: See TracBrowser for help on using the repository browser.