(in-package #:mulk.objective-cl)
(eval-when (:compile-toplevel :load-toplevel :execute)
  (defun selector-load-time-form (method-name)
    "This docstring has been put here for demonstration purposes."
    `(load-time-value
      (handler-case
          (find-selector ',method-name)
        (serious-condition ()
          (warn (make-condition 'simple-style-warning
                                :format-control "~S designates an unknown method selector."
                                :format-arguments (list ',method-name)))
          ',method-name)))))
(define-compiler-macro selector (&whole form method-name)
  (if (constantp method-name)
      (selector-load-time-form (eval method-name))
      form))
(define-compiler-macro primitive-invoke (&whole form
                                         receiver method-name return-type
                                         &rest args)
  (if (constantp method-name)
      `(primitive-invoke ,receiver (selector ,method-name) ,return-type ,@args)
      form))
(define-compiler-macro invoke-by-name (&whole form
                                       receiver method-name &rest args)
  (if (constantp method-name)
      `(invoke-by-name ,receiver (selector ,method-name) ,@args)
      form))
(define-compiler-macro invoke (&whole form
                               receiver message-start &rest message-components)
  (multiple-value-bind (method-name args)
      (split-method-call message-start message-components)
    (if (and (listp method-name)
             (every #'constantp method-name))
        `(invoke-by-name ,receiver (selector ',(mapcar #'eval method-name))
                         ,@args)
        form)))