KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * AbstractArray.java
3  *
4  * Copyright (C) 2003-2004 Peter Graves
5  * $Id: AbstractArray.java,v 1.26 2004/05/27 20:44:59 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 abstract class AbstractArray extends LispObject
25 {
26     public LispObject typep(LispObject type) throws ConditionThrowable
27     {
28         if (type == Symbol.ARRAY)
29             return T;
30         if (type == BuiltInClass.ARRAY)
31             return T;
32         return super.typep(type);
33     }
34
35     public boolean equalp(LispObject obj) throws ConditionThrowable
36     {
37         if (obj instanceof AbstractArray) {
38             AbstractArray a = (AbstractArray) obj;
39             if (getRank() != a.getRank())
40                 return false;
41             for (int i = getRank(); i-- > 0;) {
42                 if (getDimension(i) != a.getDimension(i))
43                     return false;
44             }
45             for (int i = getTotalSize(); i--> 0;) {
46                 if (!getRowMajor(i).equalp(a.getRowMajor(i)))
47                     return false;
48             }
49             return true;
50         }
51         return false;
52     }
53
54     public boolean isDisplaced()
55     {
56         return false;
57     }
58
59     public LispObject arrayDisplacement() throws ConditionThrowable
60     {
61         return LispThread.currentThread().setValues(NIL, Fixnum.ZERO);
62     }
63
64     public boolean hasFillPointer()
65     {
66         return false;
67     }
68
69     public int getFillPointer() throws ConditionThrowable
70     {
71         noFillPointer();
72         return -1; // Not reached.
73
}
74
75     public boolean isAdjustable()
76     {
77         return true;
78     }
79
80     public LispObject AREF(LispObject index) throws ConditionThrowable
81     {
82         StringBuffer JavaDoc sb = new StringBuffer JavaDoc("AREF: ");
83         sb.append("wrong number of subscripts (1) for array of rank ");
84         sb.append(getRank());
85         sb.append(".");
86         return signal(new ProgramError(sb.toString()));
87     }
88
89     public abstract int getRank();
90
91     public abstract LispObject getDimensions();
92
93     public abstract int getDimension(int n) throws ConditionThrowable;
94
95     public abstract LispObject getElementType();
96
97     public abstract int getTotalSize();
98
99     public abstract LispObject getRowMajor(int index) throws ConditionThrowable;
100
101     public abstract void setRowMajor(int index, LispObject newValue) throws ConditionThrowable;
102
103     // FIXME Detect overflow!
104
protected static final int computeTotalSize(int[] dimensions)
105     {
106         int size = 1;
107         for (int i = dimensions.length; i-- > 0;)
108             size *= dimensions[i];
109         return size;
110     }
111
112     public int getRowMajorIndex(LispObject[] subscripts)
113         throws ConditionThrowable
114     {
115         int[] subs = new int[subscripts.length];
116         for (int i = 0; i < subscripts.length; i++) {
117             LispObject subscript = subscripts[i];
118             if (subscript instanceof Fixnum)
119                 subs[i] = ((Fixnum)subscript).value;
120             else
121                 signal(new TypeError(subscript, Symbol.FIXNUM));
122         }
123         return getRowMajorIndex(subs);
124     }
125
126     public int getRowMajorIndex(int[] subscripts) throws ConditionThrowable
127     {
128         final int rank = getRank();
129         if (rank != subscripts.length) {
130             StringBuffer JavaDoc sb = new StringBuffer JavaDoc("Wrong number of subscripts (");
131             sb.append(subscripts.length);
132             sb.append(") for array of rank ");
133             sb.append(rank);
134             sb.append('.');
135             signal(new ProgramError(sb.toString()));
136         }
137         int sum = 0;
138         int size = 1;
139         for (int i = rank; i-- > 0;) {
140             int dim = getDimension(i);
141             int lastSize = size;
142             size *= dim;
143             int n = subscripts[i];
144             if (n < 0 || n >= getDimension(i)) {
145                 StringBuffer JavaDoc sb = new StringBuffer JavaDoc("Invalid index ");
146                 sb.append(n);
147                 sb.append(" for array ");
148                 sb.append(this);
149                 sb.append('.');
150                 signal(new ProgramError(sb.toString()));
151             }
152             sum += n * lastSize;
153         }
154         return sum;
155     }
156
157     public LispObject get(int[] subscripts) throws ConditionThrowable
158     {
159         return getRowMajor(getRowMajorIndex(subscripts));
160     }
161
162     public void set(int[] subscripts, LispObject newValue)
163         throws ConditionThrowable
164     {
165         setRowMajor(getRowMajorIndex(subscripts), newValue);
166     }
167
168     public abstract void fill(LispObject obj) throws ConditionThrowable;
169
170     // Helper for toString().
171
protected void appendContents(int[] dimensions, int index, StringBuffer JavaDoc sb)
172         throws ConditionThrowable
173     {
174         try {
175             if (dimensions.length == 0) {
176                 sb.append(getRowMajor(index).writeToString());
177             } else {
178                 sb.append('(');
179                 int[] dims = new int[dimensions.length - 1];
180                 for (int i = 1; i < dimensions.length; i++)
181                     dims[i-1] = dimensions[i];
182                 int count = 1;
183                 for (int i = 0; i < dims.length; i++)
184                     count *= dims[i];
185                 int length = dimensions[0];
186                 for (int i = 0; i < length; i++) {
187                     if (i != 0)
188                         sb.append(' ');
189                     appendContents(dims, index, sb);
190                     index += count;
191                 }
192                 sb.append(')');
193             }
194         }
195         catch (ConditionThrowable t) {
196             Debug.trace(t);
197         }
198     }
199
200     public final LispObject noFillPointer() throws ConditionThrowable
201     {
202         return signal(new TypeError("Array does not have a fill pointer."));
203     }
204 }
205
Popular Tags