X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Fdefmacro.lisp;h=39ec97cfaf9e3a84abbdb12cd523f4f0cef98807;hb=95591ed483dbb8c0846c129953acac1554f28809;hp=276c6d4c0250db31ce4f53a073075e256f73f322;hpb=512f941895f93afd4cf2ffedfd02124faedaa8ff;p=sbcl.git diff --git a/src/code/defmacro.lisp b/src/code/defmacro.lisp index 276c6d4..39ec97c 100644 --- a/src/code/defmacro.lisp +++ b/src/code/defmacro.lisp @@ -16,32 +16,51 @@ ;;; bootstrap idiom ;;; CL:DEFMACRO SB!XC:DEFMACRO ;;; SB!XC:DEFMACRO CL:DEFMACRO -(eval-when (:compile-toplevel :load-toplevel :execute) +(eval-when (#-sb-xc :compile-toplevel :load-toplevel :execute) (defun %expander-for-defmacro (name lambda-list body) (unless (symbolp name) (error "The macro name ~S is not a symbol." name)) + ;; When we are building the cross-compiler, we could be in a host + ;; lisp which implements CL macros (e.g. CL:AND) as special + ;; operators (while still providing a macroexpansion for + ;; compliance): therefore can't use the host's SPECIAL-OPERATOR-P + ;; as a discriminator, but that's OK because the set of forms the + ;; cross-compiler compiles is tightly controlled. -- CSR, + ;; 2003-04-20 + #-sb-xc-host (when (special-operator-p name) (error "The special operator ~S can't be redefined as a macro." name)) - (let ((whole (gensym "WHOLE-")) - (environment (gensym "ENV-"))) + (with-unique-names (whole environment) (multiple-value-bind (new-body local-decs doc) - (parse-defmacro lambda-list whole body name 'defmacro - :environment environment) - (let ((def `(lambda (,whole ,environment) - ,@local-decs - (block ,name - ,new-body)))) - `(eval-when (:compile-toplevel :load-toplevel :execute) - (sb!c::%defmacro ',name #',def ',lambda-list ,doc))))))) + (parse-defmacro lambda-list whole body name 'defmacro + :environment environment) + (let ((def `(#+sb-xc-host lambda + ;; Use a named-lambda rather than a lambda so that + ;; proper xref information can be stored. Use a + ;; list-based name, since otherwise the compiler + ;; will momentarily assume that it names a normal + ;; function, and report spurious warnings about + ;; redefinition a macro as a function, and then + ;; vice versa. + #-sb-xc-host named-lambda #-sb-xc-host (defmacro ,name) + (,whole ,environment) + ,@local-decs + ,new-body)) + (debug-name (sb!c::debug-name 'macro-function name))) + `(eval-when (:compile-toplevel :load-toplevel :execute) + (sb!c::%defmacro ',name #',def ',lambda-list + ,doc ',debug-name))))))) (macrolet - ((def (times set-args-p) + ((def (times set-p) `(eval-when (,@times) - (defun sb!c::%defmacro (name definition lambda-list doc) + (defun sb!c::%defmacro (name definition lambda-list doc debug-name) ;; old note (ca. 1985, maybe:-): "Eventually %%DEFMACRO ;; should deal with clearing old compiler information for ;; the functional value." + ,@(unless set-p + '((declare (ignore lambda-list debug-name)))) (ecase (info :function :kind name) ((nil)) (:function @@ -71,20 +90,15 @@ ;; will involve finding the old macro lambda-list ;; and comparing it with the new one. (style-warn "redefining ~S in DEFMACRO" name)) - (setf (sb!xc:macro-function name) definition - (fdocumentation name 'function) doc) - ,(when set-args-p - `(case (widetag-of definition) - (#.sb!vm:closure-header-widetag - (setf (%simple-fun-arglist (%closure-fun definition)) - lambda-list)) - ((#.sb!vm:simple-fun-header-widetag - #.sb!vm:closure-fun-header-widetag) - (setf (%simple-fun-arglist definition) lambda-list)))) + (setf (sb!xc:macro-function name) definition) + ,(when set-p + `(setf (%fun-doc definition) doc + (%fun-lambda-list definition) lambda-list + (%fun-name definition) debug-name)) name)))) (progn (def (:load-toplevel :execute) #-sb-xc-host t #+sb-xc-host nil) - (def (:compile-toplevel) nil))) + (def (#-sb-xc :compile-toplevel) nil))) ;;; Parse the definition and make an expander function. The actual ;;; definition is done by %DEFMACRO which we expand into. After the @@ -106,21 +120,23 @@ ;;; DEFMACRO-MUNDANELY is like SB!XC:DEFMACRO, except that it doesn't ;;; have any EVAL-WHEN or IR1 magic associated with it, so it only ;;; takes effect in :LOAD-TOPLEVEL or :EXECUTE situations. -;;; -;;; FIXME: It'd probably be good (especially for DEFMACRO) -;;; to make this share more code with DEFMACRO. (def!macro defmacro-mundanely (name lambda-list &body body) - (let ((whole (gensym "WHOLE-")) - (environment (gensym "ENVIRONMENT-"))) - (multiple-value-bind (new-body local-decs doc) - (parse-defmacro lambda-list whole body name 'defmacro - :environment environment) - `(progn - (setf (sb!xc:macro-function ',name) - (lambda (,whole ,environment) - ,@local-decs - (block ,name - ,new-body))) - (setf (fdocumentation ',name 'macro) - ,doc) - ',name)))) + + ;; old way: + ;;(let ((whole (gensym "WHOLE-")) + ;; (environment (gensym "ENVIRONMENT-"))) + ;; (multiple-value-bind (new-body local-decs doc) + ;; (parse-defmacro lambda-list whole body name 'defmacro + ;; :environment environment) + ;; `(progn + ;; (setf (sb!xc:macro-function ',name) + ;; (lambda (,whole ,environment) + ;; ,@local-decs + ;; (block ,name + ;; ,new-body))) + ;; (setf (fdocumentation ',name 'macro) + ;; ,doc) + ;; ',name))) + + `(let () + (sb!xc:defmacro ,name ,lambda-list ,@body)))