diff --git a/convex-core/src/main/java/convex/core/cvm/Context.java b/convex-core/src/main/java/convex/core/cvm/Context.java index b1c1b18d4..b6debb472 100644 --- a/convex-core/src/main/java/convex/core/cvm/Context.java +++ b/convex-core/src/main/java/convex/core/cvm/Context.java @@ -1059,7 +1059,8 @@ public Context updateBindings(ACell bindingForm, Object args) { if (bindingForm instanceof Symbol) { Symbol sym=(Symbol)bindingForm; if (sym.equals(Symbols.UNDERSCORE)) return ctx; - // TODO: confirm must be an ACell at this point? + // args must be an ACell at this point, since we must have descended at least one level of binding from a + // function invocation on ACell[] return withLocalBindings(localBindings.conj((ACell)args)); } else if (bindingForm instanceof AVector) { AVector v=(AVector)bindingForm; @@ -1083,7 +1084,7 @@ public Context updateBindings(ACell bindingForm, Object args) { // bind variadic form at position i+1 to all args except nLeft long consumeCount=(argCount-i)-nLeft; if (consumeCount<0) return ctx.withArityError("Insufficient arguments to allow variadic binding"); - AVector rest=RT.vec(args).slice(i,i+consumeCount); // TODO: cost of this? + AVector rest=RT.vec(args,i,i+consumeCount); ctx= ctx.updateBindings(v.get(i+1), rest); if(ctx.isExceptional()) return ctx; diff --git a/convex-core/src/main/java/convex/core/data/VectorArray.java b/convex-core/src/main/java/convex/core/data/VectorArray.java index cda94bbe2..0e24470bb 100644 --- a/convex-core/src/main/java/convex/core/data/VectorArray.java +++ b/convex-core/src/main/java/convex/core/data/VectorArray.java @@ -34,6 +34,12 @@ private VectorArray(ACell[] data, long start, long count) { public static VectorArray wrap(ACell[] arr) { return new VectorArray(arr,0,arr.length); } + + public static VectorArray wrap(ACell[] elements, long start, long end) { + long n=end-start; + if (n<0) throw new IllegalArgumentException("end before start index"); + return new VectorArray(elements,start,n); + } public static VectorArray of(Object ... os) { int n=os.length; @@ -308,4 +314,6 @@ public AVector dissocAt(long i) { return wrap(cells); } + + } diff --git a/convex-core/src/main/java/convex/core/data/Vectors.java b/convex-core/src/main/java/convex/core/data/Vectors.java index 11dc5a5c0..dc79f6fb1 100644 --- a/convex-core/src/main/java/convex/core/data/Vectors.java +++ b/convex-core/src/main/java/convex/core/data/Vectors.java @@ -80,8 +80,9 @@ public static AVector create(ACell... elements) { * @return New vector wrapping the specified elements */ public static AVector wrap(ACell[] elements) { - if (elements.length==0) return empty(); - return VectorArray.wrap(elements); + int n=elements.length; + if (n==0) return empty(); + return VectorArray.wrap(elements,0,n); } /** diff --git a/convex-core/src/main/java/convex/core/lang/RT.java b/convex-core/src/main/java/convex/core/lang/RT.java index 0e40ca402..ba39054e7 100644 --- a/convex-core/src/main/java/convex/core/lang/RT.java +++ b/convex-core/src/main/java/convex/core/lang/RT.java @@ -38,6 +38,7 @@ import convex.core.data.Sets; import convex.core.data.Strings; import convex.core.data.Symbol; +import convex.core.data.VectorArray; import convex.core.data.Vectors; import convex.core.data.prim.AInteger; import convex.core.data.prim.ANumeric; @@ -688,9 +689,10 @@ private static double doubleValue(ACell a) { } /** - * Converts any data structure to a vector + * Converts any data structure to a vector. May wrap a Java array in VectorArray, so + * the object must be treated as immutable in order for this to be safe. * - * @param o Object to attempt to convert to a Vector. May wrap a Java array in VectorArray + * @param o Object to attempt to convert to a Vector. * @return AVector instance, or null if not convertible */ @SuppressWarnings("unchecked") @@ -712,6 +714,25 @@ public static AVector vec(Object o) { return null; } + + /** + * Converts any data structure to a vector. May wrap a Java array in VectorArray, so + * the object must be treated as immutable in order for this to be safe. + * + * @param o Object to attempt to convert to a Vector. + * @param start start index to slice + * @end end index to slice + * @return AVector instance, or null if not convertible + */ + @SuppressWarnings("unchecked") + public static AVector vec(Object o, long start, long end) { + if (o instanceof ACell[]) { + ACell[] arr = (ACell[])o; + return VectorArray.wrap(arr,start,end); + } + + return (AVector) vec(o).slice(start, end); + } /** * Converts any countable data structure to a vector. Might be O(n) @@ -1902,4 +1923,5 @@ public static long[] toLongArray(AVector v) { + }