summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2012-05-17 20:39:21 -0700
committerKaz Kylheku <kaz@kylheku.com>2012-05-17 20:39:21 -0700
commit338fa0de2bb5c943775278eef608ce21723cde19 (patch)
tree8ee038310c988cdb43f4d9c7543c351c1fe1d24f
parentf1d3884b7492e8c08f964b893153d6b2b5b44361 (diff)
downloadtxr-338fa0de2bb5c943775278eef608ce21723cde19.tar.gz
txr-338fa0de2bb5c943775278eef608ce21723cde19.tar.bz2
txr-338fa0de2bb5c943775278eef608ce21723cde19.zip
* match.c (v_collect): Implemented semantics for repeat symbol.
(dir_tables_init): Register dispatch for repeat to v_collect function. * parser.y (collect_repeat): New nonterminal symbol. (clause): Removed repeat_clause error case because that now clashes with the syntax in collect_clause. (collect_clause): Repeat syntax implemented, with help of collect_repeat. (out_clause): Error case for collect_clause removed due to syntactic clash. * txr.1: Added mention of @(collect :vars nil) and documented @(repeat) as the shorthand.
-rw-r--r--ChangeLog17
-rw-r--r--match.c12
-rw-r--r--parser.y23
-rw-r--r--txr.119
4 files changed, 59 insertions, 12 deletions
diff --git a/ChangeLog b/ChangeLog
index 6375a737..1585018d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,22 @@
2012-05-17 Kaz Kylheku <kaz@kylheku.com>
+ * match.c (v_collect): Implemented semantics for repeat symbol.
+ (dir_tables_init): Register dispatch for repeat to v_collect
+ function.
+
+ * parser.y (collect_repeat): New nonterminal symbol.
+ (clause): Removed repeat_clause error case because that now clashes
+ with the syntax in collect_clause.
+ (collect_clause): Repeat syntax implemented, with help of
+ collect_repeat.
+ (out_clause): Error case for collect_clause removed due to
+ syntactic clash.
+
+ * txr.1: Added mention of @(collect :vars nil) and documented
+ @(repeat) as the shorthand.
+
+2012-05-17 Kaz Kylheku <kaz@kylheku.com>
+
* configure: Do not capture the stderr of GNU Make in the
configure step; send it to /dev/null.
diff --git a/match.c b/match.c
index b85488e7..9964bd83 100644
--- a/match.c
+++ b/match.c
@@ -2617,6 +2617,7 @@ static val v_gather(match_files_ctx *c)
static val v_collect(match_files_ctx *c)
{
spec_bind (specline, first_spec, c->spec);
+ val op_sym = first(first_spec);
val coll_spec = second(first_spec);
val until_last_spec = third(first_spec);
val args = fourth(first_spec);
@@ -2644,7 +2645,15 @@ static val v_collect(match_files_ctx *c)
val iter;
if (gap && (max || min))
- sem_error(specline, lit("collect: cannot mix :gap with :mingap or :maxgap"), nao);
+ sem_error(specline, lit("~s: cannot mix :gap with :mingap or :maxgap"),
+ op_sym, nao);
+
+ if (op_sym == repeat_s) {
+ if (have_vars)
+ sem_error(specline, lit("~s: collect takes :vars, repeat does not"),
+ op_sym, nao);
+ have_vars = t;
+ }
vars = vars_to_bindings(specline, vars, c->bindings);
@@ -3787,6 +3796,7 @@ static void dir_tables_init(void)
sethash(v_directive_table, choose_s, cptr((mem_t *) v_parallel));
sethash(v_directive_table, gather_s, cptr((mem_t *) v_gather));
sethash(v_directive_table, collect_s, cptr((mem_t *) v_collect));
+ sethash(v_directive_table, repeat_s, cptr((mem_t *) v_collect));
sethash(v_directive_table, flatten_s, cptr((mem_t *) v_flatten));
sethash(v_directive_table, forget_s, cptr((mem_t *) v_forget_local));
sethash(v_directive_table, local_s, cptr((mem_t *) v_forget_local));
diff --git a/parser.y b/parser.y
index 46a0052b..c71ddce7 100644
--- a/parser.y
+++ b/parser.y
@@ -82,6 +82,7 @@ static val parsed_spec;
%type <val> spec clauses clauses_opt clause
%type <val> all_clause some_clause none_clause maybe_clause block_clause
%type <val> cases_clause choose_clause gather_clause collect_clause until_last
+%type <val> collect_repeat
%type <val> clause_parts additional_parts gather_parts additional_gather_parts
%type <val> output_clause define_clause try_clause catch_clauses_opt
%type <val> line elems_opt elems clause_parts_h additional_parts_h
@@ -143,8 +144,6 @@ clause : all_clause { $$ = cons($1, nil); rlcp($$, $1); }
| try_clause { $$ = cons($1, nil); rlcp($$, $1); }
| output_clause { $$ = cons($1, nil); rlcp($$, $1); }
| line { $$ = $1; }
- | repeat_clause { $$ = nil;
- yyerror("repeat outside of output"); }
;
all_clause : ALL newl clause_parts { $$ = list(all_s, $3, nao);
@@ -260,19 +259,19 @@ additional_gather_parts : AND newl clauses additional_gather_parts { $$ = c
| /* empty */ { $$ = nil; }
;
-collect_clause : COLLECT exprs_opt ')' newl
- clauses END newl { $$ = list(collect_s,
+collect_clause : collect_repeat exprs_opt ')' newl
+ clauses END newl { $$ = list(car($1),
$5, nil, $2,
nao);
- rl($$, num($1)); }
- | COLLECT exprs_opt ')'
+ rl($$, cdr($1)); }
+ | collect_repeat exprs_opt ')'
newl clauses until_last
- newl clauses END newl { $$ = list(collect_s, $5,
+ newl clauses END newl { $$ = list(car($1), $5,
cons(cdr($6), $8),
$2, nao);
- rl($$, num($1));
+ rl($$, cdr($1));
rl($8, car($6)); }
- | COLLECT exprs_opt ')'
+ | collect_repeat exprs_opt ')'
newl error { $$ = nil;
if (yychar == UNTIL ||
yychar == END ||
@@ -283,6 +282,10 @@ collect_clause : COLLECT exprs_opt ')' newl
lit("collect clause")); }
;
+collect_repeat : COLLECT { $$ = cons(collect_s, num($1)); }
+ | REPEAT { $$ = cons(repeat_s, num($1)); }
+ ;
+
until_last : UNTIL { $$ = cons(num($1), until_s); }
| LAST { $$ = cons(num($1), last_s); }
;
@@ -494,8 +497,6 @@ out_clause : repeat_clause { $$ = cons($1, nil); }
yyerror("match clause in output"); }
| choose_clause { $$ = nil;
yyerror("choose clause in output"); }
- | collect_clause { $$ = nil;
- yyerror("match clause in output"); }
| define_clause { $$ = nil;
yyerror("match clause in output"); }
diff --git a/txr.1 b/txr.1
index f2531d02..057c27d1 100644
--- a/txr.1
+++ b/txr.1
@@ -2111,6 +2111,13 @@ or with an until or last clause:
... lines of subquery: last clause
@(end)
+The repeat symbol may be specified instead of collect, which changes
+the meaning, see below:
+
+ @(repeat)
+ ... lines of subquery
+ @(end)
+
The subquery is matched repeatedly, starting at the current line.
If it fails to match, it is tried starting at the subsequent line.
If it matches successfully, it is tried at the line following the
@@ -2369,6 +2376,18 @@ an empty list.
@a
@(end)
+The following means: do not allow any variables to propagate out of any
+iteration of the collect and therefore collect nothing:
+
+ @(collect :vars nil)
+ ...
+ @(end)
+
+Instead of writing @(collect :vars nil), it is possible to write
+@(repeat). @(repeat) takes all collect keywords, except for :vars.
+There is a repeat directive used in @(output) clauses; that is
+a different repeat directive.
+
.SS The Coll Directive
The coll directive is a kind of miniature version of the collect directive.