(defmacro defklass (name super &rest slots) (let ((parents (if super `(,super) nil))) `(defclass ,name ,parents (,@(mapcar #'(lambda (s) (klass1 name s)) slots))))) (defun klass1 (about slot) (let ((initform (if (listp slot) (second slot) nil)) (slotname (if (listp slot) (first slot) slot))) `(,slotname :accessor ,(intern (string-upcase (format nil "~a-~a" about slotname))) :initarg ,(string2keyword (format nil "~a" slotname)) :initform ,initform))) (defun string2keyword (s) (intern (string-upcase (format nil "~a" s)) "KEYWORD")) (defmacro dohash ((key value hash &optional end) &body body) `(progn (maphash #'(lambda (,key ,value) ,@body) ,hash) ,end))