Next: Specification Examples, Previous: Backtracking, Up: Instrumenting Macro Calls [Contents][Index]
Backquote (`) is a macro that results in an expression that may or
may not be evaluated. It is often used to simplify the definition of a
macro to return an expression that is evaluated, but Edebug does not know
when this is the case. However, the forms inside unquotes (,
and
,@
) are evaluated and Edebug instruments them.
Nested backquotes are supported by Edebug, but there is a limit on the
support of quotes inside of backquotes. Quoted forms (with '
)
are not normally evaluated, but if the quoted form appears immediately
within ,
and ,@
forms, Edebug treats this as a backquoted
form at the next higher level (even if there is not a next higher level
- this is difficult to fix).
If the backquoted forms happen to be code intended to be evaluated, you
can have Edebug instrument them by using edebug-`
instead of the
regular `
. Unquoted forms can always appear inside
edebug-`
anywhere a form is normally allowed. But (,
form)
may be used in two other places specially recognized by
Edebug: wherever a predicate specification would match, and at the head
of a list form in place of a function name or lambda expression. The
form inside a spliced unquote, (,@ form)
, will be
wrapped, but the unquote form itself will not be wrapped since this
would interfere with the splicing.
There is one other complication with using edebug-`
. If the
edebug-`
call is in a macro and the macro may be called from code
that is also instrumented, and if unquoted forms contain any macro
arguments bound to instrumented forms, then you should modify the
specification for the macro as follows: the specifications for those
arguments must use def-form
instead of form
. (This is to
reestablish the Edebugging context for those external forms.)
For example, the for
macro
(see ‘Problems with Macros’ in SXEmacs Lisp Reference Manual) is shown here but with edebug-`
substituted for regular `
.
(defmacro inc (var) (list 'setq var (list '1+ var))) (defmacro for (var from init to final do &rest body) (let ((tempvar (make-symbol "max"))) (edebug-` (let (((, var) (, init)) ((, tempvar) (, final))) (while (<= (, var) (, tempvar)) (, body) (inc (, var)))))))
Here is the corresponding modified Edebug specification and some code that calls the macro:
(def-edebug-spec for (symbolp "from" def-form "to" def-form "do" &rest def-form)) (let ((n 5)) (for i from n to (* n (+ n 1)) do (message "%s" i)))
After instrumenting the for
macro and the macro call, Edebug
first steps to the beginning of the macro call, then into the macro
body, then through each of the unquoted expressions in the backquote
showing the expressions that will be embedded in the backquote form.
Then when the macro expansion is evaluated, Edebug will step through the
let
form and each time it gets to an unquoted form, it will jump
back to an argument of the macro call to step through that expression.
Finally stepping will continue after the macro call. Even more
convoluted execution paths may result when using anonymous functions.
When the result of an expression is an instrumented expression, it is
difficult to see the expression inside the instrumentation. So
you may want to set the option edebug-unwrap-results
to a
non-nil
value while debugging such expressions, but it would slow
Edebug down to always do this.
Next: Specification Examples, Previous: Backtracking, Up: Instrumenting Macro Calls [Contents][Index]