summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-07-02 07:04:07 -0700
committerKaz Kylheku <kaz@kylheku.com>2014-07-02 07:04:07 -0700
commitce7f0602f317d02a71ad70e0ce27a0edd8cbde4f (patch)
treea4319042d6d14b7379c7462fd62359ace9933d85 /lib.c
parent4aac1a2a6144d04a047966e295727258bd09a734 (diff)
downloadtxr-ce7f0602f317d02a71ad70e0ce27a0edd8cbde4f.tar.gz
txr-ce7f0602f317d02a71ad70e0ce27a0edd8cbde4f.tar.bz2
txr-ce7f0602f317d02a71ad70e0ce27a0edd8cbde4f.zip
* eval.c (dwim_loc): Support indexing using a list of positions,
such as obtained by the where function. * lib.c (replace_list, replace_str, replace_vec): Allow the from argument to be a list of index positions, possibly empty. * txr.1: Condensed syntactic descriptions under dwim operator. Range Indexing section no longer says that the value nil can be used as either endpoint of a range. This will not work any longer since a "from" value of nil looks like an empty list of indexes. Documented new behavior under replace, and shortened documentation for replace-list, replace-str and replace-vec.
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c75
1 files changed, 65 insertions, 10 deletions
diff --git a/lib.c b/lib.c
index e45902c1..d8ac95e3 100644
--- a/lib.c
+++ b/lib.c
@@ -766,11 +766,32 @@ val replace_list(val list, val items, val from, val to)
if (!list)
return items;
- if (null_or_missing_p(from))
+ if (consp(from)) {
+ val where = from;
+ val seq = list;
+ val idx = zero;
+
+ if (!missingp(to))
+ uw_throwf(error_s,
+ lit("replace-list: to-arg not applicable when from-arg is a list"),
+ nao);
+
+ for (; seq && where && items; seq = cdr(seq), idx = plus(idx, one)) {
+ val wh;
+
+ for (; where && lt(wh = car(where), idx); where = cdr(where))
+ ; /* empty */
+
+ if (eql(wh, idx))
+ rplaca(seq, pop(&items));
+ }
+
+ return list;
+ } else if (null_or_missing_p(from)) {
from = zero;
- else if (from == t)
+ } else if (from == t) {
from = nil;
- else if (lt(from, zero)) {
+ } else if (lt(from, zero)) {
from = plus(from, len ? len : (len = length(list)));
if (to == zero)
to = len;
@@ -2332,11 +2353,28 @@ val replace_str(val str_in, val items, val from, val to)
str_in, typeof(str_in), nao);
}
- if (null_or_missing_p(from))
+ if (consp(from)) {
+ val where = from;
+ val len = length_str(str_in);
+
+ if (!missingp(to))
+ uw_throwf(error_s,
+ lit("replace-str: to-arg not applicable when from-arg is a list"),
+ nao);
+
+ for (; where && items; where = cdr(where)) {
+ val wh = car(where);
+ if (ge(wh, len))
+ break;
+ chr_str_set(str_in, wh, pop(&items));
+ }
+
+ return str_in;
+ } else if (null_or_missing_p(from)) {
from = zero;
- else if (from == t)
+ } else if (from == t) {
from = len;
- else if (lt(from, zero)) {
+ } else if (lt(from, zero)) {
from = plus(from, len);
if (to == zero)
to = len;
@@ -4346,11 +4384,28 @@ val replace_vec(val vec_in, val items, val from, val to)
val len_it = length(it_seq);
val len_rep;
- if (null_or_missing_p(from))
+ if (consp(from)) {
+ val where = from;
+ val len = length_vec(vec_in);
+
+ if (!missingp(to))
+ uw_throwf(error_s,
+ lit("replace-vec: to-arg not applicable when from-arg is a list"),
+ nao);
+
+ for (; where && items; where = cdr(where)) {
+ val wh = car(where);
+ if (ge(wh, len))
+ break;
+ set(vecref_l(vec_in, wh), pop(&items));
+ }
+
+ return vec_in;
+ } else if (null_or_missing_p(from)) {
from = zero;
- else if (from == t)
+ } else if (from == t) {
from = len;
- else if (lt(from, zero)) {
+ } else if (lt(from, zero)) {
from = plus(from, len);
if (to == zero)
to = len;
@@ -5594,7 +5649,7 @@ val sel(val seq_in, val where_in)
val found;
loc pfound = mkcloc(found);
val key = car(where);
- val value = gethash_f(seq, car(where), pfound);
+ val value = gethash_f(seq, key, pfound);
if (found)
sethash(newhash, key, value);