;;;-*-Mode: LISP; Package: CCL -*- ;;; ;;; Copyright (C) 2009 Clozure Associates ;;; Copyright (C) 1994-2001 Digitool, Inc ;;; This file is part of Clozure CL. ;;; ;;; Clozure CL is licensed under the terms of the Lisp Lesser GNU Public ;;; License , known as the LLGPL and distributed with Clozure CL as the ;;; file "LICENSE". The LLGPL consists of a preamble and the LGPL, ;;; which is distributed with Clozure CL as the file "LGPL". Where these ;;; conflict, the preamble takes precedence. ;;; ;;; Clozure CL is referenced in the preamble as the "LIBRARY." ;;; ;;; The LLGPL is also available online at ;;; http://opensource.franz.com/preamble.html ; This file is needed to compile DEFSTRUCT and anything accessing defstruct ; data structures. (in-package "CCL") (eval-when (:execute :compile-toplevel) (require "LISPEQU")) (defconstant $struct-r/o 24) ; Read-only bit in refinfo fixnum (defconstant $struct-inherited 25) ; Struct slot is inherited. (defconstant $defstruct-nth 0) ; Anything that won't conflict with array types... (defconstant $defstruct-struct 8) (defconstant $defstruct-simple-vector 16) (defmacro ssd-name (ssd) `(car ,ssd)) ;(defmacro ssd-type (ssd) (declare (ignore ssd)) t) (defmacro ssd-initform (ssd) `(cadr ,ssd)) ;(defmacro ssd-refinfo (ssd) `(cddr ,ssd)) (defmacro ssd-update-refinfo ((ssd refinfo-var) new-refinfo-form) (check-type refinfo-var symbol) (let ((refinfo-cons (gensym))) `(let* ((,refinfo-cons (cdr ,ssd)) (,refinfo-var (cdr ,refinfo-cons))) (when (consp ,refinfo-var) (setq ,refinfo-cons ,refinfo-var) (setq ,refinfo-var (%cdr ,refinfo-cons))) (%rplacd ,refinfo-cons ,new-refinfo-form)))) (defmacro refinfo-offset (refinfo) `(%ilogand2 #xFFFF ,refinfo)) (defmacro refinfo-r/o (refinfo) `(%ilogbitp $struct-r/o ,refinfo)) (defmacro refinfo-reftype (refinfo) `(%ilogand2 #xFF (%ilsr 16 ,refinfo))) (defmacro refinfo-inherited (refinfo) `(%ilogbitp $struct-inherited ,refinfo)) (defmacro ssd-offset (ssd) `(refinfo-offset (ssd-refinfo ,ssd))) (defmacro ssd-r/o (ssd) `(refinfo-r/o (ssd-refinfo ,ssd))) (defmacro ssd-reftype (ssd) `(refinfo-reftype (ssd-refinfo ,ssd))) (defmacro ssd-inherited (ssd) `(refinfo-inherited (ssd-refinfo ,ssd))) (defmacro ssd-set-initform (ssd value) `(rplaca (cdr ,ssd) ,value)) #| these are fns now (defmacro ssd-set-reftype (ssd reftype) ;-> ssd multiply evaluated `(rplacd (cdr ,ssd) (%ilogior2 (%ilogand2 #x100FFFF (cdr (%cdr ,ssd))) (%ilsl 16 ,reftype)))) (defmacro ssd-set-r/o (ssd) ;-> ssd multiply evaluated `(rplacd (cdr ,ssd) (%ilogior2 #x1000000 (cdr (%cdr ,ssd))))) (defmacro copy-ssd (ssd) ;-> ssd multiply evaluated `(list* (car ,ssd) (car (%cdr ,ssd)) (%cddr ,ssd))) |# (defmacro named-ssd (name slot-list) `(assq ,name ,slot-list)) (defmacro sd-name (sd) `(car (svref ,sd 2))) (defmacro sd-type (sd) `(svref ,sd 0)) (defmacro sd-slots (sd) `(svref ,sd 1)) (defmacro sd-superclasses (sd) `(svref ,sd 2)) (defmacro sd-size (sd) `(svref ,sd 3)) (defmacro sd-constructor (sd) `(svref ,sd 4)) (defmacro sd-print-function (sd) `(svref ,sd 5)) (defmacro sd-set-print-function (sd value) `(svset ,sd 5 ,value)) (defmacro sd-refnames (sd) `(svref ,sd 6)) (defmacro struct-name (struct) `(class-cell-name (car (uvref ,struct 0)))) (defmacro struct-def (struct) `(gethash (struct-name ,struct) %defstructs%)) ;Can use this to let the printer print with print-function, reader read with ;constructor and slot-names, inspector inspect with slot-names. ;Everything else you have to arrange yourself. #+ignore (defmacro pretend-i-am-a-structure (name constructor print-function &rest slot-names) (let ((slots slot-names) (offset 1) (supers (list name))) (while slots (%rplaca slots (make-ssd (%car slots) () offset t)) (ssd-set-reftype (%car slots) $v_struct) (setq slots (%cdr slots) offset (1+ offset))) (push (make-ssd 0 `',supers 0 t) slot-names) (ssd-set-reftype (%car slot-names) $v_struct) `(puthash ',name %defstructs% '#(internal-structure ;Make structure-class-p false. ,slot-names ,supers ,offset ,constructor ,print-function nil)))) (provide 'defstruct-macros) ; End of defstruct-macros.lisp