Advertisement
Shinmera

Radiance implement.lisp

Jul 2nd, 2013
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lisp 3.27 KB | None | 0 0
  1. #|
  2.   This file is a part of TyNETv5/Radiance
  3.   (c) 2013 TymoonNET/NexT http://tymoon.eu (shinmera@tymoon.eu)
  4.   Author: Nicolas Hafner <shinmera@tymoon.eu>
  5. |#
  6.  
  7. (in-package :radiance)
  8.  
  9. (defvar *radiance-implements* (make-hash-table) "Radiance implements table.")
  10.  
  11. (defclass implementation ()
  12.   ((module :initform NIL :initarg :module :accessor module :type module)
  13.    (superclass :initform (error "Superclass required.") :initarg :superclass :accessor superclass :type symbol))
  14.   (:documentation "Radiance implementation class to hold information about an implementations slot."))
  15.  
  16. (defmethod print-object ((impl implementation) out)
  17.   (print-unreadable-object (impl out :type t)
  18.     (format out "~a -> ~a" (superclass impl) (module impl))))
  19.  
  20. (defgeneric implement (slot module)
  21.   (:documentation "Registers a module for an implementation."))
  22.  
  23. (defmethod implement ((slot symbol) (module module))
  24.   "Standard implements function for non-existent symbols."
  25.   (error "Implementation ~a unknown!" slot))
  26.  
  27. (defmacro defimplclass (slot superclass)
  28.   "Defines an implementations interface class."
  29.   `(progn
  30.      (log:info "Defining implementation ~a with ~a" ',slot ',superclass)
  31.      (setf (gethash ',slot *radiance-implements*)
  32.            (make-instance 'implementation :superclass ',superclass))
  33.      (defmethod implement ((slot (eql ',slot)) (module module))
  34.        "Standard implements function for badly requested classes."
  35.        (error "Module does not match implementation superclass ~a!" slot))
  36.      (defmethod implement ((slot (eql ',slot)) (module ,superclass))
  37.        (log:info "~a implements ~a" module slot)
  38.        (setf (module (gethash ',slot *radiance-implements*)) module))
  39.      ',superclass))
  40.  
  41. (defmacro defimpl (slot &rest generics)
  42.   "Define a new implementation. A generics definition is a list of the following format: (function-name (additional-args*) docstring?)"
  43.   (let ((documentation "")
  44.         (mod-gens (gensym "IMPL-GENSYM")))
  45.     (when (stringp (car generics))
  46.       (setf documentation (car generics)
  47.             generics (cdr generics)))
  48.     `(progn
  49.        (defclass ,slot (module) ()
  50.          (:documentation ,documentation))
  51.        ,@(loop for generic in generics collect
  52.               (destructuring-bind (func args &optional doc) generic
  53.                 (let* ((args (append args
  54.                                     (if (not (find '&key args)) '(&key))
  55.                                     '(&allow-other-keys)))
  56.                       (gen-args (loop for arg in args collect (if (listp arg) (first arg) arg))))
  57.                   `(progn
  58.                      (defgeneric ,func ,(append (list mod-gens) gen-args)
  59.                        (:documentation ,doc))
  60.                      (defmethod ,func ,(append `((,mod-gens ,slot)) args)
  61.                        ,(format nil "Standard method implementation for ~a's ~a, always throws an error." slot func)
  62.                        
  63.                        #+sbcl (declare (sb-ext:muffle-conditions style-warning))
  64.                        (error "Module ~a does not implement required method ~a!" ,mod-gens ',func))))))
  65.        (defimplclass ,slot ,slot))))
  66.  
  67. (defun implementation (slot)
  68.   "Retrieves the implementing module."
  69.   (module (gethash slot *radiance-implements*)))
  70.  
  71. (defsetf implementation implement)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement