diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2012-01-06 15:39:33 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2012-01-06 15:39:33 -0800 |
commit | 8cdbb92688207d0d9f3bcd37279f89a2cbcdf7a3 (patch) | |
tree | 96490ccd1ccd4c1c3f71802a59f5a1cdc1790478 | |
parent | b6fdf456e413412aaa7cd132b1f340b5b706eddd (diff) | |
download | txr-8cdbb92688207d0d9f3bcd37279f89a2cbcdf7a3.tar.gz txr-8cdbb92688207d0d9f3bcd37279f89a2cbcdf7a3.tar.bz2 txr-8cdbb92688207d0d9f3bcd37279f89a2cbcdf7a3.zip |
* match.c (v_gather): Implemented until/last clause.
* parser.y (gather_parts, additional_gather_parts): New nonterminals.
(gather_clause): Syntax refactored for until/last clause.
* txr.1: Updated.
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | match.c | 28 | ||||
-rw-r--r-- | parser.y | 23 | ||||
-rw-r--r-- | txr.1 | 16 |
4 files changed, 74 insertions, 2 deletions
@@ -1,3 +1,12 @@ +2012-01-06 Kaz Kylheku <kaz@kylheku.com> + + * match.c (v_gather): Implemented until/last clause. + + * parser.y (gather_parts, additional_gather_parts): New nonterminals. + (gather_clause): Syntax refactored for until/last clause. + + * txr.1: Updated. + 2012-01-02 Kaz Kylheku <kaz@kylheku.com> * eval.c (eval_init): Fix regression introduced in @@ -2312,6 +2312,7 @@ static val v_gather(match_files_ctx *c) spec_bind (specline, first_spec, c->spec); val specs = copy_list(second(first_spec)); val args = third(first_spec); + val until_last = fourth(first_spec); val vars = vars_to_bindings(specline, getplist(args, vars_k), c->bindings); while (specs && c->data) { @@ -2319,6 +2320,7 @@ static val v_gather(match_files_ctx *c) val max_line = zero; val max_data = nil; val iter, next; + val orig_bindings = c->bindings; for (iter = specs, next = cdr(iter); iter != nil; iter = next, next = cdr(iter)) { val nested_spec = first(iter); @@ -2341,6 +2343,32 @@ static val v_gather(match_files_ctx *c) } } + if (until_last) + { + cons_bind (sym, ul_spec, until_last); + cons_bind (until_last_bindings, success, + match_files(mf_spec(*c, ul_spec))); + + if (success) { + debuglf(specline, lit("until/last matched ~a:~a"), + first(c->files), c->data_lineno, nao); + /* Until discards bindings and position, last keeps them. */ + if (sym == last_s) { + val last_bindings = set_diff(until_last_bindings, c->bindings, eq_f, nil); + c->bindings = nappend2(last_bindings, orig_bindings); + + if (success == t) { + c->data = t; + } else { + cons_bind (new_data, new_line, success); + c->data = new_data; + c->data_lineno = new_line; + } + } + break; + } + } + specs = new_specs; if (consp(max_data)) { @@ -82,7 +82,7 @@ static val parsed_spec; %type <val> spec clauses clauses_opt clause %type <val> all_clause some_clause none_clause maybe_clause %type <val> cases_clause choose_clause gather_clause collect_clause until_last -%type <val> clause_parts additional_parts +%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 %type <val> text texts elem var var_op meta_expr vector @@ -208,11 +208,23 @@ choose_clause : CHOOSE exprs_opt ')' ; gather_clause : GATHER exprs_opt ')' - newl clause_parts { $$ = list(gather_s, + newl gather_parts + END newl { $$ = list(gather_s, append2(mapcar(curry_12_1(func_n2(cons), nil), first($5)), rest($5)), $2, nao); rl($$, num($1)); } + + | GATHER exprs_opt ')' + newl gather_parts + until_last newl + clauses + END newl { $$ = list(gather_s, + append2(mapcar(curry_12_1(func_n2(cons), nil), + first($5)), rest($5)), + $2, cons(cdr($6), $8), nao); + rl($$, num($1)); } + | GATHER exprs_opt ')' newl error { $$ = nil; yybadtoken(yychar, @@ -222,6 +234,13 @@ gather_clause : GATHER exprs_opt ')' yyerror("empty gather clause"); } ; +gather_parts : clauses additional_gather_parts { $$ = cons($1, $2); } + ; + +additional_gather_parts : AND newl clauses additional_gather_parts { $$ = cons($3, $4); } + | OR newl clauses additional_parts { $$ = cons($3, $4); } + | /* empty */ { $$ = nil; } + ; collect_clause : COLLECT exprs_opt ')' newl clauses END newl { $$ = list(collect_s, @@ -1829,6 +1829,14 @@ The syntax follows this pattern Of course the multi-line clauses are optional. The gather directive takes keyword parameters, see below. +Similarly to @(collect), @(gather) has an optional until/last clause: + + @(gather) + ... + @(until) + ... + @(end) + How gather works is that the text is searched for matches for the single line and multi-line queries. The clauses are applied in the order in which they appear. Whenever one of the clauses matches, any bindings it produces are retained and @@ -1849,6 +1857,14 @@ order: SHELL=@SHELL @(end) +If the until or last clause is present and a match occurs, then the matches +from the other clauses are discarded and the gather terminates. The difference +between until and last is that any bindings bindings established in last are +retained, and the input position is advanced past the matched material. +The until/last clause has visibility to bindings established in the +previous clauses in that same iteration, even though those bindings +end up thrown away. + .SS Gather Keyword Parameters The gather diretive accepts the keyword parameter :vars. The argument to vars is a list |