summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-01-15 20:15:21 -0800
committerKaz Kylheku <kaz@kylheku.com>2014-01-15 20:15:21 -0800
commita0d5ba9831cf2a33144337ab8f0e6f2fd1e6f0cb (patch)
tree2f76ab09e600c2908f70232b6d9e5445f4804083
parent9ddfef0aa6718731db7823c20c5ff21be4311197 (diff)
downloadtxr-a0d5ba9831cf2a33144337ab8f0e6f2fd1e6f0cb.tar.gz
txr-a0d5ba9831cf2a33144337ab8f0e6f2fd1e6f0cb.tar.bz2
txr-a0d5ba9831cf2a33144337ab8f0e6f2fd1e6f0cb.zip
* eval.c (append_each_s, append_each_star_s): New symbol variables.
(op_each, expand): Support append-each and append-each*. (eval_init): Initialize new symbol variables, and register new operators. * txr.1: Document append-each and append-each*.
-rw-r--r--ChangeLog9
-rw-r--r--eval.c15
-rw-r--r--txr.136
3 files changed, 45 insertions, 15 deletions
diff --git a/ChangeLog b/ChangeLog
index fe500cfe..378961d5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2014-01-15 Kaz Kylheku <kaz@kylheku.com>
+
+ * eval.c (append_each_s, append_each_star_s): New symbol variables.
+ (op_each, expand): Support append-each and append-each*.
+ (eval_init): Initialize new symbol variables, and register
+ new operators.
+
+ * txr.1: Document append-each and append-each*.
+
2014-01-14 Kaz Kylheku <kaz@kylheku.com>
* txr.1: Wrote missing documentation for throw, throwf and error.
diff --git a/eval.c b/eval.c
index 6bb4b5d9..3e51f600 100644
--- a/eval.c
+++ b/eval.c
@@ -79,6 +79,7 @@ val cond_s, if_s, defvar_s, defun_s;
val inc_s, dec_s, push_s, pop_s, flip_s, gethash_s, car_s, cdr_s;
val del_s, vecref_s;
val for_s, for_star_s, each_s, each_star_s, collect_each_s, collect_each_star_s;
+val append_each_s, append_each_star_s;
val dohash_s;
val uw_protect_s, return_s, return_from_s;
val list_s, append_s, apply_s, gen_s, generate_s, rest_s;
@@ -617,8 +618,11 @@ static val op_each(val form, val env)
val args = rest(form);
val vars = first(args);
val body = rest(args);
- val star = or2(eq(each, each_star_s), eq(each, collect_each_star_s));
+ val star = or3(eq(each, each_star_s),
+ eq(each, collect_each_star_s),
+ eq(each, append_each_star_s));
val collect = or2(eq(each, collect_each_s), eq(each, collect_each_star_s));
+ val append = or2(eq(each, append_each_s), eq(each, append_each_star_s));
val new_bindings = bindings_helper(vars, env, star, form);
val lists = mapcar(cdr_f, new_bindings);
list_collect_decl (collection, ptail);
@@ -643,6 +647,8 @@ static val op_each(val form, val env)
val res = eval_progn(body, make_env(new_bindings, nil, env), form);
if (collect)
list_collect(ptail, res);
+ else if (append)
+ list_collect_nconc(ptail, res);
}
}
@@ -1675,7 +1681,8 @@ val expand(val form)
if (sym == let_s || sym == let_star_s || sym == lambda_s ||
sym == each_s || sym == each_star_s || sym == collect_each_s ||
- sym == collect_each_star_s)
+ sym == collect_each_star_s || sym == append_each_s ||
+ sym == append_each_star_s)
{
val body = rest(rest(form));
val vars = second(form);
@@ -2212,6 +2219,8 @@ void eval_init(void)
each_star_s = intern(lit("each*"), user_package);
collect_each_s = intern(lit("collect-each"), user_package);
collect_each_star_s = intern(lit("collect-each*"), user_package);
+ append_each_s = intern(lit("append-each"), user_package);
+ append_each_star_s = intern(lit("append-each*"), user_package);
dohash_s = intern(lit("dohash"), user_package);
uw_protect_s = intern(lit("unwind-protect"), user_package);
return_s = intern(lit("return"), user_package);
@@ -2245,6 +2254,8 @@ void eval_init(void)
sethash(op_table, each_star_s, cptr((mem_t *) op_each));
sethash(op_table, collect_each_s, cptr((mem_t *) op_each));
sethash(op_table, collect_each_star_s, cptr((mem_t *) op_each));
+ sethash(op_table, append_each_s, cptr((mem_t *) op_each));
+ sethash(op_table, append_each_star_s, cptr((mem_t *) op_each));
sethash(op_table, let_star_s, cptr((mem_t *) op_let));
sethash(op_table, lambda_s, cptr((mem_t *) op_lambda));
sethash(op_table, call_s, cptr((mem_t *) op_call));
diff --git a/txr.1 b/txr.1
index 42255176..b4ab6814 100644
--- a/txr.1
+++ b/txr.1
@@ -5702,7 +5702,7 @@ and processing resumes at step 2.
Furthermore, the for operators establish an anonymous block,
allowing the return operator to be used to terminate at any point.
-.SS Operators each, each*, collect-each and collect-each*
+.SS Operators each, each*, collect-each, collect-each*, append-each and append-each*
.TP
Syntax:
@@ -5711,6 +5711,8 @@ Syntax:
(each* ({(<sym> <init-form>)}*) <body-form>*)
(collect-each ({(<sym> <init-form>)}*) <body-form>*)
(collect-each* ({(<sym> <init-form>)}*) <body-form>*)
+ (append-each ({(<sym> <init-form>)}*) <body-form>*)
+ (append-each* ({(<sym> <init-form>)}*) <body-form>*)
.TP
Description:
@@ -5728,18 +5730,26 @@ the return value.
The collect-each and collect-each* variants are like each and each*,
except that for each iteration, the resulting value of the body is collected
-into a list. When the iteration terminates, the return value is this
-collection.
-
-The alternate forms denoted by the adorned symbols each* and collect-each*
-variants differ from each and collect-each in the following way. The plain
-forms evaluate the <init-form>-s in an environment in which none of the <sym>
-variables are yet visible. By contrast, the alternate forms evaluate each
-<init-form> in an environment in which bindings for the previous <sym>
-variables are visible. In this phase of evaluation, <sym> variables are
-list-valued: one by one they are each bound to the list object emanating from
-their corresponding <init-form>. Just before the first loop iteration, however,
-the <sym> variables are assigned the first item from each of their lists.
+into a list. When the iteration terminates, the return value of the
+collect-each or collect-each* operator is this collection.
+
+The append-each and append-each* variants are like each and each*,
+except that for each iteration other than the last, the resulting value of the
+body must be a list. The last iteration may produce either an atom or a list.
+The objects produced by the iterations are combined together as if they
+were arguments to the append function, and the resulting value is the
+value of the append-each or append-each* operator.
+
+The alternate forms denoted by the adorned symbols each*, collect-each* and
+append-each*, variants differ from each, collect-each and append-each* in the
+following way. The plain forms evaluate the <init-form>-s in an environment in
+which none of the <sym> variables are yet visible. By contrast, the alternate
+forms evaluate each <init-form> in an environment in which bindings for the
+previous <sym> variables are visible. In this phase of evaluation, <sym>
+variables are list-valued: one by one they are each bound to the list object
+emanating from their corresponding <init-form>. Just before the first loop
+iteration, however, the <sym> variables are assigned the first item from each
+of their lists.
.TP
Examples: