summaryrefslogtreecommitdiffstats
path: root/match.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2011-11-26 16:25:39 -0800
committerKaz Kylheku <kaz@kylheku.com>2011-11-26 16:25:39 -0800
commitff9efa28206ca7c6aaaedbe0418106867868d129 (patch)
tree6ed26f6918ccabb3ca2826f5bc329fce910ea044 /match.c
parentbb83f68455149edd0acd6996115de881ed0e77a2 (diff)
downloadtxr-ff9efa28206ca7c6aaaedbe0418106867868d129.tar.gz
txr-ff9efa28206ca7c6aaaedbe0418106867868d129.tar.bz2
txr-ff9efa28206ca7c6aaaedbe0418106867868d129.zip
* match.c (subst_vars): Handle expr_s, so that
Lisp expressions can be interpolated into quasiliterals. (extract_vars): Avoid recursing into expressions marked with expr_s. (do_output_line): Handle expr_s so that Lisp expressions can be interpolated into output. * parser.y (o_elem, quasi_items): Handle list expressions, annotated with expr_s.
Diffstat (limited to 'match.c')
-rw-r--r--match.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/match.c b/match.c
index 4210474f..1eeed66f 100644
--- a/match.c
+++ b/match.c
@@ -1268,7 +1268,9 @@ static val subst_vars(val spec, val bindings, val filter)
val elem = first(spec);
if (consp(elem)) {
- if (first(elem) == var_s) {
+ val sym = first(elem);
+
+ if (sym == var_s) {
val sym = second(elem);
val pat = third(elem);
val modifiers = fourth(elem);
@@ -1290,11 +1292,15 @@ static val subst_vars(val spec, val bindings, val filter)
}
uw_throwf(query_error_s, lit("unbound variable ~a"),
sym, nao);
- } else if (first(elem) == quasi_s) {
+ } else if (sym == quasi_s) {
val nested = subst_vars(rest(elem), bindings, filter);
list_collect_append(iter, nested);
spec = cdr(spec);
continue;
+ } else if (sym == expr_s) {
+ val result = eval(rest(elem), make_env(bindings, nil, nil), elem);
+ spec = cons(format(nil, lit("~a"), result, nao), rest(spec));
+ continue;
} else {
val nested = subst_vars(elem, bindings, filter);
list_collect_append(iter, nested);
@@ -1463,9 +1469,10 @@ static val extract_vars(val output_spec)
list_collect_decl (vars, tai);
if (consp(output_spec)) {
- if (first(output_spec) == var_s) {
+ val sym = first(output_spec);
+ if (sym == var_s) {
list_collect (tai, second(output_spec));
- } else {
+ } else if (sym != expr_s) {
for (; output_spec; output_spec = cdr(output_spec))
list_collect_nconc(tai, extract_vars(car(output_spec)));
}
@@ -1540,8 +1547,9 @@ static void do_output_line(val bindings, val specline, val filter, val out)
}
}
- } else {
- sem_error(specline, lit("unknown directive: ~a"), directive, nao);
+ } else if (directive == expr_s) {
+ format(out, lit("~a"),
+ eval(rest(elem), make_env(bindings, nil, nil), elem), nao);
}
}
break;