Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* ComplexArray.java
*
* Copyright (C) 2003-2007 Peter Graves
* $Id$
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* As a special exception, the copyright holders of this library give you
* permission to link this library with independent modules to produce an
* executable, regardless of the license terms of these independent
* modules, and to copy and distribute the resulting executable under
* terms of your choice, provided that you also meet, for each linked
* independent module, the terms and conditions of the license of that
* module. An independent module is a module which is not derived from
* or based on this library. If you modify this library, you may extend
* this exception to your version of the library, but you are not
* obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*/
package org.armedbear.lisp;
import static org.armedbear.lisp.Lisp.*;
public final class ComplexArray extends AbstractArray
{
private final int[] dimv;
private final LispObject elementType;
private int totalSize;
// For non-displaced arrays.
private LispObject[] data;
// For displaced arrays.
private AbstractArray array;
private int displacement;
public ComplexArray(int[] dimv, LispObject elementType)
{
this.dimv = dimv;
this.elementType = elementType;
totalSize = computeTotalSize(dimv);
data = new LispObject[totalSize];
for (int i = totalSize; i-- > 0;)
data[i] = Fixnum.ZERO;
}
public ComplexArray(int[] dimv,
LispObject elementType,
LispObject initialContents)
{
this.dimv = dimv;
this.elementType = elementType;
final int rank = dimv.length;
LispObject rest = initialContents;
for (int i = 0; i < rank; i++) {
dimv[i] = rest.length();
rest = rest.elt(0);
}
totalSize = computeTotalSize(dimv);
data = new LispObject[totalSize];
setInitialContents(0, dimv, initialContents, 0);
}
public ComplexArray(int[] dimv, AbstractArray array, int displacement)
{
this.dimv = dimv;
this.elementType = array.getElementType();
this.array = array;
this.displacement = displacement;
totalSize = computeTotalSize(dimv);
}
private int setInitialContents(int axis, int[] dims, LispObject contents,
int index)
{
if (dims.length == 0) {
try {
data[index] = contents;
}
catch (ArrayIndexOutOfBoundsException e) {
error(new LispError("Bad initial contents for array."));
return -1;
}
++index;
} else {
int dim = dims[0];
if (dim != contents.length()) {
error(new LispError("Bad initial contents for array."));
return -1;
}
int[] newDims = new int[dims.length-1];
for (int i = 1; i < dims.length; i++)
newDims[i-1] = dims[i];
if (contents.listp()) {
for (int i = contents.length();i-- > 0;) {
LispObject content = contents.car();
index =
setInitialContents(axis + 1, newDims, content, index);
contents = contents.cdr();
}
} else {
AbstractVector v = checkVector(contents);
final int length = v.length();
for (int i = 0; i < length; i++) {
LispObject content = v.AREF(i);
index =
setInitialContents(axis + 1, newDims, content, index);
}
}
}
return index;
}
@Override
public LispObject typeOf()
{
return list(Symbol.ARRAY, elementType, getDimensions());
}
@Override
public LispObject classOf()
{
return BuiltInClass.ARRAY;
}
@Override
public int getRank()
{
return dimv.length;
}
@Override
public LispObject getDimensions()
{
LispObject result = NIL;
for (int i = dimv.length; i-- > 0;)
result = new Cons(Fixnum.getInstance(dimv[i]), result);
return result;
}
@Override
public int getDimension(int n)
{
try {
return dimv[n];
}
catch (ArrayIndexOutOfBoundsException e) {
error(new TypeError("Bad array dimension " + n + "."));
return -1;
}
}
@Override
public LispObject getElementType()
{
return elementType;
}
@Override
public int getTotalSize()
{
return totalSize;
}
@Override
public LispObject arrayDisplacement()
{
LispObject value1, value2;
if (array != null) {
value1 = array;
value2 = Fixnum.getInstance(displacement);
} else {
value1 = NIL;
value2 = Fixnum.ZERO;
}
return LispThread.currentThread().setValues(value1, value2);
}
@Override
public LispObject AREF(int index)
{
if (data != null) {
try {
return data[index];
}
catch (ArrayIndexOutOfBoundsException e) {
return error(new TypeError("Bad row major index " + index + "."));
}
} else
return array.AREF(index + displacement);
}
@Override
public void aset(int index, LispObject newValue)
{
if (data != null) {
try {
data[index] = newValue;
}
catch (ArrayIndexOutOfBoundsException e) {
error(new TypeError("Bad row major index " + index + "."));
}
} else
array.aset(index + displacement, newValue);
}
@Override
public void fill(LispObject obj)
{
if (data != null) {
for (int i = data.length; i-- > 0;)
data[i] = obj;
} else {
for (int i = totalSize; i-- > 0;)
aset(i, obj);
}
}
@Override
public String printObject()
{
return printObject(dimv);
}
@Override
public AbstractArray adjustArray(int[] dims,
LispObject initialElement,
LispObject initialContents)
{
if (isAdjustable()) {
if (initialContents != null)
setInitialContents(0, dims, initialContents, 0);
else {
//### FIXME Take the easy way out: we don't want to reorganize
// all of the array code yet
SimpleArray_T tempArray = new SimpleArray_T(dims, elementType);
if (initialElement != null)
tempArray.fill(initialElement);
SimpleArray_T.copyArray(this, tempArray);
this.data = tempArray.data;
for (int i = 0; i < dims.length; i++)
dimv[i] = dims[i];
}
return this;
} else {
if (initialContents != null)
return new ComplexArray(dims, elementType, initialContents);
else {
ComplexArray newArray = new ComplexArray(dims, elementType);
if (initialElement != null)
newArray.fill(initialElement);
return newArray;
}
}
}
@Override
public AbstractArray adjustArray(int[] dims,
AbstractArray displacedTo,
int displacement)
{
if (isAdjustable()) {
for (int i = 0; i < dims.length; i++)
dimv[i] = dims[i];
this.data = null;
this.array = displacedTo;
this.displacement = displacement;
this.totalSize = computeTotalSize(dims);
return this;
} else {
ComplexArray a = new ComplexArray(dims, displacedTo, displacement);
return a;
}
}
}