Skip to content

Commit f227289

Browse files
committed
Bug fix: eval order in href/@ compiler macros
Make the compiler macros for href and @ preserve left-to-right argument order evaluation. Also, redefine the expansion of @ in terms of href.
1 parent c7af4f0 commit f227289

File tree

2 files changed

+28
-12
lines changed

2 files changed

+28
-12
lines changed

hash-tables.lisp

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,15 @@ As soon as one of KEYS fails to match, DEFAULT is returned."
192192
keys
193193
:initial-value table))
194194

195-
(define-compiler-macro href (table &rest keys)
196-
(expand-href table keys))
195+
(define-compiler-macro href (table key &rest keys)
196+
(let* ((keys (cons key keys))
197+
(table-tmp (gensym (string 'table)))
198+
(key-tmps
199+
(make-gensym-list (length keys)
200+
(string 'key))))
201+
`(let ((,table-tmp ,table)
202+
,@(mapcar #'list key-tmps keys))
203+
,(expand-href table-tmp key-tmps))))
197204

198205
(define-compiler-macro (setf href) (value table &rest keys)
199206
`(setf ,(expand-href table keys) ,value))
@@ -212,16 +219,11 @@ As soon as one of KEYS fails to match, DEFAULT is returned."
212219
(rec (gethash (car keys) table) (cdr keys))
213220
(setf (gethash (car keys) table) value))))
214221

215-
(flet ((expand-@ (table keys)
216-
(reduce
217-
(lambda (table key)
218-
`(gethash ,key ,table))
219-
keys
220-
:initial-value table)))
221-
(define-compiler-macro @ (table key &rest keys)
222-
(expand-@ table (cons key keys)))
223-
(define-compiler-macro (setf @) (value table key &rest keys)
224-
`(setf ,(expand-@ table (cons key keys)) ,value)))
222+
(define-compiler-macro @ (table key &rest keys)
223+
`(href ,table ,key ,@keys))
224+
225+
(define-compiler-macro (setf @) (value table key &rest keys)
226+
`(setf (href ,table ,key ,@keys) ,value))
225227

226228
(-> pophash (t hash-table) (values t boolean &optional))
227229
(defun pophash (key hash-table)

tests/hash-tables.lisp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,17 @@
137137
(dolist (test '(eq eql equal equalp))
138138
(is (hash-table-test-p (symbol-function test))))
139139
(is (not (hash-table-test-p #'car))))
140+
141+
(test href-eval-order
142+
(let ((table (dict))
143+
(list '())
144+
(y 0))
145+
(href (progn (push 2 list) table)
146+
(push 1 list))
147+
(is (equal list '(1 2))))
148+
(let ((table (dict))
149+
(list '())
150+
(y 0))
151+
(@ (progn (push 2 list) table)
152+
(push 1 list))
153+
(is (equal list '(1 2)))))

0 commit comments

Comments
 (0)