[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

edit definition

    Date: Fri, 15 Jun 90 11:46 PDT
    From: Charest@AI-SUN.jpl.nasa.gov (Len Charest)

    When I define a LISP structure, Zmacs "knows" that the definitions of the accessor functions,
    predicate function, etc. are inside the structure definition. Now I want to define my own macro
    with much of the same functionality:
	    (defmacro deffoo (name)
	      (let ((predicate (intern (format nil "~a-P" name))))
	      `(progn (blah-blah-blah)
		      (defun ,predicate (x)
			(typep x ',name))
    Defun automatically records the source file name for boo-boo-p, but Zmacs cannot find the embedded 
    definition. It gives me an annoying message like "Can't find definition for BOO-BOO-P; trying textual
    search." How can I get Zmacs to correctly find this embedded definition a la defstruct?

Short answer:  Read the documentation on record-source-file-name and the
sys:function-parent declaration, e.g.,

(defmacro deffoo (name)
  (let ((predicate (intern (format nil "~A-P" name))))
    `(progn (record-source-file-name ',name 'deffoo) ;tell it where the deffoo form is 
	    (defun ,predicate (x)
	      (declare (sys:function-parent ,name deffoo)) ;tell it the predicate is inside the deffoo
	        (typep x ',name))

Longer answer: There is a "protocol" followed by defining forms like this.
For example, you might want not only to have m-. find internal
functions, but to have Zmacs able to look at the definition and find the
function spec being defined, have a compiler style-checker that warns if
it's not at top-level, supply drivers for m-X Kill Definition and m-X
Show Effect of Definition, etc.

Discovering this protocol from reading the source and remembering how to
use it every time is a bit painful.  I wrote a macro that does most of
this for you, and reminds you about parts of this "protocol":

(def-defining-form deffoo
  :definer ((name)
	    ;; macro-expander for deffoo forms
            (let ((predicate (intern (format nil "~A-P" name))))
	      `(progn (record-source-file-name ',name 'deffoo)
		      (defun ,predicate (x)
			(declare (sys:function-parent ,name deffoo))
			(typep x ',name))
  :killer ((name)
	   ;; driver for m-X Kill Definition
	   (fundefine (intern (format nil "~A-P" name))))
  :shower ((form)
           ;; driver for m-X Show Effect of Definition
	   (let ((name (second form)))
	     (cond ((not (symbolp name))
	            (zwei:barf "Mal-formed FOO name: ~S" name))
	           ((fdefinedp name)
	            (zwei:typein-line "~&Evaluating this will redefine the existing FOO ~S." name))
		    (zwei:typein-line "~&Evaluating this will define the FOO ~S for the first time." name))))
  ;; Don't need more complicated :PARSER or :FINDER, since name is a symbol
  ;; Use standard style-checker, COMPILER:ONLY-AT-TOP-LEVEL.
  :type-name "Foo") ; Printed by Zmacs when it sez "Compiling Foo BOO-BOO" in the typein area.