aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorNicolas Petton2016-03-25 15:09:04 +0100
committerNicolas Petton2016-03-25 15:11:23 +0100
commit3a13472adee7117e5af1249e41f6e8db9c473603 (patch)
tree2bb3ab1fd87273ff2a906d95d3c0ea64c8a4f0e5 /lisp
parent422c3dadce6dbd33ced2024782438af68c5756de (diff)
downloademacs-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.el36
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.
127If KEY is already present in MAP, replace the associated value 127If KEY is already present in MAP, replace the associated value
128with VALUE. 128with VALUE.
129 129
130MAP can be a list, hash-table or array." 130MAP 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.
138No error is signaled if KEY is not a key of MAP. If MAP is an 135No error is signaled if KEY is not a key of MAP. If MAP is an
139array, store nil at the index KEY. 136array, store nil at the index KEY.
140 137
141MAP can be a list, hash-table or array." 138MAP 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)