X-Git-Url: https://git.distorted.org.uk/~mdw/sod/blobdiff_plain/bf090e021a5c20da452a4841cdfb8eb78e29544e..aa14a4cddcb96b681d5c19a2ec8bad382f43b264:/src/impl-class-make.lisp?ds=sidebyside diff --git a/src/impl-class-make.lisp b/src/impl-class-make.lisp deleted file mode 100644 index 4470416..0000000 --- a/src/impl-class-make.lisp +++ /dev/null @@ -1,240 +0,0 @@ -;;; -*-lisp-*- -;;; -;;; Class construction protocol implementation -;;; -;;; (c) 2009 Straylight/Edgeware -;;; - -;;;----- Licensing notice --------------------------------------------------- -;;; -;;; This file is part of the Sensble Object Design, an object system for C. -;;; -;;; SOD is free software; you can redistribute it and/or modify -;;; it under the terms of the GNU General Public License as published by -;;; the Free Software Foundation; either version 2 of the License, or -;;; (at your option) any later version. -;;; -;;; SOD is distributed in the hope that it will be useful, -;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;; GNU General Public License for more details. -;;; -;;; You should have received a copy of the GNU General Public License -;;; along with SOD; if not, write to the Free Software Foundation, -;;; Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -(cl:in-package #:sod) - -;;;-------------------------------------------------------------------------- -;;; Classes. - -(defmethod guess-metaclass ((class sod-class)) - "Default metaclass-guessing function for classes. - - Return the most specific metaclass of any of the CLASS's direct - superclasses." - (do ((supers (sod-class-direct-superclasses class) (cdr supers)) - (meta nil (let ((candidate (sod-class-metaclass (car supers)))) - (cond ((null meta) candidate) - ((sod-subclass-p meta candidate) meta) - ((sod-subclass-p candidate meta) candidate) - (t (error "Unable to choose metaclass for `~A'" - class)))))) - ((endp supers) meta))) - -(defmethod shared-initialize :after ((class sod-class) slot-names &key pset) - "Specific behaviour for SOD class initialization. - - Properties inspected are as follows: - - * `:metaclass' names the metaclass to use. If unspecified, nil is - stored, and (unless you intervene later) `guess-metaclass' will be - called by `finalize-sod-class' to find a suitable default. - - * `:nick' provides a nickname for the class. If unspecified, a default - (the class's name, forced to lowercase) will be chosen in - `finalize-sod-class'. - - * `:link' names the chained superclass. If unspecified, this class will - be left at the head of its chain." - - ;; If no nickname, copy the class name. It won't be pretty, though. - (default-slot-from-property (class 'nickname slot-names) - (pset :nick :id) - (string-downcase (slot-value class 'name))) - - ;; If no metaclass, guess one in a (Lisp) class-specific way. - (default-slot-from-property (class 'metaclass slot-names) - (pset :metaclass :id meta (find-sod-class meta)) - (guess-metaclass class)) - - ;; If no chain-link, then start a new chain here. - (default-slot-from-property (class 'chain-link slot-names) - (pset :link :id link (find-sod-class link)) - nil)) - -;;;-------------------------------------------------------------------------- -;;; Slots. - -(defmethod make-sod-slot - ((class sod-class) name type pset &optional location) - (with-default-error-location (location) - (let ((slot (make-instance (get-property pset :lisp-class :symbol - 'sod-slot) - :class class - :name name - :type type - :location (file-location location) - :pset pset))) - (with-slots (slots) class - (setf slots (append slots (list slot)))) - (check-unused-properties pset)))) - -(defmethod shared-initialize :after ((slot sod-slot) slot-names &key pset) - "This method does nothing. - - It only exists so that it isn't an error to provide a `:pset' initarg - to (make-instance 'sod-slot ...)." - - (declare (ignore slot-names pset))) - -;;;-------------------------------------------------------------------------- -;;; Slot initializers. - -(defmethod make-sod-instance-initializer - ((class sod-class) nick name value-kind value-form pset - &optional location) - (with-default-error-location (location) - (let* ((slot (find-instance-slot-by-name class nick name)) - (initializer (make-sod-initializer-using-slot - class slot 'sod-instance-initializer - value-kind value-form pset - (file-location location)))) - (with-slots (instance-initializers) class - (setf instance-initializers - (append instance-initializers (list initializer)))) - (check-unused-properties pset)))) - -(defmethod make-sod-class-initializer - ((class sod-class) nick name value-kind value-form pset - &optional location) - (with-default-error-location (location) - (let* ((slot (find-class-slot-by-name class nick name)) - (initializer (make-sod-initializer-using-slot - class slot 'sod-class-initializer - value-kind value-form pset - (file-location location)))) - (with-slots (class-initializers) class - (setf class-initializers - (append class-initializers (list initializer)))) - (check-unused-properties pset)))) - -(defmethod make-sod-initializer-using-slot - ((class sod-class) (slot sod-slot) - init-class value-kind value-form pset location) - (make-instance (get-property pset :lisp-class :symbol init-class) - :class class - :slot slot - :value-kind value-kind - :value-form value-form - :location location - :pset pset)) - -(defmethod shared-initialize :after - ((init sod-initializer) slot-names &key pset) - "This method does nothing. - - It only exists so that it isn't an error to provide a `:pset' initarg - to (make-instance 'sod-initializer ...)." - (declare (ignore slot-names pset)) - nil) - -;;;-------------------------------------------------------------------------- -;;; Messages. - -(defmethod make-sod-message - ((class sod-class) name type pset &optional location) - (with-default-error-location (location) - (let ((message (make-instance (get-property pset :lisp-class :symbol - 'standard-message) - :class class - :name name - :type type - :location (file-location location) - :pset pset))) - (with-slots (messages) class - (setf messages (append messages (list message)))) - (check-unused-properties pset)))) - -(defmethod shared-initialize :after - ((message sod-message) slot-names &key pset) - (declare (ignore slot-names pset)) - (with-slots (type) message - (check-message-type message type))) - -(defmethod check-message-type ((message sod-message) (type c-function-type)) - nil) - -(defmethod check-message-type ((message sod-message) (type c-type)) - (error "Messages must have function type, not ~A" type)) - -;;;-------------------------------------------------------------------------- -;;; Methods. - -(defmethod make-sod-method - ((class sod-class) nick name type body pset &optional location) - (with-default-error-location (location) - (let* ((message (find-message-by-name class nick name)) - (method (make-sod-method-using-message message class - type body pset - (file-location location)))) - (with-slots (methods) class - (setf methods (append methods (list method))))) - (check-unused-properties pset))) - -(defmethod make-sod-method-using-message - ((message sod-message) (class sod-class) type body pset location) - (make-instance (or (get-property pset :lisp-class :symbol) - (sod-message-method-class message class pset)) - :message message - :class class - :type type - :body body - :location location - :pset pset)) - -(defmethod sod-message-method-class - ((message sod-message) (class sod-class) pset) - (declare (ignore pset)) - 'sod-method) - -(defmethod shared-initialize :after - ((method sod-method) slot-names &key pset) - (declare (ignore slot-names pset)) - - ;; Check that the arguments are named if we have a method body. - (with-slots (body type) method - (unless (or (not body) - (every #'argument-name (c-function-arguments type))) - (error "Abstract declarators not permitted in method definitions"))) - - ;; Check the method type. - (with-slots (message type) method - (check-method-type method message type))) - -(defmethod check-method-type - ((method sod-method) (message sod-message) (type c-type)) - (error "Methods must have function type, not ~A" type)) - -(defmethod check-method-type - ((method sod-method) (message sod-message) (type c-function-type)) - (with-slots ((msgtype type)) message - (unless (c-type-equal-p (c-type-subtype msgtype) - (c-type-subtype type)) - (error "Method return type ~A doesn't match message ~A" - (c-type-subtype msgtype) (c-type-subtype type))) - (unless (argument-lists-compatible-p (c-function-arguments msgtype) - (c-function-arguments type)) - (error "Method arguments ~A don't match message ~A" type msgtype)))) - -;;;----- That's all, folks --------------------------------------------------