I am trying to make a macro that creates a function that takes S-expresions and evaluates them inside the lexical context of the fixture. Here is the macro I wrote:
(defmacro def-fixture (name bindings)
"Return a function that takes the form to execute but is wrapped between a let of the bindings"
`(defun ,(intern (symbol-name name)) (body)
(let (,bindings)
(unwind-protect
(progn
body)))))
But when I run it it appears to be executing outside the lexical context I provided
(def-fixture test-fixture '(zxvf 1))
(test-fixture '(= zxvf 1))
let: Symbol's value as variable is void: zxvf
Btw, I have enabled the variable lexical binding. Any ideas as to what is my mistake?
This has nothing to do with lexical scoping. Your macro call expands to:
(defun test-fixture (body)
(let ((quote (zxvf 1)))
(unwind-protect (progn body))))
Which is of course not what you intended. I do not believe that (test-fixture '(= zxvf 1))
signals the error you cite (i.e. variable is void
). Instead, the call signals (void-function zxvf)
because it tries to evaluate (zxvf 1)
. The (= zxvf 1)
expression is never evaluated, since it's quoted.
You might like to try something more like:
(defmacro def-fixture (name bindings)
"Return a macro that takes the form to execute but is wrapped between a let of the bindings"
`(defmacro ,name (body)
`(let (,',bindings)
(unwind-protect
(progn
,body)))))
and then use it as in:
(def-fixture test-fixture (zxvf 1))
(test-fixture (= zxvf 1))