1 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; } 74 75 public boolean isAdjustable() 76 { 77 return true; 78 } 79 80 public LispObject AREF(LispObject index) throws ConditionThrowable 81 { 82 StringBuffer sb = new StringBuffer ("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 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 sb = new StringBuffer ("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 sb = new StringBuffer ("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 protected void appendContents(int[] dimensions, int index, StringBuffer 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 |