diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2015-11-17 06:41:38 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2015-11-20 16:17:18 -0800 |
commit | a25862d24050e8ff6e8eb1077715abac4afe5ff4 (patch) | |
tree | 7b292a9cb0866475ceedca6737b323b06e8d5dd9 | |
parent | 559c24b4900f70e893902dbac99d7a8a113fb6f0 (diff) | |
download | txr-a25862d24050e8ff6e8eb1077715abac4afe5ff4.tar.gz txr-a25862d24050e8ff6e8eb1077715abac4afe5ff4.tar.bz2 txr-a25862d24050e8ff6e8eb1077715abac4afe5ff4.zip |
@(rep) as shorthand for @(coll :vars nil).
* match.c (h_coll): Check for rep symbol, and handle similarly
to v_coll. Use symbol in error message.
(dir_tables_init): Bind rep symbol to h_coll.
* parser.y (elems): Don't generate rep_elem phrase structure
for the sake of catching "rep outside of output"; this
production now conflicts with the intent to allow this.
(elem): Add various REP productions which clones of COLL.
* txr.1: Documented new @(rep) usage.
-rw-r--r-- | match.c | 13 | ||||
-rw-r--r-- | parser.y | 11 | ||||
-rw-r--r-- | txr.1 | 22 |
3 files changed, 41 insertions, 5 deletions
@@ -808,6 +808,7 @@ static val h_skip(match_line_ctx *c) static val h_coll(match_line_ctx *c) { val elem = first(c->specline); + val op_sym = first(elem); val coll_specline = second(elem); val until_last_specline = third(elem); val args = fourth(elem); @@ -833,6 +834,13 @@ static val h_coll(match_line_ctx *c) cnum timescounter = 0, charscounter = 0; val iter; + if (op_sym == rep_s) { + if (have_vars) + sem_error(elem, lit("~s: coll takes :vars, rep does not"), + op_sym, nao); + have_vars = t; + } + vars = vars_to_bindings(elem, vars, c->bindings); if (((times || maxtimes) && ctimax == 0) || (chars && cchars == 0)) @@ -893,8 +901,8 @@ static val h_coll(match_line_ctx *c) } if (have_new && missing) - sem_error(elem, lit("collect failed to bind ~a"), - missing, nao); + sem_error(elem, lit("~s failed to bind ~a"), + op_sym, missing, nao); for (iter = strictly_new_bindings; iter; iter = cdr(iter)) { @@ -4192,6 +4200,7 @@ static void dir_tables_init(void) sethash(h_directive_table, var_s, cptr(coerce(mem_t *, h_var))); sethash(h_directive_table, skip_s, cptr(coerce(mem_t *, h_skip))); sethash(h_directive_table, coll_s, cptr(coerce(mem_t *, h_coll))); + sethash(h_directive_table, rep_s, cptr(coerce(mem_t *, h_coll))); sethash(h_directive_table, flatten_s, cptr(coerce(mem_t *, hv_trampoline))); sethash(h_directive_table, forget_s, cptr(coerce(mem_t *, hv_trampoline))); sethash(h_directive_table, local_s, cptr(coerce(mem_t *, hv_trampoline))); @@ -387,8 +387,6 @@ elems : elem { $$ = cons($1, nil); rlcp($$, $1); } | elem elems { $$ = cons($1, $2); rlcp($$, $1); } - | rep_elem { $$ = nil; - yyerr("rep outside of output"); } ; @@ -429,8 +427,17 @@ elem : texts { $$ = rlcp(cons(text_s, $1), $1); $2, nao); rl($$, num($1)); rl($6, car($5)); } + | REP exprs_opt ')' elems END { $$ = list(rep_s, $4, nil, $2, nao); + rl($$, num($1)); } + | REP exprs_opt ')' elems + until_last elems END { $$ = list(rep_s, $4, cons(cdr($5), $6), + $2, nao); + rl($$, num($1)); + rl($6, car($5)); } | COLL error { $$ = nil; yybadtok(yychar, lit("coll clause")); } + | REP error { $$ = nil; + yybadtok(yychar, lit("rep clause")); } | ALL clause_parts_h { $$ = rl(list(all_s, t, $2, nao), num($1)); } | ALL END { yyerr("empty all clause"); } | SOME exprs_opt ')' @@ -3011,7 +3011,13 @@ understood in an output clause. A directive understood within an @(output) section, for repeating multi-line text, with successive substitutions pulled from lists. The directive .code @(rep) -produces iteration over lists horizontally within one line. +produces iteration over lists horizontally within one line. These directives +have a different meaning in matching clauses, providing a shorthand +notation for +.code @(repeat :vars nil) +and +.codn "@(rep :vars nil)" , +respectively. .coIP @(deffilter) This directive is used for defining named filters, which are useful @@ -5107,6 +5113,20 @@ an analogous .code :chars keyword. +The +.code @(coll) +directive takes the +.code :vars +keyword. + +The shorthand +.code @(rep) +may be used instead of +.codn "@(coll :vars nil)" . +.code @(rep) +takes all keywords, except +.codn :vars . + .dir flatten The |