1 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 private LispObject[] data; 32 33 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 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 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 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 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 writeToString() throws ConditionThrowable 211 { 212 StringBuffer sb = new StringBuffer (); 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 |