diff options
| author | Nicolas Petton | 2016-03-25 15:09:04 +0100 |
|---|---|---|
| committer | Nicolas Petton | 2016-03-25 15:11:23 +0100 |
| commit | 3a13472adee7117e5af1249e41f6e8db9c473603 (patch) | |
| tree | 2bb3ab1fd87273ff2a906d95d3c0ea64c8a4f0e5 /lisp | |
| parent | 422c3dadce6dbd33ced2024782438af68c5756de (diff) | |
| download | emacs-3a13472adee7117e5af1249e41f6e8db9c473603.tar.gz emacs-3a13472adee7117e5af1249e41f6e8db9c473603.zip | |
Fix map-put and map-delete for alists (Bug#23105)
* lisp/emacs-lisp/map.el (map-put): Do not bind the evaluated place
expression to a new symbol.
* test/lisp/emacs-lisp/map-tests.el: Add a regression test.
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/emacs-lisp/map.el | 36 |
1 files changed, 10 insertions, 26 deletions
diff --git a/lisp/emacs-lisp/map.el b/lisp/emacs-lisp/map.el index ec8d3d79d9f..ba15a65f5e1 100644 --- a/lisp/emacs-lisp/map.el +++ b/lisp/emacs-lisp/map.el | |||
| @@ -123,33 +123,26 @@ MAP can be a list, hash-table or array." | |||
| 123 | default))) | 123 | default))) |
| 124 | 124 | ||
| 125 | (defmacro map-put (map key value) | 125 | (defmacro map-put (map key value) |
| 126 | "Associate KEY with VALUE in MAP and return MAP. | 126 | "Associate KEY with VALUE in MAP and return VALUE. |
| 127 | If KEY is already present in MAP, replace the associated value | 127 | If KEY is already present in MAP, replace the associated value |
| 128 | with VALUE. | 128 | with VALUE. |
| 129 | 129 | ||
| 130 | MAP can be a list, hash-table or array." | 130 | MAP can be a list, hash-table or array." |
| 131 | (macroexp-let2 nil map map | 131 | `(setf (map-elt ,map ,key) ,value)) |
| 132 | `(progn | ||
| 133 | (setf (map-elt ,map ,key) ,value) | ||
| 134 | ,map))) | ||
| 135 | 132 | ||
| 136 | (defmacro map-delete (map key) | 133 | (defun map-delete (map key) |
| 137 | "Delete KEY from MAP and return MAP. | 134 | "Delete KEY from MAP and return MAP. |
| 138 | No error is signaled if KEY is not a key of MAP. If MAP is an | 135 | No error is signaled if KEY is not a key of MAP. If MAP is an |
| 139 | array, store nil at the index KEY. | 136 | array, store nil at the index KEY. |
| 140 | 137 | ||
| 141 | MAP can be a list, hash-table or array." | 138 | MAP can be a list, hash-table or array." |
| 142 | (declare (debug t)) | 139 | (map--dispatch map |
| 143 | (gv-letplace (mgetter msetter) `(gv-delay-error ,map) | 140 | :list (setf (alist-get key map nil t) nil) |
| 144 | (macroexp-let2 nil key key | 141 | :hash-table (remhash key map) |
| 145 | `(if (not (listp ,mgetter)) | 142 | :array (and (>= key 0) |
| 146 | (map--delete ,mgetter ,key) | 143 | (<= key (seq-length map)) |
| 147 | ;; The alist case is special, since it can't be handled by the | 144 | (aset map key nil))) |
| 148 | ;; map--delete function. | 145 | map) |
| 149 | (setf (alist-get ,key (gv-synthetic-place ,mgetter ,msetter) | ||
| 150 | nil t) | ||
| 151 | nil) | ||
| 152 | ,mgetter)))) | ||
| 153 | 146 | ||
| 154 | (defun map-nested-elt (map keys &optional default) | 147 | (defun map-nested-elt (map keys &optional default) |
| 155 | "Traverse MAP using KEYS and return the looked up value or DEFAULT if nil. | 148 | "Traverse MAP using KEYS and return the looked up value or DEFAULT if nil. |
| @@ -337,15 +330,6 @@ MAP can be a list, hash-table or array." | |||
| 337 | (cdr pair))) | 330 | (cdr pair))) |
| 338 | map)) | 331 | map)) |
| 339 | 332 | ||
| 340 | (defun map--delete (map key) | ||
| 341 | (map--dispatch map | ||
| 342 | :list (error "No place to remove the mapping for %S" key) | ||
| 343 | :hash-table (remhash key map) | ||
| 344 | :array (and (>= key 0) | ||
| 345 | (<= key (seq-length map)) | ||
| 346 | (aset map key nil))) | ||
| 347 | map) | ||
| 348 | |||
| 349 | (defun map--apply-hash-table (function map) | 333 | (defun map--apply-hash-table (function map) |
| 350 | "Private function used to apply FUNCTION over MAP, MAP being a hash-table." | 334 | "Private function used to apply FUNCTION over MAP, MAP being a hash-table." |
| 351 | (let (result) | 335 | (let (result) |