X-Git-Url: https://git.distorted.org.uk/~mdw/sod/blobdiff_plain/048d0b2d143b6a491ac73eed6ab972e97774391c..300a3f0a55f777216bcc7e9de833b28fb57104ac:/src/pset-proto.lisp diff --git a/src/pset-proto.lisp b/src/pset-proto.lisp index 91668ed..61793b5 100644 --- a/src/pset-proto.lisp +++ b/src/pset-proto.lisp @@ -7,7 +7,7 @@ ;;;----- Licensing notice --------------------------------------------------- ;;; -;;; This file is part of the Sensble Object Design, an object system for C. +;;; This file is part of the Sensible 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 @@ -45,7 +45,7 @@ (:constructor %make-property (name value &key type location seenp - &aux (key (property-key name))))) + &aux (key (property-key name)) (%type type)))) "A simple structure for holding a property in a property set. The main useful feature is the ability to tick off properties which have @@ -55,12 +55,13 @@ distinctly about identifiers, strings and symbols, and we've only got two obvious Lisp types to play with. Sad, but true." - (name nil :type (or string symbol)) - (value nil :type t) - (type nil :type symbol) - (location (file-location nil) :type file-location) - (key nil :type symbol) + (name nil :type (or string symbol) :read-only t) + (value nil :type t :read-only t) + (%type nil :type symbol :read-only t) + (location (file-location nil) :type file-location :read-only t) + (key nil :type symbol :read-only t) (seenp nil :type boolean)) +(define-access-wrapper p-type p-%type :read-only t) (export 'decode-property) (defgeneric decode-property (raw) @@ -70,7 +71,9 @@ (:method ((raw string)) (values :string raw)) (:method ((raw character)) (values :char raw)) (:method ((raw property)) (values (p-type raw) (p-value raw))) - (:method ((raw cons)) (values (car raw) (cdr raw)))) + (:method ((raw cons)) (values (car raw) (cdr raw))) + (:method ((raw function)) (values :func raw)) + (:method ((raw c-type)) (values :type raw))) (export 'make-property) (defun make-property (name raw-value &key type location seenp) @@ -146,6 +149,7 @@ ;; If the caller asks for type T then give him the raw thing. (:method (value type (wanted (eql t))) + (declare (ignore type)) value)) ;;;-------------------------------------------------------------------------- @@ -170,7 +174,7 @@ (defun pset-get (pset key) "Look KEY up in PSET and return what we find. - If there's no property by that name, return NIL." + If there's no property by that name, return nil." (values (gethash key (%pset-hash pset)))) (defun pset-store (pset prop) @@ -224,7 +228,10 @@ Otherwise the value is coerced to the right kind of thing (where possible) and returned. - If PSET is nil, then return DEFAULT." + The file location at which the property was defined is returned as a + second value. + + If PSET is nil, then return DEFAULT and nil." (let ((prop (and pset (pset-get pset (property-key name))))) (with-default-error-location ((and prop (p-location prop))) @@ -284,7 +291,7 @@ ((endp list) pset) (add-property pset (funcall name list) (funcall value list)))))) -(export 'check--unused-properties) +(export 'check-unused-properties) (defun check-unused-properties (pset) "Issue errors about unused properties in PSET." (when pset @@ -300,7 +307,7 @@ ;;; Utility macros. (defmacro default-slot-from-property - ((instance slot slot-names) + ((instance slot &optional (slot-names t)) (pset property type &optional (pvar (gensym "PROP-")) &rest convert-forms) @@ -310,19 +317,25 @@ We initialize SLOT in INSTANCE. In full: if PSET contains a property called NAME, then convert it to TYPE, bind the value to PVAR and evaluate CONVERT-FORMS -- these default to just using the property value. If - there's no property, and the slot is named in SLOT-NAMES and currently + there's no property, and DEFAULT-FORMS contains at least one non- + declaration form, and the slot is named in SLOT-NAMES and currently unbound, then evaluate DEFAULT-FORMS and use their value to compute the slot value." (once-only (instance slot slot-names pset property type) - (with-gensyms (floc) - `(multiple-value-bind (,pvar ,floc) - (get-property ,pset ,property ,type) - (if ,floc - (setf (slot-value ,instance ,slot) - (with-default-error-location (,floc) - ,@(or convert-forms `(,pvar)))) - (default-slot (,instance ,slot ,slot-names) - ,@default-forms)))))) + (multiple-value-bind (docs decls body) + (parse-body default-forms :docp nil) + (declare (ignore docs)) + (with-gensyms (floc) + `(multiple-value-bind (,pvar ,floc) + (get-property ,pset ,property ,type) + ,@decls + (if ,floc + (setf (slot-value ,instance ,slot) + (with-default-error-location (,floc) + ,@(or convert-forms `(,pvar)))) + ,@(and body + `((default-slot (,instance ,slot ,slot-names) + ,@body))))))))) ;;;----- That's all, folks --------------------------------------------------