summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-03-06 20:53:48 -0800
committerKaz Kylheku <kaz@kylheku.com>2017-03-06 20:53:48 -0800
commitfd87267eb4802d1e3ec3c22a48e09a86f76810ad (patch)
tree8760a2fb325d259e5e86983b20f690ee08da93c4 /lib.c
parent266e28cb7129d175ad4af5af5cb45fbbd3054862 (diff)
downloadtxr-fd87267eb4802d1e3ec3c22a48e09a86f76810ad.tar.gz
txr-fd87267eb4802d1e3ec3c22a48e09a86f76810ad.tar.bz2
txr-fd87267eb4802d1e3ec3c22a48e09a86f76810ad.zip
uref: the a.b.c syntax extended to .a.b.c
Now it is possible to use a leading dot on the referencing dot syntax. This is the is the "unbound reference dot". It expands to the uref macro, which denotes an unbound-reference: it produces a function which takes an object as the argument, and curries the reference implied by the remaining arguments. * eval.c (uref_s): New global symbol variable. (eval_init): Intern uref symbol and init uref_s. * eval.h (uref_s): Declared. * lib.c (simple_qref_args_p): A qref expression is now also not simple if it contains an embedded uref, meaning that it cannot be rendered into the dot notation without ambiguity. (obj_print_impl): Support printing (uref a b c) as .a.b.c. * lisplib.c (struct_set_entries): Add uref to the list of autoload triggers for struct.tl. * parser.l (DOTDOT): Consume any leading whitespace as part of recognizing the DOTDOT token. Otherwise the new rule for UREFDOT, which matches (mandatory) leading space will take precedence, causing " .." to be scanned wrong. (UREFDOT): Rule for new kind of dot token, which is preceded by mandatory whitespace, and isn't consing dot (which has mandatory trailing whitespace too, matched by an earlier rule). * parser.y (UREFDOT): New token type. (i_dot_expr, n_dot_expr): New grammar rules. (list): Handle a leading dot on the first element of a list as a special case. Things are done this way because trying to work a UREFDOT into the grammar otherwise causes intractable conflicts. (i_expr): The ^, ' and , punctuators are now followed by an i_dot_expr, so that the expression can be an unbound dot. (n_expr): Same change as in i_expr, but using n_dot_expr. Plus new UREFDOT n_expr production. * share/txr/stdlib/struct.tl (uref): New macro. * txr.1: Documented.
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/lib.c b/lib.c
index f7029785..99e7da76 100644
--- a/lib.c
+++ b/lib.c
@@ -9572,7 +9572,10 @@ static val simple_qref_args_p(val args, val pos)
return nil;
} else {
val arg = car(args);
- if (symbolp(arg) || (consp(arg) && car(arg) != qref_s)) {
+ if (symbolp(arg) || (consp(arg) &&
+ car(arg) != qref_s &&
+ car(arg) != uref_s))
+ {
return simple_qref_args_p(cdr(args), succ(pos));
}
return nil;
@@ -9800,6 +9803,12 @@ val obj_print_impl(val obj, val out, val pretty, struct strm_ctx *ctx)
put_string(lit("."), out);
iter = next;
}
+ } else if (sym == uref_s && simple_qref_args_p(cdr(obj), one)) {
+ val iter;
+ for (iter = cdr(obj); iter; iter = cdr(iter)) {
+ put_string(lit("."), out);
+ obj_print_impl(car(iter), out, pretty, ctx);
+ }
} else if (sym == quasi_s && consp(cdr(obj))) {
put_char(chr('`'), out);
out_quasi_str(obj, out, ctx);