;; A Poor Man's CLOS for test purposes
;;AUTOLOAD: defmethod
;;AUTOLOAD: add-method

(setq *package* 'pmc)

(defvar %methods (Hashtable ()))

(defmacro defmethod (name lambdalist &rest body &aux
    (class (1 (0 lambdalist)))
    (params (+ (list (0 (0 lambdalist))) (subseq lambdalist 1)))
  )
  (set name %send)
  `(add-method ,class ',name (lambda ,params ,@body))
)

(setq Errors:Undefined-pmc-method "undefined method %0 for type %1!
       sent to: %r2)\n")

(defun %send (&rest args &whole call &aux
    (selector (0 call))
    (obj (0 args))
  )
  (apply (get %methods (list (type-of obj) selector)
      '(error 'Errors:Undefined-pmc-method selector (type-of obj) args)
    )
    args)
)

(defun add-method (class name method)
  (if method
    (put %methods (list class name) method)
    (delete %methods (list class name))
  )
)
  
(defun find-method (class name)
  (get %methods (list class name) ())
)

(defun copy-method (name &rest args)
  (dohash (classfrom classto args)
    (add-method classto name (find-method classfrom name))
  )
)

