diff options
-rw-r--r-- | ChangeLog | 14 | ||||
-rw-r--r-- | eval.c | 6 | ||||
-rw-r--r-- | lib.c | 51 | ||||
-rw-r--r-- | lib.h | 1 | ||||
-rw-r--r-- | txr.1 | 9 |
5 files changed, 69 insertions, 12 deletions
@@ -1,5 +1,19 @@ 2014-01-21 Kaz Kylheku <kaz@kylheku.com> + * eval.c (mapcarv, mappendv): Convert output to type of leftmost + input sequence. + + * lib.c (make_like): New function. + (reverse, remq, remql, remqual, remove_if, keep_if, mapcar, mapcon, + mappend, set_diff): Convert output list to type of leftmost input + sequence. + + * lib.h (make_like): Declared. + + * txr.1: Documented. + +2014-01-21 Kaz Kylheku <kaz@kylheku.com> + * lib.c (car, cdr, ldiff): Extend to handle vectors and strings. Thereby, numerous previously list-only operations in TXR Lisp now magically handle strings and vectors. @@ -1828,6 +1828,7 @@ val mapcarv(val fun, val list_of_lists) return mapcar(fun, car(list_of_lists)); } else { val lofl = copy_list(list_of_lists); + val list_orig = car(list_of_lists); list_collect_decl (out, otail); for (;;) { @@ -1837,7 +1838,7 @@ val mapcarv(val fun, val list_of_lists) for (iter = lofl; iter; iter = cdr(iter)) { val list = car(iter); if (!list) - return out; + return make_like(out, list_orig); list_collect(atail, car(list)); *car_l(iter) = cdr(list); } @@ -1853,6 +1854,7 @@ static val mappendv(val fun, val list_of_lists) return mappend(fun, car(list_of_lists)); } else { val lofl = copy_list(list_of_lists); + val list_orig = car(list_of_lists); list_collect_decl (out, otail); for (;;) { @@ -1862,7 +1864,7 @@ static val mappendv(val fun, val list_of_lists) for (iter = lofl; iter; iter = cdr(iter)) { val list = car(iter); if (!list) - return out; + return make_like(out, list_orig); list_collect(atail, car(list)); *car_l(iter) = cdr(list); } @@ -404,6 +404,27 @@ val copy_list(val list) return out; } +val make_like(val list, val thatobj) +{ + if (list != thatobj) { + switch (type(thatobj)) { + case VEC: + return list_vector(list); + case STR: + case LIT: + case LSTR: + return cat_str(list, nil); + case NIL: + case CONS: + case LCONS: + default: + break; + } + } + + return list; +} + val nreverse(val in) { val rev = nil; @@ -420,6 +441,7 @@ val nreverse(val in) val reverse(val in) { + val in_orig = in; val rev = nil; while (in) { @@ -427,7 +449,7 @@ val reverse(val in) in = cdr(in); } - return rev; + return make_like(rev, in_orig); } val append2(val list1, val list2) @@ -673,6 +695,7 @@ val memqual(val obj, val list) val remq(val obj, val list) { list_collect_decl (out, ptail); + val list_orig = list; val lastmatch = cons(nil, list); for (; list; list = cdr(list)) { @@ -682,12 +705,13 @@ val remq(val obj, val list) } } list_collect_nconc(ptail, cdr(lastmatch)); - return out; + return make_like(out, list_orig); } val remql(val obj, val list) { list_collect_decl (out, ptail); + val list_orig = list; val lastmatch = cons(nil, list); for (; list; list = cdr(list)) { @@ -697,12 +721,13 @@ val remql(val obj, val list) } } list_collect_nconc(ptail, cdr(lastmatch)); - return out; + return make_like(out, list_orig); } val remqual(val obj, val list) { list_collect_decl (out, ptail); + val list_orig = list; val lastmatch = cons(nil, list); for (; list; list = cdr(list)) { @@ -712,12 +737,13 @@ val remqual(val obj, val list) } } list_collect_nconc(ptail, cdr(lastmatch)); - return out; + return make_like(out, list_orig); } val remove_if(val pred, val list, val key) { list_collect_decl (out, ptail); + val list_orig = list; val lastmatch = cons(nil, list); if (!key) @@ -733,12 +759,13 @@ val remove_if(val pred, val list, val key) } } list_collect_nconc(ptail, cdr(lastmatch)); - return out; + return make_like(out, list_orig); } val keep_if(val pred, val list, val key) { list_collect_decl (out, ptail); + val list_orig = list; val lastmatch = cons(nil, list); if (!key) @@ -754,7 +781,7 @@ val keep_if(val pred, val list, val key) } } list_collect_nconc(ptail, cdr(lastmatch)); - return out; + return make_like(out, list_orig); } static val rem_lazy_rec(val obj, val list, val env, val func); @@ -4320,31 +4347,34 @@ val copy_alist(val list) val mapcar(val fun, val list) { list_collect_decl (out, iter); + val list_orig = list; for (; list; list = cdr(list)) list_collect (iter, funcall1(fun, car(list))); - return out; + return make_like(out, list_orig); } val mapcon(val fun, val list) { list_collect_decl (out, iter); + val list_orig = list; for (; list; list = cdr(list)) list_collect_nconc (iter, funcall1(fun, list)); - return out; + return make_like(out, list_orig); } val mappend(val fun, val list) { list_collect_decl (out, iter); + val list_orig = list; for (; list; list = cdr(list)) list_collect_append (iter, funcall1(fun, car(list))); - return out; + return make_like(out, list_orig); } val merge(val list1, val list2, val lessfun, val keyfun) @@ -4547,6 +4577,7 @@ val find_if(val pred, val list, val key) val set_diff(val list1, val list2, val testfun, val keyfun) { list_collect_decl (out, ptail); + val list_orig = list1; if (!keyfun) keyfun = identity_f; @@ -4568,7 +4599,7 @@ val set_diff(val list1, val list2, val testfun, val keyfun) } } - return out; + return make_like(out, list_orig); } val length(val seq) @@ -373,6 +373,7 @@ val *ltail(val *cons); val pop(val *plist); val push(val v, val *plist); val copy_list(val list); +val make_like(val list, val thatobj); val nreverse(val in); val reverse(val in); val append2(val list1, val list2); @@ -5037,6 +5037,15 @@ The ldiff operation starts with "abcd" and repeatedly applies cdr to produce Operations based on car, cdr and ldiff, such as keep-if and remq extend to strings and vectors. +Derived list processing operations such as remq or mapcar obey the following +rule: the returned object follows the type of the leftmost input list object. +For instance, if one or more sequences are processed by mapcar, and the +leftmost one is a character string, the function is expected to return +characters, which are converted to a character string. + +The lazy versions of these functions such as mapcar* do not have this behavior; +they produce lazy lists. + .SH CONTROL FLOW AND SEQUENCING When the first element of a compound expression is an operator symbol, |