summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-04-03 20:44:41 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-04-03 20:44:41 -0700
commit7d265d9f5e901487dc30a57e64cd604430a378b8 (patch)
treec0bd0075dbfb79228f46919a53dfb735e629e80b
parent1647cb336a10564946274e613ebd921e4c91e899 (diff)
downloadtxr-7d265d9f5e901487dc30a57e64cd604430a378b8.tar.gz
txr-7d265d9f5e901487dc30a57e64cd604430a378b8.tar.bz2
txr-7d265d9f5e901487dc30a57e64cd604430a378b8.zip
apply and iapply bugfix: split sequences into args.
These functions don't conform with the documentation. For instance [apply list "abc"] yields "abc". It is supposed to yield (#\a #\b #\c), since the characters of "abc" must become individual arguments to list. Part of the fix is in the apply_frob_args logic; however, we have to clone that function because it is used for implementing other things which will break: we cannot, for for example, have (list* 1 "ab") producing (1 #\a #\b). * eval.c (apply_intrisic_frob_args): New static function. Differs from apply_frob_args in that it calls tolist on the final element. (apply_intrinsic): Use apply_intrinsic_frob_args instead of apply_frob_args. (iapply): Invoke tolist on the value assigned to last_arg. * txr.1: Add a clarifying note for iapply that the terminating atom is not split into arguments if it is a sequence.
-rw-r--r--eval.c19
-rw-r--r--txr.15
2 files changed, 21 insertions, 3 deletions
diff --git a/eval.c b/eval.c
index fc00a630..1584bd94 100644
--- a/eval.c
+++ b/eval.c
@@ -1106,9 +1106,24 @@ static val apply_frob_args(val args)
}
}
+static val apply_intrinsic_frob_args(val args)
+{
+ if (!cdr(args)) {
+ return tolist(car(args));
+ } else {
+ list_collect_decl (out, ptail);
+
+ for (; cdr(args); args = cdr(args))
+ ptail = list_collect(ptail, car(args));
+
+ list_collect_nconc(ptail, tolist(car(args)));
+ return out;
+ }
+}
+
val apply_intrinsic(val fun, val args)
{
- return apply(fun, apply_frob_args(z(args)));
+ return apply(fun, apply_intrinsic_frob_args(z(args)));
}
static val applyv(val fun, struct args *args)
@@ -1129,7 +1144,7 @@ static val iapply(val fun, struct args *args)
saved_ptail = ptail;
if (args_more(args, index)) {
- last_arg = args_get(args, &index);
+ last_arg = tolist(args_get(args, &index));
ptail = list_collect_nconc(ptail, last_arg);
}
diff --git a/txr.1 b/txr.1
index 09af87bf..4125f9a8 100644
--- a/txr.1
+++ b/txr.1
@@ -27062,7 +27062,10 @@ Secondly, if
.meta trailing-args
is a list, but an improper list, then the terminating atom of
.meta trailing-args
-becomes an ordinary argument. Thus, in all possible cases,
+becomes an individual argument.
+This terminating atom is not split into multiple arguments,
+even if it is a sequence.
+Thus, in all possible cases,
.code iapply
treats an extra
.cod2 non- nil