summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--share/txr/stdlib/defset.tl32
-rw-r--r--txr.133
2 files changed, 50 insertions, 15 deletions
diff --git a/share/txr/stdlib/defset.tl b/share/txr/stdlib/defset.tl
index 9b1c9559..3fd8de2e 100644
--- a/share/txr/stdlib/defset.tl
+++ b/share/txr/stdlib/defset.tl
@@ -56,37 +56,39 @@
,body)))))))
(defun defset-expander (env macform name params newval getform setform)
- (let* ((fp (new fun-param-parser form macform syntax params))
+ (let* ((ap (analyze-params params))
+ (exp-params (car ap))
+ (total-syms (cadr ap))
+ (fp (new fun-param-parser form macform syntax exp-params))
(fixpars (append fp.req fp.(opt-syms)))
- (restpar fp.rest))
+ (restpar (if (symbol-package fp.rest) fp.rest))
+ (extsyms [keep-if symbol-package
+ (diff total-syms (cons restpar fixpars))]))
(with-gensyms (getter setter)
^(defplace (,name ,*params) body
(,getter ,setter
- (let* ((gpf-pairs (append (mapcar (op list (gensym) @1)
+ (let* ((gpf-pairs (append (mapcar (op list (gensym))
(list ,*fixpars))))
(gpr-pairs (if ',restpar
- (mapcar (ret ^(,(gensym) ,@1)) ,restpar)))
+ (mapcar (op list (gensym)) ,restpar)))
+ (ext-pairs (mapcar (op list (gensym)) (list ,*extsyms)))
(pgens [mapcar car gpf-pairs])
- (rgens [mapcar car gpr-pairs]))
- ^(alet (,*gpf-pairs ,*gpr-pairs)
+ (rgens [mapcar car gpr-pairs])
+ (egens [mapcar car ext-pairs]))
+ ^(alet (,*gpf-pairs ,*gpr-pairs ,*ext-pairs)
,(expand ^(symacrolet (,*(zip ',fixpars
(mapcar (ret ^',@1) pgens))
- ,*(if gpr-pairs
- ^((,',restpar ',rgens))))
+ ,*(zip ',extsyms
+ (mapcar (ret ^',@1) egens))
+ ,*(if gpr-pairs
+ ^((,',restpar ',rgens))))
(macrolet ((,,getter () ,',getform)
(,,setter (,',newval) ,',setform))
,body))
,env))))))))
-(defun defset-expander-hairy (env macform name params newval getform setform)
- (compile-error macform "param list macro support is being researched"))
-
(defmacro usr:defset (:env e :form mf . args)
(tree-case args
- ((name (param . params) newval getform setform)
- (if (and (keywordp param) (neq : param))
- (defset-expander-hairy e mf . args)
- (defset-expander e mf . args)))
((name (. params) newval getform setform)
(defset-expander e mf . args))
((get-fun set-fun)
diff --git a/txr.1 b/txr.1
index 173c7e38..541bef80 100644
--- a/txr.1
+++ b/txr.1
@@ -34625,6 +34625,39 @@ Syntactic places defined by
.code defset
may not use improper syntax such as
.codn "(set (g 1 2 . 3) v)" .
+Although syntactic places defined by
+.code defset
+perform macro-parameter-like destructuring of the place form, binding
+unevaluated argument expressions to the parameter symbols,
+nested macro parameter lists are not supported:
+.meta params
+specifies a function parameter list.
+
+The parameter list may use parameter macros, keeping in mind that
+the parameter expansion is applied at the time the
+.code defset
+form is processed, specifying an expanded parameter list which
+receives unevaluated expressions. The
+.meta get-form
+and
+.meta set-form
+may refer to all symbols produced by parameter list expansion, other
+than generated symbols. For instance, if a parameter list macro
+.code :addx
+exists which adds the parameter symbol
+.code x
+to the parameter list, and this
+.code :addx
+is invoked in the
+.meta params
+list of a
+.codn defset ,
+then
+.code x
+will be visible to the
+.meta get-form
+and
+.metn set-form .
The short, two-argument form of
.code defset