summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lisplib.c2
-rw-r--r--share/txr/stdlib/place.tl13
-rw-r--r--txr.131
3 files changed, 45 insertions, 1 deletions
diff --git a/lisplib.c b/lisplib.c
index 9ac7e3a7..bf41ab82 100644
--- a/lisplib.c
+++ b/lisplib.c
@@ -69,7 +69,7 @@ static val place_set_entries(val dlt, val fun)
lit("with-delete-expander"),
lit("set"), lit("pset"), lit("zap"), lit("flip"), lit("inc"), lit("dec"),
lit("push"), lit("pop"), lit("swap"), lit("shift"), lit("rotate"),
- lit("pushnew"), lit("del"),
+ lit("pushnew"), lit("del"), lit("lset"),
lit("defplace"), lit("define-place-macro"), lit("define-modify-macro"),
lit("placelet"), lit("placelet*"), lit("define-acessor"),
lit("with-slots"),
diff --git a/share/txr/stdlib/place.tl b/share/txr/stdlib/place.tl
index 7ef7f44d..5d17acb7 100644
--- a/share/txr/stdlib/place.tl
+++ b/share/txr/stdlib/place.tl
@@ -295,6 +295,19 @@
(with-delete-expander (deleter) place env
^(,deleter)))
+(defmacro lset (. places-source)
+ (let ((places (butlast places-source))
+ (source (last places-source))
+ (orig (gensym))
+ (iter (gensym)))
+ (unless places
+ (sys:eval-err "lset: require one or more places followed by expression"))
+ ^(let* ((,orig ,(car source))
+ (,iter ,orig))
+ ,*(butlast (mappend (ret ^((set ,@1 (car ,iter)) (set ,iter (cdr ,iter))))
+ places))
+ ,orig)))
+
(defmacro defplace (place-destructuring-args body-sym
(getter-sym setter-sym update-body) :
((ssetter-sym clobber-body))
diff --git a/txr.1 b/txr.1
index 2a068815..26be2887 100644
--- a/txr.1
+++ b/txr.1
@@ -25452,6 +25452,37 @@ place denotes a value stored in a dynamic data set such as a hash table,
then deletion of that place implies deletion of the entry which holds
that value. If the entry is identified by a key, that key is also removed.
+.coNP Macro @ lset
+.synb
+.mets (lset <> { place }+ << list-expr )
+.syne
+.desc
+The
+.code lset
+operator's parameter list consists of one or more places followed
+by an expression
+.metn list-expr .
+
+The macro evaluates
+.codn list-expr ,
+which is expected to produce a proper list.
+
+Successive elements of the resulting list are then assigned to each
+successive
+.codn place .
+
+If there are fewer elements in the list than places, the
+unmatched places receive the value
+.codn nil .
+
+Excess elements in the list are ignored.
+
+A
+.code lset
+form produces the value of
+.meta list-expr
+as its result value.
+
.SS* User-Defined Places and Place Operators
\*(TL provides a number of place-modifying operators such as
.codn set ,