summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-02-22 19:30:40 -0800
committerKaz Kylheku <kaz@kylheku.com>2014-02-22 19:30:40 -0800
commit0e50007d98c6b507e71762d9e5d21b2ee9ec4886 (patch)
tree94a5d2d886acc6f2797da6ade1ceacb590ecd9f6
parent1dabce1358de135b82bf0831f045352b3ff9ab1c (diff)
downloadtxr-0e50007d98c6b507e71762d9e5d21b2ee9ec4886.tar.gz
txr-0e50007d98c6b507e71762d9e5d21b2ee9ec4886.tar.bz2
txr-0e50007d98c6b507e71762d9e5d21b2ee9ec4886.zip
* parser.y: Allow the (. expr) syntax to denote expr.
* eval.h: Declare existing lambda_s extern variable. * lib.c (obj_print, obj_pprint): print (lambda sym ...) as (lambda (. sym) ...) and (lambda sym) as (lambda (. sym)). * txr.1: document it.
-rw-r--r--ChangeLog11
-rw-r--r--eval.h2
-rw-r--r--lib.c28
-rw-r--r--parser.y1
-rw-r--r--txr.127
5 files changed, 68 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 0286a61c..02f27206 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
2014-02-22 Kaz Kylheku <kaz@kylheku.com>
+ * parser.y: Allow the (. expr) syntax to denote expr.
+
+ * eval.h: Declare existing lambda_s extern variable.
+
+ * lib.c (obj_print, obj_pprint): print (lambda sym ...)
+ as (lambda (. sym) ...) and (lambda sym) as (lambda (. sym)).
+
+ * txr.1: document it.
+
+2014-02-22 Kaz Kylheku <kaz@kylheku.com>
+
Implemented macrolet.
* eval.c (macrolet_s): New variable.
diff --git a/eval.h b/eval.h
index 83c885e9..2c517ff7 100644
--- a/eval.h
+++ b/eval.h
@@ -24,7 +24,7 @@
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-extern val dwim_s, vector_lit_s, vector_list_s;
+extern val dwim_s, lambda_s, vector_lit_s, vector_list_s;
extern val hash_lit_s, hash_construct_s;
extern val eval_error_s;
extern val last_form_evaled;
diff --git a/lib.c b/lib.c
index 7037585f..0c257102 100644
--- a/lib.c
+++ b/lib.c
@@ -5213,8 +5213,22 @@ val obj_print(val obj, val out)
put_char(chr('('), out);
}
+ if (sym == lambda_s && cdr(obj) && symbolp(second(obj))) {
+ obj_print(sym, out);
+ if (second(obj)) {
+ put_string(lit(" (. "), out);
+ obj_print(second(obj), out);
+ put_char(chr(')'), out);
+ } else {
+ put_string(lit(" ()"), out);
+ }
+ iter = (cdr(obj));
+ goto finish;
+ }
+
for (iter = obj; consp(iter); iter = cdr(iter)) {
obj_print(car(iter), out);
+finish:
if (nilp(cdr(iter))) {
put_char(closepar, out);
} else if (consp(cdr(iter))) {
@@ -5379,8 +5393,22 @@ val obj_pprint(val obj, val out)
put_char(chr('('), out);
}
+ if (sym == lambda_s && cdr(obj) && symbolp(second(obj))) {
+ obj_print(sym, out);
+ if (second(obj)) {
+ put_string(lit(" (. "), out);
+ obj_print(second(obj), out);
+ put_char(chr(')'), out);
+ } else {
+ put_string(lit(" ()"), out);
+ }
+ iter = (cdr(obj));
+ goto finish;
+ }
+
for (iter = obj; consp(iter); iter = cdr(iter)) {
obj_pprint(car(iter), out);
+finish:
if (nilp(cdr(iter))) {
put_char(closepar, out);
} else if (consp(cdr(iter))) {
diff --git a/parser.y b/parser.y
index a2553f88..819630b9 100644
--- a/parser.y
+++ b/parser.y
@@ -702,6 +702,7 @@ hash : HASH_H list { if (unquotes_occur($2))
list : '(' n_exprs ')' { $$ = rl($2, num($1)); }
| '(' ')' { $$ = nil; }
+ | '(' '.' n_expr ')' { $$ = $3; }
| '[' n_exprs ']' { $$ = rl(cons(dwim_s, $2), num($1)); }
| '[' ']' { $$ = rl(cons(dwim_s, nil), num($1)); }
| '@' n_expr { if (consp($2))
diff --git a/txr.1 b/txr.1
index 0299f698..8e663236 100644
--- a/txr.1
+++ b/txr.1
@@ -4845,6 +4845,33 @@ Much of the TXR Lisp syntax has been introduced in the previous sections of the
manual, since directive forms are based on it. There is some additional syntax
that is useful in TXR Lisp programming.
+.SS Consing Dot
+
+Unlike other major Lisp dialects, TXR Lisp allows a consing dot with no forms
+preceding it. This construct simply denotes the form which follows the dot.
+That is to say, the parser implements the following transformation:
+
+ (. expr) -> expr
+
+This is convenient in writing function argument lists that only take
+variable arguments. Instead of the syntax:
+
+ (defun fun args ...)
+
+the following syntax can be used:
+
+ (defun fun (. args) ...)
+
+When a lambda form is printed, it is printed in the following style.
+
+ (lambda nil ...) -> (lambda () ...)
+ (lambda sym ...) -> (lambda (. sym) ...)
+ (lambda (sym) ...) -> (lambda (sym) ...)
+
+In no other circumstances is nil printed as (), or a symbol as (. sym).
+
+symbol is followed by a symbol.
+
.SS Quoting/Unquoting
.IP 'form