Mercurial > core / lisp/lib/obj/meta/pkg.lisp
changeset 698: |
96958d3eb5b0 |
parent: |
efb4a19ff530
|
author: |
Richard Westhaver <ellis@rwest.io> |
date: |
Fri, 04 Oct 2024 22:04:59 -0400 |
permissions: |
-rw-r--r-- |
description: |
fixes |
1 ;;; obj/meta/pkg.lisp --- Meta-objects 10 ;; ordered? https://www.reddit.com/r/lisp/comments/n88x59/metaclasses_using_structures_or_speeding_up_slot/ 14 ;; https://franz.com/support/documentation/11.0/mop/concepts.html 17 (defpackage :obj/meta/stealth 18 (:use :cl :std :obj/meta :sb-mop)) 20 (defpackage :obj/meta/typed 21 (:use :cl :std :obj/meta :sb-mop)) 23 (defpackage :obj/meta/filtered 24 (:use :cl :std :obj/meta :sb-mop) 26 :define-filtered-function :filtered :filtered-function :filtered-method 27 :generic-function-filter-expression :generic-function-filters :method-filter :simple-filtered-function)) 29 (defpackage :obj/meta/sealed 30 (:use :cl :std :obj/meta) 31 (:import-from :sb-pcl :eql-specializer :intern-eql-specializer 32 :eql-specializer-object :funcallable-standard-class) 33 (:import-from :sb-mop :class-finalized-p :finalize-inheritance 34 :class-precedence-list :class-direct-superclasses :specializer :method-specializers 35 :generic-function-argument-precedence-order :generic-function-name :generic-function-methods :class-direct-subclasses 40 :specializer-prototype 41 :specializer-direct-superspecializers 42 :specializer-intersectionp 53 :metaobject-sealable-p 55 :generic-function-sealable-p 57 :specializer-sealable-p 61 :generic-function-sealed-p 66 :seal-generic-function 72 :validate-method-property 74 :static-call-signature 75 :static-call-signature-types 76 :static-call-signature-prototypes 79 :compute-static-call-signatures 80 :externalizable-object-p 82 :sealable-generic-function 83 :sealable-standard-generic-function 84 :potentially-sealable-method 85 :potentially-sealable-standard-method)) 87 (defpackage :obj/meta/fast 88 (:use :cl :std :obj/meta/sealed :obj/meta) 89 (:import-from :sb-int :gensymify) 90 (:import-from :sb-walker :macroexpand-all) 91 (:export :fast-generic-function :fast-method :inlineable)) 93 (defpackage :obj/meta/lazy 94 (:use :cl :std :obj/meta)) 96 (defpackage :obj/meta/overloaded 97 (:use :cl :std :obj/meta)) 99 (defpackage :obj/meta/storable 100 (:use :cl :std :obj/meta :obj/id) 102 :storable-class :initialize-storable-class 103 :storable-slot-mixin :storable-direct-slot-definition 104 :storable-effective-slot-definition)) 106 (in-package :obj/meta) 108 (defun class-equalp (c1 c2) 109 (when (symbolp c1) (setf c1 (find-class c1))) 110 (when (symbolp c2) (setf c2 (find-class c2))) 113 (defun type-specifier-and (&rest type-specifiers) 114 (let ((relevant (remove t type-specifiers))) 115 (cond ((null relevant) t) 116 ((null (cdr relevant)) (first relevant)) 117 (t `(and ,@relevant))))) 119 (defun type-specifier-or (&rest type-specifiers) 120 (let ((relevant (remove nil type-specifiers))) 121 (cond ((null relevant) nil) 122 ((null (cdr relevant)) (first relevant)) 123 (t `(or ,@relevant))))) 125 (defun type-specifier-not (type-specifier) 126 (cond ((eql type-specifier t) nil) 127 ((eql type-specifier nil) t) 128 (t `(not ,type-specifier)))) 130 (defparameter *standard-metaobjects* 131 (list (find-class 'standard-object) 132 (find-class 'standard-class) 133 (find-class 'standard-generic-function) 134 (find-class 'standard-method) 135 (find-class 'built-in-class))) 137 ;;; From ARNESI - Messing with the MOP 139 ;; https://bese.common-lisp.dev/docs/arnesi/html/Messing_0020with_0020the_0020MOP.html#wrapping-standard_0020method_0020combination 141 (define-method-combination wrapping-standard 142 (&key (around-order :most-specific-first) 143 (before-order :most-specific-first) 144 (primary-order :most-specific-first) 145 (after-order :most-specific-last) 146 (wrapping-order :most-specific-last) 147 (wrap-around-order :most-specific-last)) 148 ((wrap-around (:wrap-around)) 151 (wrapping (:wrapping)) 152 (primary () :required t) 154 "Same semantics as standard method combination but allows 155 \"wrapping\" methods. Ordering of methods: 164 :warp-around, :around, :wrapping and :primary methods call the 165 next least/most specific method via call-next-method (as in 166 standard method combination). 168 The various WHATEVER-order keyword arguments set the order in 169 which the methods are called and be set to either 170 :most-specific-last or :most-specific-first." 171 (labels ((effective-order (methods order) 173 (:most-specific-first methods) 174 (:most-specific-last (reverse methods)))) 175 (call-methods (methods) 176 (mapcar (lambda (meth) `(call-method ,meth)) 178 (let* (;; reorder the methods based on the -order arguments 179 (wrap-around (effective-order wrap-around wrap-around-order)) 180 (around (effective-order around around-order)) 181 (wrapping (effective-order wrapping wrapping-order)) 182 (before (effective-order before before-order)) 183 (primary (effective-order primary primary-order)) 184 (after (effective-order after after-order)) 185 ;; inital value of the effective call is a call its primary 187 (form (case (length primary) 188 (1 `(call-method ,(first primary))) 189 (t `(call-method ,(first primary) ,(rest primary)))))) 191 ;; wrap form in call to the wrapping methods 192 (setf form `(call-method ,(first wrapping) 193 (,@(rest wrapping) (make-method ,form))))) 195 ;; wrap FORM in calls to its before methods 197 ,@(call-methods before) 200 ;; wrap FORM in calls to its after methods 201 (setf form `(multiple-value-prog1 203 ,@(call-methods after)))) 205 ;; wrap FORM in calls to its around methods 206 (setf form `(call-method ,(first around) 208 (make-method ,form))))) 210 (setf form `(call-method ,(first wrap-around) 211 (,@(rest wrap-around) 212 (make-method ,form)))))