diff options
-rw-r--r-- | eval.c | 1 | ||||
-rw-r--r-- | lib.c | 34 | ||||
-rw-r--r-- | lib.h | 1 | ||||
-rw-r--r-- | share/txr/stdlib/doc-syms.tl | 1 | ||||
-rw-r--r-- | tests/010/vec.tl | 32 | ||||
-rw-r--r-- | txr.1 | 88 |
6 files changed, 157 insertions, 0 deletions
@@ -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)); @@ -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"); @@ -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)) @@ -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 ) |