diff options
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | eval.h | 2 | ||||
-rw-r--r-- | lib.c | 28 | ||||
-rw-r--r-- | parser.y | 1 | ||||
-rw-r--r-- | txr.1 | 27 |
5 files changed, 68 insertions, 1 deletions
@@ -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. @@ -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; @@ -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))) { @@ -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)) @@ -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 |