-
Notifications
You must be signed in to change notification settings - Fork 0
/
class.lisp
34 lines (26 loc) · 1.36 KB
/
class.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
;;; This file contains extensions to defclass
;;;
;;; Extensions:
;;; You can add delegates to slots of the class ``(:delegate-to slot-accessor ((method . delegate-method)))``
(in-package #:bedrock)
(defun codegen-delegate (class delegate-obj delegator-method delegate-method)
`((defmethod ,delegator-method ((m ,class))
(funcall #',delegate-method (,delegate-obj m)))
(defmethod (setf ,delegator-method) (new-value (m ,class))
(setf (,delegate-method (,delegate-obj m)) new-value))))
(defun codegen-delegates (class delegate-def)
(let ((expected-delegate (car delegate-def))
(delegate-obj (cadr delegate-def))
(delegate-mappings (caddr delegate-def)))
(when (not (eq expected-delegate :delegate-to))
(error "Malformed delegate expression"))
(reduce #'append (loop for mapping in delegate-mappings
collect (codegen-delegate class delegate-obj (car mapping) (cdr mapping))))))
(defmacro define-class (name superclasses slots &rest properties)
"Extends defclass with some extras like delegates."
(let* ((name (intern (symbol-name name) *package*))
(delegates-defs (remove-if-not (lambda (p) (eq :delegate-to (car p))) properties))
(delegates-codegen (reduce #'append (mapcar (lambda (delegate-def) (codegen-delegates name delegate-def)) delegates-defs))))
`(progn
(defclass ,name ,superclasses ,slots)
,@delegates-codegen)))