+static void evalUnpack(naContext ctx, int count)
+{
+ naRef vec = ctx->opStack[--ctx->opTop];
+ if(!IS_VEC(vec) || naVec_size(vec) < count)
+ ERR(ctx, "short or invalid multi-assignment vector");
+ while(count--) PUSH(naVec_get(vec, count));
+}
+
+// FIXME: unify with almost identical checkVec() above
+static int vbound(naContext ctx, naRef v, naRef ir, int end)
+{
+ int sz=naVec_size(v), i = IS_NIL(ir) ? (end ? -1 : 0) : numify(ctx, ir);
+ if(IS_NIL(ir) && !sz) return i;
+ if(i < 0) i += sz;
+ if(i < 0 || i >= sz)
+ naRuntimeError(ctx, "slice index %d out of bounds (size: %d)",
+ i, sz);
+ return i;
+}
+
+static void evalSlice(naContext ctx, naRef src, naRef dst, naRef idx)
+{
+ if(!IS_VEC(src)) ERR(ctx, "cannot slice non-vector");
+ naVec_append(dst, naVec_get(src, checkVec(ctx, src, idx)));
+}
+
+static void evalSlice2(naContext ctx, naRef src, naRef dst,
+ naRef start, naRef endr)
+{
+ int i, end;
+ if(!IS_VEC(src)) ERR(ctx, "cannot slice non-vector");
+ end = vbound(ctx, src, endr, 1);
+ for(i = vbound(ctx, src, start, 0); i<=end; i++)
+ naVec_append(dst, naVec_get(src, i));
+}
+
+#define ARG() BYTECODE(cd)[f->ip++]