Skip to content

Commit 953ef4b

Browse files
committed
Bug fix: href/@ compiler macros evaluate arguments left-to-right
1 parent 82a9c33 commit 953ef4b

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

hash-tables.lisp

Lines changed: 9 additions & 2 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))

tests/hash-tables.lisp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,25 @@
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+
"Test that href arguments are evaluated left-to-right.
143+
Regression for href/@ compiler macros."
144+
(let ((table (dict :x (dict :y (dict :z 'correct))))
145+
(list '()))
146+
(is (eql 'correct
147+
(href
148+
(progn (push 4 list) table)
149+
(progn (push 3 list) :x)
150+
(progn (push 2 list) :y)
151+
(progn (push 1 list) :z))))
152+
(is (equal list '(1 2 3 4))))
153+
(let ((table (dict :x (dict :y (dict :z 'correct))))
154+
(list '()))
155+
(is (eql 'correct
156+
(@
157+
(progn (push 4 list) table)
158+
(progn (push 3 list) :x)
159+
(progn (push 2 list) :y)
160+
(progn (push 1 list) :z))))
161+
(is (equal list '(1 2 3 4)))))

0 commit comments

Comments
 (0)