summaryrefslogtreecommitdiffstats
path: root/match.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2011-11-17 22:06:10 -0800
committerKaz Kylheku <kaz@kylheku.com>2011-11-17 22:06:10 -0800
commitf55237951cd029bdfe40346c52060a8ed59bb49e (patch)
treeb4ab13970cc6c317415f366740a75df86f8f4638 /match.c
parentdf70e45dae4adccca01441e0911d2f5e114e8e7f (diff)
downloadtxr-f55237951cd029bdfe40346c52060a8ed59bb49e.tar.gz
txr-f55237951cd029bdfe40346c52060a8ed59bb49e.tar.bz2
txr-f55237951cd029bdfe40346c52060a8ed59bb49e.zip
Task #11598.
* match.c (resolve_k): New keyword symbol variable. (h_parallel, v_parallel): Implement :resolve keyword in @(some) directive. (syms_init): New symbol variable initialized. * parser.l: Allow (some) to have argument material. * parser.y (some_clause, elem): SOME syntax adjusted. * txr.1: Documented new :resolve keyword in @(some).
Diffstat (limited to 'match.c')
-rw-r--r--match.c62
1 files changed, 61 insertions, 1 deletions
diff --git a/match.c b/match.c
index a4efdf4b..f5d23760 100644
--- a/match.c
+++ b/match.c
@@ -56,7 +56,7 @@ val mingap_k, maxgap_k, gap_k, mintimes_k, maxtimes_k, times_k;
val lines_k, chars_k;
val choose_s, gather_s;
val longest_k, shortest_k, greedy_k;
-val vars_k;
+val vars_k, resolve_k;
val append_k, into_k, var_k, list_k, string_k, env_k;
val filter_s;
@@ -843,6 +843,9 @@ static val h_parallel(match_line_ctx c, match_line_ctx *cout)
val choose_sym = or2(choose_longest, choose_shortest);
val choose_bindings = c.bindings, choose_pos = c.pos;
val choose_minmax = choose_longest ? num(-1) : num(NUM_MAX);
+ val resolve = getplist(plist, resolve_k);
+ val resolve_ub_vars = nil;
+ val resolve_bindings = nil;
val iter;
if (choose_longest && choose_shortest)
@@ -850,6 +853,16 @@ static val h_parallel(match_line_ctx c, match_line_ctx *cout)
if (directive == choose_s && !choose_sym)
sem_error(elem, lit("choose: criterion not specified"), nao);
+
+
+ if (resolve) {
+ for (iter = resolve; iter; iter = cdr(iter)) {
+ val var = car(iter);
+ if (!assoc(c.bindings, var))
+ push(var, &resolve_ub_vars);
+ }
+ }
+
for (iter = specs; iter != nil; iter = cdr(iter)) {
val nested_spec = first(iter);
cons_bind (new_bindings, new_pos,
@@ -857,8 +870,23 @@ static val h_parallel(match_line_ctx c, match_line_ctx *cout)
if (new_pos) {
some_match = t;
+
+ if (resolve_ub_vars) {
+ val uiter;
+ for (uiter = resolve_ub_vars; uiter; uiter = cdr(uiter)) {
+ val ubvar = car(uiter);
+ val exists = assoc(new_bindings, ubvar);
+
+ if (exists)
+ resolve_bindings = acons_new(resolve_bindings, ubvar, cdr(exists));
+ }
+
+ new_bindings = alist_remove(new_bindings, resolve_ub_vars);
+ }
+
if (gt(new_pos, max_pos))
max_pos = new_pos;
+
if (directive == choose_s) {
val binding = choose_sym ? assoc(new_bindings, choose_sym) : nil;
val value = cdr(binding);
@@ -903,6 +931,10 @@ static val h_parallel(match_line_ctx c, match_line_ctx *cout)
/* No check for maybe, since it always succeeds. */
+
+ if (resolve_bindings)
+ c.bindings = nappend2(resolve_bindings, c.bindings);
+
if (directive == choose_s) {
c.bindings = choose_bindings;
c.pos = choose_pos;
@@ -1987,6 +2019,9 @@ static val v_parallel(match_files_ctx *c)
val choose_sym = or2(choose_longest, choose_shortest);
val choose_bindings = c->bindings, choose_line = zero, choose_data = nil;
val choose_minmax = choose_longest ? num(-1) : num(NUM_MAX);
+ val resolve = getplist(plist, resolve_k);
+ val resolve_ub_vars = nil;
+ val resolve_bindings = nil;
val iter;
if (choose_longest && choose_shortest)
@@ -1995,6 +2030,14 @@ static val v_parallel(match_files_ctx *c)
if (sym == choose_s && !choose_sym)
sem_error(specline, lit("choose: criterion not specified"), nao);
+ if (resolve) {
+ for (iter = resolve; iter; iter = cdr(iter)) {
+ val var = car(iter);
+ if (!assoc(c->bindings, var))
+ push(var, &resolve_ub_vars);
+ }
+ }
+
for (iter = specs; iter != nil; iter = rest(iter))
{
val nested_spec = first(iter);
@@ -2004,6 +2047,19 @@ static val v_parallel(match_files_ctx *c)
if (success) {
some_match = t;
+ if (resolve_ub_vars) {
+ val uiter;
+ for (uiter = resolve_ub_vars; uiter; uiter = cdr(uiter)) {
+ val ubvar = car(uiter);
+ val exists = assoc(new_bindings, ubvar);
+
+ if (exists)
+ resolve_bindings = acons_new(resolve_bindings, ubvar, cdr(exists));
+ }
+
+ new_bindings = alist_remove(new_bindings, resolve_ub_vars);
+ }
+
if (sym == choose_s) {
val binding = choose_sym ? assoc(new_bindings, choose_sym) : nil;
val value = cdr(binding);
@@ -2067,6 +2123,9 @@ static val v_parallel(match_files_ctx *c)
/* No check for maybe, since it always succeeds. */
+ if (resolve_bindings)
+ c->bindings = nappend2(resolve_bindings, c->bindings);
+
if (choose_sym) {
if (consp(choose_data)) {
c->data_lineno = choose_line;
@@ -3178,6 +3237,7 @@ static void syms_init(void)
shortest_k = intern(lit("shortest"), keyword_package);
greedy_k = intern(lit("greedy"), keyword_package);
vars_k = intern(lit("vars"), keyword_package);
+ resolve_k = intern(lit("resolve"), keyword_package);
append_k = intern(lit("append"), keyword_package);
into_k = intern(lit("into"), keyword_package);
var_k = intern(lit("var"), keyword_package);