diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2014-01-15 20:15:21 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2014-01-15 20:15:21 -0800 |
commit | a0d5ba9831cf2a33144337ab8f0e6f2fd1e6f0cb (patch) | |
tree | 2f76ab09e600c2908f70232b6d9e5445f4804083 | |
parent | 9ddfef0aa6718731db7823c20c5ff21be4311197 (diff) | |
download | txr-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-- | ChangeLog | 9 | ||||
-rw-r--r-- | eval.c | 15 | ||||
-rw-r--r-- | txr.1 | 36 |
3 files changed, 45 insertions, 15 deletions
@@ -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. @@ -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)); @@ -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: |