summaryrefslogtreecommitdiffstats
path: root/match.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2020-07-07 23:43:08 -0700
committerKaz Kylheku <kaz@kylheku.com>2020-07-07 23:43:08 -0700
commitfa3c90eb3ac48abd8bb9065884fe15523a864766 (patch)
treec96e5c01207325af768cba0032f3a47184d15f20 /match.c
parentcb31c444c367ffe950cffae7adca5a3ec024620a (diff)
downloadtxr-fa3c90eb3ac48abd8bb9065884fe15523a864766.tar.gz
txr-fa3c90eb3ac48abd8bb9065884fe15523a864766.tar.bz2
txr-fa3c90eb3ac48abd8bb9065884fe15523a864766.zip
txr: support @(if)/@(elif)/@(else) in @(output).
This turns out to be way easier than I thought. * match.c (do_output_if): New static function. (do_output): Handle if via do_output_if. * parser.y (out_if_clause, out_elif_clauses_opt, out_else_clause_opt): New nonterminal symbols and grammar rules. (out_clause): Now produces out_if_clause. (not_a_clause): Remove ELIF and ELSE; these entries here cause conflicts now. Here, continue to recognize the Lisp if, which is distinguished by having at least two arguments. out_if_clause matches only a one-argument if, and a no-argumeent one that is diagnosed as erroneous. * txr.1: Documented.
Diffstat (limited to 'match.c')
-rw-r--r--match.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/match.c b/match.c
index 69bb374f..13c47a54 100644
--- a/match.c
+++ b/match.c
@@ -2234,6 +2234,18 @@ static void do_repeat(val bindings, val repeat_syntax, val filter, val out)
}
}
+static void do_output_if(val bindings, val if_syntax, val filter, val out)
+{
+ val args = cdr(if_syntax);
+
+ for (; args; args = cdr(args)) {
+ cons_bind (expr, specs, car(args));
+ if (tleval(args, expr, bindings)) {
+ do_output(bindings, specs, filter, out);
+ return;
+ }
+ }
+}
void do_output(val bindings, val specs, val filter, val out)
{
@@ -2252,6 +2264,8 @@ void do_output(val bindings, val specs, val filter, val out)
continue;
}
+ if (sym == if_s) {
+ do_output_if(bindings, first_elem, filter, out);
continue;
}
}