Hi,
Thanks for your great project.
I found an issue where defsetf doesn't work for a symbol defined by symbol-macrolet. The detail is the following.
## environment - version of Parenscript - latest of master (526346549f0342d67947d360a8f7ba9fc7b09e54) - CL Implementation (same result in both) - SBCL 1.5.0 - Clozure CL 1.11.5
## code to reproduce ```lisp (use-package :parenscript)
(princ (ps (defun my-car (lst) (nth 0 lst)) (defun my-set-car (lst value) (setf (nth 0 lst) value))
(defsetf my-car (lst) (value) `(my-set-car ,lst ,value))
;; Raw setf is ok (setf (my-car lst) 100)
;; setf for macrolet symbol is NG (symbol-macrolet ((sym (my-car lst))) (setf sym 300)))) ```
Then, the result is the following. (I added some comments for convenience.)
```javascript function myCar(lst) { __PS_MV_REG = []; return nth(0, lst); }; function mySetCar(lst, value) { __PS_MV_REG = []; return nth(0, lst) = value; }; /* Raw setf is ok */ (function () { var _js66 = lst; var _js65 = 100; __PS_MV_REG = []; return mySetCar(_js66, _js65); })(); /* setf for macrolet symbol is NG */ myCar(lst) = 300; ```
Thanks.
Regards, -- Eiji, Seki (hamgoostar@gmail.com) https://github.com/eshamster
Hi,
For reference: The following patch can solve the issue and destroys no existing tests (parenscript.tests:run-tests). However, I'm afraid that it is ad-hoc...
```diff diff --git a/src/macros.lisp b/src/macros.lisp index 986c283..ad0eb00 100644 --- a/src/macros.lisp +++ b/src/macros.lisp @@ -334,9 +334,15 @@ lambda-list::= (assert (evenp (length args)) () "~s does not have an even number of arguments." `(setf ,args)) `(progn ,@(loop for (place value) on args by #'cddr collect - (aif (and (listp place) (gethash (car place) *setf-expanders*)) - (funcall it (cdr place) value) - `(ps-assign ,place ,value))))) + (progn + (when (atom place) + (setf place (ps-compile place)) + (when (and (listp place) + (eq (car place) 'ps-js:funcall)) + (setf place (cdr place)))) + (aif (and (listp place) (gethash (car place) *setf-expanders*)) + (funcall it (cdr place) value) + `(ps-assign ,place ,value))))))
(defpsmacro psetf (&rest args) (let ((places (loop for x in args by #'cddr collect x)) ```
Regards, -- Eiji, Seki (hamgoostar@gmail.com) https://github.com/eshamster
2019年4月9日(火) 0:12 Seki_GMail hamgoostar@gmail.com:
Hi,
Thanks for your great project.
I found an issue where defsetf doesn't work for a symbol defined by symbol-macrolet. The detail is the following.
## environment
- version of Parenscript
- latest of master (526346549f0342d67947d360a8f7ba9fc7b09e54)
- CL Implementation (same result in both)
- SBCL 1.5.0
- Clozure CL 1.11.5
## code to reproduce
(use-package :parenscript) (princ (ps (defun my-car (lst) (nth 0 lst)) (defun my-set-car (lst value) (setf (nth 0 lst) value)) (defsetf my-car (lst) (value) `(my-set-car ,lst ,value)) ;; Raw setf is ok (setf (my-car lst) 100) ;; setf for macrolet symbol is NG (symbol-macrolet ((sym (my-car lst))) (setf sym 300))))
Then, the result is the following. (I added some comments for convenience.)
function myCar(lst) { __PS_MV_REG = []; return nth(0, lst); }; function mySetCar(lst, value) { __PS_MV_REG = []; return nth(0, lst) = value; }; /* Raw setf is ok */ (function () { var _js66 = lst; var _js65 = 100; __PS_MV_REG = []; return mySetCar(_js66, _js65); })(); /* setf for macrolet symbol is NG */ myCar(lst) = 300;
Thanks.
Regards,
Eiji, Seki (hamgoostar@gmail.com) https://github.com/eshamster
Hello,
That looks close. I believe the right fix is to macro-expand PLACE before looking it up in *SETF-EXPANDERS*.
I will review closer and add tests later.
Thank you, Vladimir
parenscript-devel@common-lisp.net