(defmacro defclass* (cls-name parents local-vars) (let ((slot-vars (parse-slot-vars local-vars)) (accessors (parse-accessors local-vars))) `(define-class ',cls-name ',parents ',slot-vars ',accessors))) ;;; (defun parse-slot-vars (local-vars) (mapcar #'(lambda (x) (cond ((atom x) x) (t (list (car x) (cadr (member :initform (cdr x))))))) local-vars)) (defun parse-accessors (local-vars) (mapcar #'(lambda (x) (cond ((atom x) (list x x (intern (format nil "SET-~a" x)))) (t (list (car x) (or (cadr (member :accessor (cdr x))) (car x)) (intern (format nil "SET-~a" (car x))))))) local-vars)) ;;; (defun define-class (cls-name parents local-vars local-accessors) (let* ((locals (get-all-local-vars (if parents parents '(t)) local-vars)) (accessors (get-all-accessors (if parents parents '(t)) local-accessors)) (class (make-cls :name cls-name :parents (if parents parents '(t)) :local-variables locals :accessors accessors :functions (if (defined-class? cls-name) (cls-functions (get-class cls-name)) (make-hash-table))))) (mapc #'create-local-var-generic-function accessors) (store-class cls-name class))) (defun create-local-var-generic-function (var&accessor) (let* ((local-var (car var&accessor)) (accessor (cadr var&accessor)) (set-accessor (caddr var&accessor))) (setf (symbol-function accessor) (eval `(function (lambda (self) (send self ',accessor))))) (eval `(defsetf ,accessor (self) (value) (list 'send self '',set-accessor value))) )) (defun local-var (loc-var) (if (atom loc-var) loc-var (car loc-var))) (defun get-all-local-vars (parents loc-vars) (dolist (parent parents (remove-duplicates loc-vars :key #'local-var)) (setf loc-vars (append (cls-local-variables (get-class parent)) loc-vars)))) (defun get-all-accessors (parents loc-accs) (dolist (parent parents loc-accs) (setf loc-accs (append (cls-accessors (get-class parent)) loc-accs))))ここでは,setfで代入が可能となる ための手続きを定義するためのdefsetfを用いています.