summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--eval.c1
-rw-r--r--lib.c34
-rw-r--r--lib.h1
-rw-r--r--share/txr/stdlib/doc-syms.tl1
-rw-r--r--tests/010/vec.tl32
-rw-r--r--txr.188
6 files changed, 157 insertions, 0 deletions
diff --git a/eval.c b/eval.c
index 2d840160..7b3f1ad6 100644
--- a/eval.c
+++ b/eval.c
@@ -7061,6 +7061,7 @@ void eval_init(void)
reg_fun(intern(lit("copy-vec"), user_package), func_n1(copy_vec));
reg_fun(intern(lit("sub-vec"), user_package), func_n3o(sub_vec, 1));
reg_fun(intern(lit("replace-vec"), user_package), func_n4o(replace_vec, 2));
+ reg_fun(intern(lit("fill-vec"), user_package), func_n4o(fill_vec, 2));
reg_fun(intern(lit("cat-vec"), user_package), func_n1(cat_vec));
reg_fun(intern(lit("assoc"), user_package), func_n2(assoc));
diff --git a/lib.c b/lib.c
index ae78b147..9e3827d7 100644
--- a/lib.c
+++ b/lib.c
@@ -8661,6 +8661,40 @@ val replace_obj(val obj, val items, val from, val to)
return obj;
}
+val fill_vec(val vec, val item, val from_in, val to_in)
+{
+ val self = lit("fill-vec");
+ val len = length_vec(vec);
+ cnum from = c_num(default_arg(from_in, zero), self);
+ cnum to = c_num(default_arg(to_in, len), self);
+ cnum l = c_num(len, self);
+ cnum i;
+
+ if (from < 0)
+ from += l;
+
+ if (to < 0)
+ to += l;
+
+ if (from < 0 || from > l)
+ uw_throwf(error_s, lit("~a: from index ~s is out of range for vector ~s"),
+ self, num(from), vec, nao);
+
+ if (to < 0 || to > l)
+ uw_throwf(error_s, lit("~a: to index ~s is out of range for vector ~s"),
+ self, num(to), vec, nao);
+
+ if (from >= to)
+ return vec;
+
+ for (i = from; i < to - 1; i++)
+ vec->v.vec[i] = item;
+
+ set(mkloc(vec->v.vec[i], vec), item);
+
+ return vec;
+}
+
val cat_vec(val list)
{
val self = lit("cat-vec");
diff --git a/lib.h b/lib.h
index a3fe1dd4..a91a2f9b 100644
--- a/lib.h
+++ b/lib.h
@@ -1069,6 +1069,7 @@ val copy_vec(val vec);
val sub_vec(val vec_in, val from, val to);
val replace_vec(val vec_in, val items, val from, val to);
val replace_obj(val obj, val items, val from, val to);
+val fill_vec(val vec, val item, val from_in, val to_in);
val cat_vec(val list);
val lazy_stream_cons(val stream);
val lazy_str(val list, val term, val limit);
diff --git a/share/txr/stdlib/doc-syms.tl b/share/txr/stdlib/doc-syms.tl
index 20e7cf0e..7c065945 100644
--- a/share/txr/stdlib/doc-syms.tl
+++ b/share/txr/stdlib/doc-syms.tl
@@ -720,6 +720,7 @@
("fill-buf-adjust" "N-00D142E1")
("fill-carray" "N-00737951")
("fill-obj" "N-0039A1D1")
+ ("fill-vec" "N-03C9A237")
("filter" "N-00B50006")
("filter-equal" "N-03136087")
("filter-string-tree" "N-00C9EEB0")
diff --git a/tests/010/vec.tl b/tests/010/vec.tl
new file mode 100644
index 00000000..c1d435b9
--- /dev/null
+++ b/tests/010/vec.tl
@@ -0,0 +1,32 @@
+(load "../common")
+
+(let ((v0 (vec))
+ (v3 (vec 1 2 3)))
+ (mtest
+ v0 #()
+ v3 #(1 2 3)
+ (fill-vec v0 nil) #()
+ (fill-vec v0 nil -1 -1) :error
+ (fill-vec v0 nil 1 1) :error
+ (fill-vec v3 nil 0 0) #(1 2 3)
+ (fill-vec v3 nil 1 1) #(1 2 3)
+ (fill-vec v3 nil 2 2) #(1 2 3)
+ (fill-vec v3 nil 3 3) #(1 2 3)
+ (fill-vec v3 nil -3 -3) #(1 2 3)
+ (fill-vec v3 nil 4 0) :error
+ (fill-vec v3 nil 4 4) :error
+ (fill-vec v3 nil 0 4) :error
+ (fill-vec v3 nil -1 0) #(1 2 3)
+ (fill-vec v3 nil 1 0) #(1 2 3)
+ (fill-vec v3 nil 2 1) #(1 2 3)
+ (fill-vec v3 nil 3 2) #(1 2 3)
+ (fill-vec v3 nil -4 -3) :error
+ (fill-vec v3 nil -3 -4) :error
+ (fill-vec v3 nil) #(nil nil nil)
+ (fill-vec v3 1 0 1) #(1 nil nil)
+ (fill-vec v3 2 1 2) #(1 2 nil)
+ (fill-vec v3 3 2 3) #(1 2 3)
+ (fill-vec v3 0 1) #(1 0 0)
+ (fill-vec v3 2 -1) #(1 0 2)
+ (fill-vec v3 3 -3) #(3 3 3))
+ (fill-vec v3 0 -2 -1) #(3 0 3))
diff --git a/txr.1 b/txr.1
index d6a016ca..dcbc568b 100644
--- a/txr.1
+++ b/txr.1
@@ -25613,6 +25613,94 @@ function except that the
.meta vec
argument must be a vector.
+.coNP Function @ fill-vec
+.synb
+.mets (fill-vec-vec < vec < elem >> [ from <> [ to ]])
+.syne
+.desc
+The
+.code fill-vec
+function overwrites a range of the vector with copies of the
+.meta elem
+value.
+
+The
+.meta from
+and
+.meta to
+index arguments follow the same range indexing conventions as the
+.meta replace
+and
+.meta sub
+functions.
+If
+.meta from
+is omitted, it defaults to zero.
+If
+.meta to
+is omitted, it defaults to the length of
+.metn vec .
+Negative values of
+.meta from
+and
+.meta to
+are adjusted by adding the length of the vector to them, once.
+
+If the adjusted value of either
+.meta from
+or
+.meta to
+is negative, or exceeds the length of
+.metn vec ,
+an error exception is thrown.
+
+The adjusted values of
+.meta to
+and
+.meta from
+specify a range of vec starting at the
+.meta from
+index, and ending at the
+.meta to
+index, which is excluded from the range.
+
+If the adjusted
+.meta to
+is less than or equal to the adjusted
+.metn from ,
+then
+.meta vec
+is unaltered.
+
+Otherwise, copies of element are stored into
+.meta vec
+starting at the
+.meta from
+index, ending just before the the
+.meta to
+index is reached.
+
+The
+.code fill-vec
+function returns
+.metn vec .
+
+.TP* Examples:
+
+.verb
+ (defvarl v (vec 1 2 3))
+
+ v --> #(1 2 3)
+
+ (fill-vec v 0) --> #(0 0 0)
+
+ (fill-vec v 3 1) --> #(0 3 3)
+
+ (fill-vec v 4 -1) --> #(0 3 4)
+
+ (fill-vec v 5 -3 -1) --> #(5 5 4)
+.brev
+
.coNP Function @ cat-vec
.synb
.mets (cat-vec << vec-list )