summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2015-11-17 06:41:38 -0800
committerKaz Kylheku <kaz@kylheku.com>2015-11-20 16:17:18 -0800
commita25862d24050e8ff6e8eb1077715abac4afe5ff4 (patch)
tree7b292a9cb0866475ceedca6737b323b06e8d5dd9
parent559c24b4900f70e893902dbac99d7a8a113fb6f0 (diff)
downloadtxr-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.c13
-rw-r--r--parser.y11
-rw-r--r--txr.122
3 files changed, 41 insertions, 5 deletions
diff --git a/match.c b/match.c
index 1577b735..71ea60c2 100644
--- a/match.c
+++ b/match.c
@@ -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)));
diff --git a/parser.y b/parser.y
index cd351bbd..00bf0adf 100644
--- a/parser.y
+++ b/parser.y
@@ -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 ')'
diff --git a/txr.1 b/txr.1
index dbb819d9..45d49946 100644
--- a/txr.1
+++ b/txr.1
@@ -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