;; defmacrod v1.0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; displacing macros
;; Colas Nahaboo <colas@sa.inria.fr>, Mar 4 1992.
;; use defmacrod instead of defmacro and the defined macro will be 
;; a displacing one
;; we set the macro name with a macro applying the macro as a FExpr, to
;; just expand the call, and we displace the macro call with this expanded
;; list
;; all names are in the defmacrod: package to avoid potential side-effects

;;AUTOLOAD: defmacrod
;;AUTODOC: defmacrod "define a displacing macro"
;;(defmacrod macro-name lambda-list [documentation] {form} * )
;;
;;Defmacrod creates a displacing macro, i.e. a macros that will physically
;;replace each of its call by the result of its expansion, thus speeding the
;;following calls from the same place.
;;Displacing macros sohould be used with care, as they make the code more 
;;difficult to debug, since expressions seen under the debugger do no match
;;the code loaded from files.
;;
;;    (defmacrod inc (var) `(setq ,var (+ 1 ,var)))
;;    (defun foo (x) (inc x))
;;    ; before any call, code is untouched
;;    (List foo)                 => (lambda (x) (inc x))
;;    (setq a 1) (foo a)         => 2
;;    ; after the call the code has been modified
;;    (List foo)                 => (lambda (x) (setq x (+ 1 x)))

(defmacro defmacrod
  (&rest defmacrod:arglist &whole defmacrod:old-list
    &aux
    (defmacrod:macro-name (getn defmacrod:arglist 0))
  )
  (set defmacrod:macro-name
    (eval
      `(lambdam (&rest defmacrod:arglist &whole defmacrod:old-list)
	(replace-list
	  defmacrod:old-list
	  (apply
	    ,(eval (put defmacrod:arglist 0 'lambdaq))
	    defmacrod:arglist))
))))
