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

Writing macros within macros :Part II, almost there



I have gotten this far:

(defun keyword-pairs (fields)
  (let ((output ()))
    (dolist (x fields output)
      (setq output (cons (intern (string x)) output))
      (setq output (cons (intern (concatenate 'string ":" (string x))) output)))))

(defmacro def-geo-thing (name &rest fields)
  (let ((conc-name (intern (concatenate 'string "MAKE-" (string name)))))
  `(progn
     (defflavor ,name
	     ,fields
	     ()
       :initable-instance-variables
       (:constructor ,conc-name)
       )
     (defmacro ,name (id ,@fields)
     `(setq ,id (,',conc-name ,',@(keyword-pairs fields)))))))

(def-geo-thing circle center radius plane)

expands into
(PROGN (DEFFLAVOR CIRCLE
                  (CENTER RADIUS PLANE)
                  NIL
                  :INITABLE-INSTANCE-VARIABLES
                  (:CONSTRUCTOR MAKE-CIRCLE))
       (DEFMACRO CIRCLE (ID CENTER RADIUS PLANE)
         `(SETQ ,ID (MAKE-CIRCLE |:PLANE| PLANE |:RADIUS| RADIUS |:CENTER| CENTER))))

which isn't quite right, since I need commas in front of the value halfs of
the pairs, (|:PLANE| ,PLANE ...

I can replace the ,`,@(keyword-pairs ... with ,,@ ,,,
but then I get 
(PROGN (DEFFLAVOR CIRCLE
                  (CENTER RADIUS PLANE)
                  NIL
                  :INITABLE-INSTANCE-VARIABLES
                  (:CONSTRUCTOR MAKE-CIRCLE))
       (DEFMACRO CIRCLE (ID CENTER RADIUS PLANE)
         `(SETQ ,ID (MAKE-CIRCLE ,|:PLANE| ,PLANE ,|:RADIUS| ,RADIUS ,|:CENTER| ,CENTER))))

which is also incorrect, since a call to circle will now try to evaluate
|:PLANE|, which would be wrong.

Still looking for help.
Strip
drstrip@sandia.gov