diff options
-rw-r--r-- | lisp/ChangeLog | 6 | ||||
-rw-r--r-- | lisp/emacs-lisp/byte-run.el | 63 |
2 files changed, 41 insertions, 28 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 49496efec69..65f71eac351 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,9 @@ +2012-12-31 Andreas Schwab <schwab@linux-m68k.org> + + * emacs-lisp/byte-run.el (defmacro): Use same argument parsing as + defun. Don't check for DECL if DOCSTRING isn't a string. + (defun): Likewise. + 2012-12-31 Glenn Morris <rgm@gnu.org> * eshell/em-cmpl.el (eshell-pcomplete): diff --git a/lisp/emacs-lisp/byte-run.el b/lisp/emacs-lisp/byte-run.el index 0cbf2616ba2..0b502aba93c 100644 --- a/lisp/emacs-lisp/byte-run.el +++ b/lisp/emacs-lisp/byte-run.el @@ -117,7 +117,7 @@ and the VALUES and should return the code to use to set this property.") (defalias 'defmacro (cons 'macro - #'(lambda (name arglist &optional docstring decl &rest body) + #'(lambda (name arglist &optional docstring &rest body) "Define NAME as a macro. When the macro is called, as in (NAME ARGS...), the function (lambda ARGLIST BODY...) is applied to @@ -126,32 +126,38 @@ and the result should be a form to be evaluated instead of the original. DECL is a declaration, optional, of the form (declare DECLS...) where DECLS is a list of elements of the form (PROP . VALUES). These are interpreted according to `macro-declarations-alist'. -The return value is undefined." - (if (stringp docstring) nil - (setq body (cons decl body)) - (setq decl docstring) - (setq docstring nil)) - (if (or (null decl) (eq 'declare (car-safe decl))) nil - (setq body (cons decl body)) - (setq decl nil)) - (if (null body) (setq body '(nil))) - (if docstring (setq body (cons docstring body))) - ;; Can't use backquote because it's not defined yet! - (let* ((fun (list 'function (cons 'lambda (cons arglist body)))) - (def (list 'defalias - (list 'quote name) - (list 'cons ''macro fun))) - (declarations - (mapcar - #'(lambda (x) - (let ((f (cdr (assq (car x) macro-declarations-alist)))) - (if f (apply (car f) name arglist (cdr x)) - (message "Warning: Unknown macro property %S in %S" - (car x) name)))) - (cdr decl)))) - (if declarations - (cons 'prog1 (cons def declarations)) - def))))) +The return value is undefined. + +\(fn NAME ARGLIST &optional DOCSTRING DECL &rest BODY)" + ;; We can't just have `decl' as an &optional argument, because we need + ;; to distinguish + ;; (defmacro foo (arg) (bar) nil) + ;; from + ;; (defmacro foo (arg) (bar)). + (let ((decls (cond + ((eq (car-safe docstring) 'declare) + (prog1 (cdr docstring) (setq docstring nil))) + ((and (stringp docstring) + (eq (car-safe (car body)) 'declare)) + (prog1 (cdr (car body)) (setq body (cdr body))))))) + (if docstring (setq body (cons docstring body)) + (if (null body) (setq body '(nil)))) + ;; Can't use backquote because it's not defined yet! + (let* ((fun (list 'function (cons 'lambda (cons arglist body)))) + (def (list 'defalias + (list 'quote name) + (list 'cons ''macro fun))) + (declarations + (mapcar + #'(lambda (x) + (let ((f (cdr (assq (car x) macro-declarations-alist)))) + (if f (apply (car f) name arglist (cdr x)) + (message "Warning: Unknown macro property %S in %S" + (car x) name)))) + decls))) + (if declarations + (cons 'prog1 (cons def declarations)) + def)))))) ;; Now that we defined defmacro we can use it! (defmacro defun (name arglist &optional docstring &rest body) @@ -173,7 +179,8 @@ The return value is undefined. (let ((decls (cond ((eq (car-safe docstring) 'declare) (prog1 (cdr docstring) (setq docstring nil))) - ((eq (car-safe (car body)) 'declare) + ((and (stringp docstring) + (eq (car-safe (car body)) 'declare)) (prog1 (cdr (car body)) (setq body (cdr body))))))) (if docstring (setq body (cons docstring body)) (if (null body) (setq body '(nil)))) |