summaryrefslogtreecommitdiffstats
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
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.
-rw-r--r--ChangeLog12
-rw-r--r--match.c20
-rw-r--r--parser.y3
3 files changed, 28 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index 4b8e6c3e..5265f36e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
2011-11-26 Kaz Kylheku <kaz@kylheku.com>
+ * 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.
+
+2011-11-26 Kaz Kylheku <kaz@kylheku.com>
+
Task #11436
Lisp interpreter added.
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;
diff --git a/parser.y b/parser.y
index 5a5c340b..7a5730ea 100644
--- a/parser.y
+++ b/parser.y
@@ -515,6 +515,7 @@ o_elem : TEXT { $$ = string_own($1);
| SPACE { $$ = string_own($1);
rl($$, num(lineno)); }
| o_var { $$ = $1; }
+ | list { $$ = rlcp(cons(expr_s, $1), $1); }
| rep_elem { $$ = $1; }
;
@@ -746,7 +747,7 @@ quasi_items : quasi_item { $$ = cons($1, nil); }
quasi_item : litchars { $$ = lit_char_helper($1); }
| TEXT { $$ = string_own($1); }
| var { $$ = $1; }
- | list { $$ = $1; }
+ | list { $$ = rlcp(cons(expr_s, $1), $1); }
;
litchars : LITCHAR { $$ = cons(chr($1), nil); }