KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > armedbear > lisp > ComplexArray


1 /*
2  * ComplexArray.java
3  *
4  * Copyright (C) 2003-2004 Peter Graves
5  * $Id: ComplexArray.java,v 1.9 2004/05/27 20:30:19 piso Exp $
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
22 package org.armedbear.lisp;
23
24 public final class ComplexArray extends AbstractArray
25 {
26     private final int[] dimv;
27     private final LispObject elementType;
28     private final int totalSize;
29
30     // For non-displaced arrays.
31
private LispObject[] data;
32
33     // For displaced arrays.
34
private AbstractArray array;
35     private int displacement;
36
37     public ComplexArray(int[] dimv, LispObject elementType)
38     {
39         this.dimv = dimv;
40         this.elementType = elementType;
41         totalSize = computeTotalSize(dimv);
42         data = new LispObject[totalSize];
43         for (int i = totalSize; i-- > 0;)
44             data[i] = NIL;
45     }
46
47     public ComplexArray(int[] dimv,
48                         LispObject elementType,
49                         LispObject initialContents)
50         throws ConditionThrowable
51     {
52         this.dimv = dimv;
53         this.elementType = elementType;
54         final int rank = dimv.length;
55         LispObject rest = initialContents;
56         for (int i = 0; i < rank; i++) {
57             dimv[i] = rest.length();
58             rest = rest.elt(0);
59         }
60         totalSize = computeTotalSize(dimv);
61         data = new LispObject[totalSize];
62         setInitialContents(0, dimv, initialContents, 0);
63     }
64
65     public ComplexArray(int[] dimv, AbstractArray array, int displacement)
66     {
67         this.dimv = dimv;
68         this.elementType = array.getElementType();
69         this.array = array;
70         this.displacement = displacement;
71         totalSize = computeTotalSize(dimv);
72     }
73
74     private int setInitialContents(int axis, int[] dims, LispObject contents,
75                                    int index)
76         throws ConditionThrowable
77     {
78         if (dims.length == 0) {
79             try {
80                 data[index] = contents;
81             }
82             catch (ArrayIndexOutOfBoundsException JavaDoc e) {
83                 signal(new LispError("Bad initial contents for array."));
84                 return -1;
85             }
86             ++index;
87         } else {
88             int dim = dims[0];
89             if (dim != contents.length()) {
90                 signal(new LispError("Bad initial contents for array."));
91                 return -1;
92             }
93             int[] newDims = new int[dims.length-1];
94             for (int i = 1; i < dims.length; i++)
95                 newDims[i-1] = dims[i];
96             if (contents.listp()) {
97                 for (int i = contents.length();i-- > 0;) {
98                     LispObject content = contents.car();
99                     index =
100                         setInitialContents(axis + 1, newDims, content, index);
101                     contents = contents.cdr();
102                 }
103             } else {
104                 AbstractVector v = checkVector(contents);
105                 final int length = v.length();
106                 for (int i = 0; i < length; i++) {
107                     LispObject content = v.getRowMajor(i);
108                     index =
109                         setInitialContents(axis + 1, newDims, content, index);
110                 }
111             }
112         }
113         return index;
114     }
115
116     public LispObject typeOf()
117     {
118         return list3(Symbol.ARRAY, elementType, getDimensions());
119     }
120
121     public LispClass classOf()
122     {
123         return BuiltInClass.ARRAY;
124     }
125
126     public int getRank()
127     {
128         return dimv.length;
129     }
130
131     public LispObject getDimensions()
132     {
133         LispObject result = NIL;
134         for (int i = dimv.length; i-- > 0;)
135             result = new Cons(new Fixnum(dimv[i]), result);
136         return result;
137     }
138
139     public int getDimension(int n) throws ConditionThrowable
140     {
141         try {
142             return dimv[n];
143         }
144         catch (ArrayIndexOutOfBoundsException JavaDoc e) {
145             signal(new TypeError("Bad array dimension " + n + "."));
146             return -1;
147         }
148     }
149
150     public LispObject getElementType()
151     {
152         return elementType;
153     }
154
155     public int getTotalSize()
156     {
157         return totalSize;
158     }
159
160     public LispObject arrayDisplacement() throws ConditionThrowable
161     {
162         LispObject value1, value2;
163         if (array != null) {
164             value1 = array;
165             value2 = new Fixnum(displacement);
166         } else {
167             value1 = NIL;
168             value2 = Fixnum.ZERO;
169         }
170         return LispThread.currentThread().setValues(value1, value2);
171     }
172
173     public LispObject getRowMajor(int index) throws ConditionThrowable
174     {
175         if (data != null) {
176             try {
177                 return data[index];
178             }
179             catch (ArrayIndexOutOfBoundsException JavaDoc e) {
180                 return signal(new TypeError("Bad row major index " + index + "."));
181             }
182         } else
183             return array.getRowMajor(index + displacement);
184     }
185
186     public void setRowMajor(int index, LispObject newValue) throws ConditionThrowable
187     {
188         if (data != null) {
189             try {
190                 data[index] = newValue;
191             }
192             catch (ArrayIndexOutOfBoundsException JavaDoc e) {
193                 signal(new TypeError("Bad row major index " + index + "."));
194             }
195         } else
196             array.setRowMajor(index + displacement, newValue);
197     }
198
199     public void fill(LispObject obj) throws ConditionThrowable
200     {
201         if (data != null) {
202             for (int i = data.length; i-- > 0;)
203                 data[i] = obj;
204         } else {
205             for (int i = totalSize; i-- > 0;)
206                 setRowMajor(i, obj);
207         }
208     }
209
210     public String JavaDoc writeToString() throws ConditionThrowable
211     {
212         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
213         sb.append('#');
214         sb.append(dimv.length);
215         sb.append('A');
216         appendContents(dimv, 0, sb);
217         return sb.toString();
218     }
219 }
220
Popular Tags