Major Section: EVENTS
Example Defmacros: (defmacro xor (x y) (list 'if x (list 'not y) y))where(defmacro git (sym key) (list 'getprop sym key nil '(quote current-acl2-world) '(w state)))
(defmacro one-of (x &rest rst) (declare (xargs :guard (symbol-listp rst))) (cond ((null rst) nil) (t (list 'or (list 'eq x (list 'quote (car rst))) (list* 'one-of x (cdr rst))))))
Example Expansions: term macroexpansion
(xor a b) (if a (not b) b) (xor a (foo b)) (if a (not (foo b)) (foo b))
(git 'car 'lemmas) (getprop 'car 'lemmas nil 'current-acl2-world (w state))
(one-of x a b c) (or (eq x 'a) (or (eq x 'b) (or (eq x 'c) nil)))
(one-of x 1 2 3) ill-formed (guard violation)
General Form: (defmacro name macro-args doc-string dcl ... dcl body)
name
is a new symbolic name (see name), macro-args
specifies
the formal parameters of the macro, and body
is a term. The formal
parameters can be specified in a much more general way than is allowed by
ACL2 defun
events; see macro-args for a description of keyword
(&key
) and optional (&optional
) parameters as well as other so-called
``lambda-list keywords'', &rest
and &whole
. Doc-string
is an
optional documentation string; see doc-string. Each dcl
is an
optional declaration (see declare) except that the only xargs
keyword
permitted by defmacro
is :
guard
.
For compute-intensive applications see the distributed book
misc/defmac.lisp
, which can speed up macroexpansion by introducing an
auxiliary defun
. For more information, evaluate the form
(include-book "misc/defmac" :dir :system)
and then evaluate
:doc defmac
.
Macroexpansion occurs when a form is read in, i.e., before the
evaluation or proof of that form is undertaken. To experiment with
macroexpansion, see trans. When a form whose car
is name
arises as the form is read in, the arguments are bound as described
in CLTL pp. 60 and 145, the guard is checked, and then the body
is
evaluated. The result is used in place of the original form.
In ACL2, macros do not have access to state
. That is, state
is not allowed among the formal parameters. This is in part a
reflection of CLTL, p. 143, ``More generally, an implementation of
Common Lisp has great latitude in deciding exactly when to expand
macro calls with a program. ... Macros should be written in such a
way as to depend as little as possible on the execution environment
to produce a correct expansion.'' In ACL2, the product of
macroexpansion is independent of the current environment and is
determined entirely by the macro body and the functions and
constants it references. It is possible, however, to define macros
that produce expansions that refer to state
or other single-threaded
objects (see stobj) or variables not among the macro's arguments.
See the git
example above. For a related utility that avoids this
state
restriction, see make-event.