diff --git a/gnu/kawa/lispexpr/LangObjType.java b/gnu/kawa/lispexpr/LangObjType.java index 1fd67473a..7cf14092a 100644 --- a/gnu/kawa/lispexpr/LangObjType.java +++ b/gnu/kawa/lispexpr/LangObjType.java @@ -65,6 +65,7 @@ public class LangObjType extends SpecialObjectType implements TypeValue private static final int ARGVECTOR_TYPE_CODE = 34; private static final int JSTRING_TYPE_CODE = 35; private static final int ISTRING_TYPE_CODE = 36; + private static final int GVECTOR_TYPE_CODE = 37; public static final LangObjType pathType = new LangObjType("path", "gnu.kawa.io.Path", @@ -107,9 +108,15 @@ public class LangObjType extends SpecialObjectType implements TypeValue DFLONUM_TYPE_CODE); public static final LangObjType vectorType = - new LangObjType("vector", "gnu.lists.FVector", + new LangObjType("vector", + "gnu.lists.FVector", VECTOR_TYPE_CODE); + public static final LangObjType gvectorType = + new LangObjType("gvector", + "gnu.lists.GVector", + GVECTOR_TYPE_CODE); + public static final LangObjType constVectorType = new LangObjType("constant-vector", "gnu.lists.FVector", CONST_VECTOR_TYPE_CODE); @@ -296,6 +303,7 @@ public class LangObjType extends SpecialObjectType implements TypeValue return 1; break; case VECTOR_TYPE_CODE: + case GVECTOR_TYPE_CODE: if (valueType instanceof ArrayType && ((ArrayType) valueType).getComponentType() instanceof ObjectType) return 1; @@ -374,6 +382,7 @@ public class LangObjType extends SpecialObjectType implements TypeValue case JSTRING_TYPE_CODE: case LIST_TYPE_CODE: case VECTOR_TYPE_CODE: + case GVECTOR_TYPE_CODE: case BITVECTOR_TYPE_CODE: case C16VECTOR_TYPE_CODE: case S8VECTOR_TYPE_CODE: @@ -588,6 +597,8 @@ public class LangObjType extends SpecialObjectType implements TypeValue return typeLangObjType.getDeclaredMethod("coerceToU8Vector", 1); case CONST_VECTOR_TYPE_CODE: return typeLangObjType.getDeclaredMethod("coerceToConstVector", 1); + case GVECTOR_TYPE_CODE: + return ClassType.make("gnu.lists.FVector").getDeclaredMethod("cast", 1); case VECTOR_TYPE_CODE: case BITVECTOR_TYPE_CODE: case C16VECTOR_TYPE_CODE: @@ -671,6 +682,7 @@ public class LangObjType extends SpecialObjectType implements TypeValue mname = "asSequenceOrNull"; break; case VECTOR_TYPE_CODE: + case GVECTOR_TYPE_CODE: case BITVECTOR_TYPE_CODE: case C16VECTOR_TYPE_CODE: case S8VECTOR_TYPE_CODE: @@ -772,6 +784,7 @@ public class LangObjType extends SpecialObjectType implements TypeValue case ISTRING_TYPE_CODE: return IString.valueOf((CharSequence) obj); case VECTOR_TYPE_CODE: + case GVECTOR_TYPE_CODE: return FVector.cast(obj); case F32VECTOR_TYPE_CODE: return F32Vector.cast(obj); @@ -921,6 +934,7 @@ public class LangObjType extends SpecialObjectType implements TypeValue toStringType.emitCoerceFromObject(code); break; case VECTOR_TYPE_CODE: + case GVECTOR_TYPE_CODE: case BITVECTOR_TYPE_CODE: case C16VECTOR_TYPE_CODE: case S8VECTOR_TYPE_CODE: @@ -964,6 +978,7 @@ public class LangObjType extends SpecialObjectType implements TypeValue return new PrimProcedure("gnu.kawa.io.URIPath", "makeURI", 1); case VECTOR_TYPE_CODE: return new PrimProcedure("gnu.lists.FVector", "make", 1); + case GVECTOR_TYPE_CODE: case CONST_VECTOR_TYPE_CODE: return new PrimProcedure("gnu.lists.FVector", "makeConstant", 1); case LIST_TYPE_CODE: @@ -1058,6 +1073,7 @@ public class LangObjType extends SpecialObjectType implements TypeValue public CompileBuildObject getBuildObject() { switch (typeCode) { case VECTOR_TYPE_CODE: + case GVECTOR_TYPE_CODE: case BITVECTOR_TYPE_CODE: case C16VECTOR_TYPE_CODE: case S8VECTOR_TYPE_CODE: diff --git a/gnu/kawa/lispexpr/LispLanguage.java b/gnu/kawa/lispexpr/LispLanguage.java index 4abeaff9e..0f3854f6f 100644 --- a/gnu/kawa/lispexpr/LispLanguage.java +++ b/gnu/kawa/lispexpr/LispLanguage.java @@ -270,6 +270,7 @@ public abstract class LispLanguage extends Language types.put("constant-string", ClassType.make("java.lang.CharSequence")); types.put("abstract-string", ClassType.make("gnu.lists.CharSeq")); types.put("vector", LangObjType.vectorType); + types.put("gvector", LangObjType.gvectorType); types.put("string", LangObjType.stringType); types.put("empty-list", ClassType.make("gnu.lists.EmptyList")); types.put("sequence", LangObjType.sequenceType); diff --git a/gnu/lists/BitVector.java b/gnu/lists/BitVector.java index 7abfe1524..b2398880a 100644 --- a/gnu/lists/BitVector.java +++ b/gnu/lists/BitVector.java @@ -8,7 +8,7 @@ import java.io.*; /** Simple adjustable-length vector of Boolean values. */ public class BitVector extends SimpleVector - implements Comparable + implements Comparable, GVector { boolean[] data; protected static boolean[] empty = new boolean[0]; diff --git a/gnu/lists/F32Vector.java b/gnu/lists/F32Vector.java index 74f56985b..ec634a587 100644 --- a/gnu/lists/F32Vector.java +++ b/gnu/lists/F32Vector.java @@ -8,7 +8,7 @@ import java.io.*; /** Simple adjustable-length vector of 32-bit floats. */ public class F32Vector extends SimpleVector - implements Comparable + implements Comparable, GVector { float[] data; protected static float[] empty = new float[0]; diff --git a/gnu/lists/F64Vector.java b/gnu/lists/F64Vector.java index b720f38c9..f040f3cd0 100644 --- a/gnu/lists/F64Vector.java +++ b/gnu/lists/F64Vector.java @@ -8,7 +8,7 @@ import java.io.*; /** Simple adjustable-length vector of 64-bit doubles. */ public class F64Vector extends SimpleVector - implements Comparable + implements Comparable, GVector { double[] data; protected static double[] empty = new double[0]; diff --git a/gnu/lists/FVector.java b/gnu/lists/FVector.java index b4ba1b800..8003c0237 100644 --- a/gnu/lists/FVector.java +++ b/gnu/lists/FVector.java @@ -8,7 +8,7 @@ import java.io.*; /** Simple adjustable-length vector of objects. */ public class FVector extends SimpleVector - implements Consumable, Comparable + implements Consumable, Comparable, GVector { Object[] data; protected static Object[] empty = new Object[0]; @@ -64,16 +64,17 @@ public class FVector extends SimpleVector this.info = VERY_SIMPLE_FLAG; } - public void copyFrom (int index, FVector src, int start, int end) { + public void copyFrom (int index, SimpleVector src, int start, int end) { int count = end-start; int sz = size(); int src_sz = src.size(); if (count < 0 || index+count > sz || end > src_sz) throw new ArrayIndexOutOfBoundsException(); int sseg, dseg; - if ((sseg = src.getSegmentReadOnly(start, count)) >= 0 && + //FVector fsrc; + if (src instanceof FVector && (sseg = src.getSegmentReadOnly(start, count)) >= 0 && (dseg = getSegment(index, count)) >= 0) { - System.arraycopy(src.data, sseg, data, dseg, count); + System.arraycopy(((FVector)src).data, sseg, data, dseg, count); } else { for (int i = 0; i < count; i++) set(index+i, src.get(start+i)); diff --git a/gnu/lists/GVector.java b/gnu/lists/GVector.java new file mode 100644 index 000000000..be88bc68f --- /dev/null +++ b/gnu/lists/GVector.java @@ -0,0 +1,5 @@ +package gnu.lists; + +public interface GVector extends AVector, java.util.RandomAccess +{ +} diff --git a/gnu/lists/PrimIntegerVector.java b/gnu/lists/PrimIntegerVector.java index b9184626e..e4e757a16 100644 --- a/gnu/lists/PrimIntegerVector.java +++ b/gnu/lists/PrimIntegerVector.java @@ -6,7 +6,7 @@ package gnu.lists; import java.io.*; public abstract class PrimIntegerVector extends SimpleVector - implements Comparable + implements Comparable, GVector { protected static int compareToInt(PrimIntegerVector v1, PrimIntegerVector v2) { diff --git a/gnu/lists/Range.java b/gnu/lists/Range.java index b12952771..5b46f1ee4 100644 --- a/gnu/lists/Range.java +++ b/gnu/lists/Range.java @@ -5,7 +5,7 @@ import gnu.kawa.functions.MultiplyOp; import gnu.math.IntNum; import java.io.*; -public class Range extends AbstractSequence implements AVector { +public class Range extends AbstractSequence implements GVector { E start; Object step; int size; diff --git a/gnu/lists/SimpleVector.java b/gnu/lists/SimpleVector.java index d64ae2190..ed554f7c1 100644 --- a/gnu/lists/SimpleVector.java +++ b/gnu/lists/SimpleVector.java @@ -391,6 +391,28 @@ public abstract class SimpleVector extends AbstractSequence return copy; } + public static SimpleVector castOrNull(Object obj) { + if (obj instanceof Object[]) + return new FVector((Object[]) obj); + // FIXME other array types + if (obj instanceof SimpleVector) + return (SimpleVector) obj; + return null; + } + + public static SimpleVector cast(Object value) { + SimpleVector vec = castOrNull(value); + if (vec == null) { + String msg; + if (value == null) + msg = "cannot convert null to vector"; + else + msg = "cannot convert a "+value.getClass().getName()+" to FVector"; + throw new ClassCastException(msg); + } + return vec; + } + /** This is convenience hack for printing "uniform vectors" (srfi 4). * It may go away without notice! */ public String getTag() { return null; } diff --git a/kawa/lib/vectors.scm b/kawa/lib/vectors.scm index 5cd1a2f96..0eac58428 100644 --- a/kawa/lib/vectors.scm +++ b/kawa/lib/vectors.scm @@ -5,23 +5,23 @@ (define (vector? x) :: (instance? x vector)) -(define (make-vector (k :: ) #!optional (fill #!null)) :: vector +(define (make-vector (k :: ) #!optional (fill #!null)) ::vector (gnu.lists.FVector k fill)) -(define (vector-length x :: ) :: +(define (vector-length x ::gvector) :: (invoke x 'size)) -(define (vector-set! (vector ::vector) (k ::int) obj) :: - (invoke vector 'setAt k obj)) +(define (vector-set! (vec ::vector) (k ::int) obj) :: + (invoke vec 'setAt k obj)) (define-procedure vector-ref setter: vector-set! (begin - (define (vector-ref (vector :: ) (k :: )) + (define (vector-ref (vector ::gvector) (k ::int)) (invoke vector 'get k)) vector-ref)) -(define (vector->list (vec :: ) +(define (vector->list (vec ::gvector) #!optional (start ::int 0) (end ::int (vec:size))) :: (let loop ((result :: '()) @@ -47,7 +47,7 @@ (set! (result j) ch) (loop result (+ i 1) (+ j 1)))))) -(define (vector-copy (vec :: vector) +(define (vector-copy (vec :: gvector) #!optional (start ::int 0) (end ::int (vec:size))) @@ -58,13 +58,13 @@ (define (vector-copy! (to ::vector) (at ::int) - (from ::vector) + (from ::gvector) #!optional (start ::int 0) (end ::int (from:size))) (to:copyFrom at from start end)) -(define (vector-fill! (vec :: vector) fill +(define (vector-fill! (vec ::vector) fill #!optional (start ::int 0) (end ::int (vec:size))) :: void (vec:fill start end fill))