From fe533f82ee26d0bf98468f25b263e8f8461f309e Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Fri, 8 Mar 2019 08:25:42 -0800 Subject: defset: support improper list places. * share/txr/stdlib/defset.tl (defset-expander): Check for restpar being an atom and handle differently. We still don't handle the case where (b . c) is matched against a rest parameter; in this case the mapcar will process an improper list. I.e. the improper form must have an atom which matches the position of the rest parameter. * txr.1: Updated. --- share/txr/stdlib/defset.tl | 11 +++++++---- txr.1 | 17 +++++++++++++++-- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/share/txr/stdlib/defset.tl b/share/txr/stdlib/defset.tl index 3fd8de2e..521260ba 100644 --- a/share/txr/stdlib/defset.tl +++ b/share/txr/stdlib/defset.tl @@ -67,10 +67,11 @@ (with-gensyms (getter setter) ^(defplace (,name ,*params) body (,getter ,setter - (let* ((gpf-pairs (append (mapcar (op list (gensym)) - (list ,*fixpars)))) + (let* ((gpf-pairs (mapcar (op list (gensym)) (list ,*fixpars))) (gpr-pairs (if ',restpar - (mapcar (op list (gensym)) ,restpar))) + (if (consp ,restpar) + (mapcar (op list (gensym)) ,restpar) + (list (list (gensym) ,restpar))))) (ext-pairs (mapcar (op list (gensym)) (list ,*extsyms))) (pgens [mapcar car gpf-pairs]) (rgens [mapcar car gpr-pairs]) @@ -81,7 +82,9 @@ ,*(zip ',extsyms (mapcar (ret ^',@1) egens)) ,*(if gpr-pairs - ^((,',restpar ',rgens)))) + (if (consp ,restpar) + ^((,',restpar ',rgens)) + ^((,',restpar ',(car rgens)))))) (macrolet ((,,getter () ,',getform) (,,setter (,',newval) ,',setform)) ,body)) diff --git a/txr.1 b/txr.1 index 541bef80..3115d465 100644 --- a/txr.1 +++ b/txr.1 @@ -34623,8 +34623,21 @@ the two trailing parameters corresponding to the rest parameter Syntactic places defined by .code defset -may not use improper syntax such as -.codn "(set (g 1 2 . 3) v)" . +that have a rest parameter may be invoked with improper syntax such as +.codn "(set (g x y . z) v)" . +In this situation, that rest parameter will be bound to the name of +a temporary variable which holds the value of +.code z +rather than to a list of temporary variable names holding the values +of trailing expressions. +The +.code get-form +and +.code set-form +must be prepared for this situation. In particular, the rest parameter's value +is an atom, then it cannot be spliced in the backquote syntax, except at the +last position of a list. + Although syntactic places defined by .code defset perform macro-parameter-like destructuring of the place form, binding -- cgit v1.2.3