;;;--------------------------------------------------------------------------
;;; Walking the layout tree.
-(defmethod hook-output progn ((class sod-class) reason sequencer)
+(defmethod hook-output :after ((class sod-class) reason sequencer)
(with-slots ((ilayout %ilayout) vtables methods effective-methods) class
(hook-output ilayout reason sequencer)
(dolist (method methods) (hook-output method reason sequencer))
(dolist (method effective-methods) (hook-output method reason sequencer))
(dolist (vtable vtables) (hook-output vtable reason sequencer))))
-(defmethod hook-output progn ((ilayout ilayout) reason sequencer)
+(defmethod hook-output :after ((ilayout ilayout) reason sequencer)
(with-slots (ichains) ilayout
(dolist (ichain ichains) (hook-output ichain reason sequencer))))
-(defmethod hook-output progn ((ichain ichain) reason sequencer)
+(defmethod hook-output :after ((ichain ichain) reason sequencer)
(dolist (item (ichain-body ichain)) (hook-output item reason sequencer)))
-(defmethod hook-output progn ((islots islots) reason sequencer)
+(defmethod hook-output :after ((islots islots) reason sequencer)
(dolist (slot (islots-slots islots)) (hook-output slot reason sequencer)))
-(defmethod hook-output progn ((vtable vtable) reason sequencer)
+(defmethod hook-output :after ((vtable vtable) reason sequencer)
(with-slots (body) vtable
(dolist (item body) (hook-output item reason sequencer))))
-(defmethod hook-output progn ((vtmsgs vtmsgs) reason sequencer)
+(defmethod hook-output :after ((vtmsgs vtmsgs) reason sequencer)
(with-slots (entries) vtmsgs
(dolist (entry entries) (hook-output entry reason sequencer))))
;;;--------------------------------------------------------------------------
;;; Classes.
-(defmethod hook-output progn ((class sod-class) (reason (eql :h)) sequencer)
+(defmethod hook-output ((class sod-class) (reason (eql :h)) sequencer)
;; Main output sequencing.
(sequence-output (stream sequencer)
(metaroot (find-root-metaclass class)))
(format stream "/* The class object. */~@
extern const struct ~A ~A__classobj;~@
- #define ~:*~A__class (&~:*~A__classobj.~A.~A)~2%"
+ #define ~:*~A__class (&~:*~A__classobj.~A.~A)~%"
(ilayout-struct-tag metaclass) class
(sod-class-nickname (sod-class-chain-head metaroot))
- (sod-class-nickname metaroot)))))
+ (sod-class-nickname metaroot))
+ (dolist (chain (sod-class-chains metaclass))
+ (let ((tail (car chain)))
+ (unless (eq tail metaroot)
+ (format stream "#define ~A__cls_~A (&~2:*~A__classobj.~A.~A)~%"
+ class (sod-class-nickname (sod-class-chain-head tail))
+ (sod-class-nickname tail)))))
+ (terpri stream))))
;; Maybe generate an islots structure.
(when (sod-class-slots class)
- (dolist (slot (sod-class-slots class))
- (hook-output slot 'islots sequencer))
(sequence-output (stream sequencer)
((class :islots :start)
(format stream "/* Instance slots. */~@
(when varargsp
(format stream "#ifdef SOD__HAVE_VARARGS_MACROS~%"))
(format stream "#define ~A(~{~A~^, ~}) ~
- ~A->_vt->~A.~A(~{~A~^, ~})~%"
+ (~A)->_vt->~A.~A(~{~A~^, ~})~%"
(message-macro-name class entry)
(nreverse in-names)
me
(nreverse out-names))
(when varargsp
(format stream "#endif~%"))))
- (terpri stream)))))
+ (terpri stream))))))
+
+(defmethod hook-output :after ((class sod-class) (reason (eql :h)) sequencer)
- ;; Generate vtmsgs structure for all superclasses.
+ ;; Output a structure member definition for each instance slot.
+ (dolist (slot (sod-class-slots class))
+ (hook-output slot 'islots sequencer))
+
+ ;; Generate a vtmsgs structure for all superclasses.
(hook-output (car (sod-class-vtables class)) 'vtmsgs sequencer))
;;;--------------------------------------------------------------------------
;;; Instance structure.
-(defmethod hook-output progn
- ((slot sod-slot) (reason (eql 'islots)) sequencer)
+(defmethod hook-output ((slot sod-slot) (reason (eql 'islots)) sequencer)
(sequence-output (stream sequencer)
(((sod-slot-class slot) :islots :slots)
(pprint-logical-block (stream nil :prefix " " :suffix ";")
(pprint-c-type (sod-slot-type slot) stream (sod-slot-name slot)))
(terpri stream))))
-(defmethod hook-output progn ((ilayout ilayout) (reason (eql :h)) sequencer)
- (with-slots ((class %class) ichains) ilayout
+(defmethod hook-output ((ilayout ilayout) (reason (eql :h)) sequencer)
+ (with-slots ((class %class)) ilayout
(sequence-output (stream sequencer)
((class :ilayout :start)
(format stream "/* Instance layout. */~@
struct ~A {~%"
(ilayout-struct-tag class)))
((class :ilayout :end)
- (format stream "};~2%")))
- (dolist (ichain ichains)
- (hook-output ichain 'ilayout sequencer))))
+ (format stream "};~2%")))))
+
+(defmethod hook-output :after ((ilayout ilayout) (reason (eql :h)) sequencer)
+ (dolist (ichain (ilayout-ichains ilayout))
+ (hook-output ichain 'ilayout sequencer)))
-(defmethod hook-output progn ((ichain ichain) (reason (eql :h)) sequencer)
+(defmethod hook-output ((ichain ichain) (reason (eql :h)) sequencer)
(with-slots ((class %class) chain-head chain-tail) ichain
(when (eq class chain-tail)
(sequence-output (stream sequencer)
(sod-class-nickname super)))
(sod-class-chain chain-tail))))))))
-(defmethod hook-output progn
- ((ichain ichain) (reason (eql 'ilayout)) sequencer)
+(defmethod hook-output ((ichain ichain) (reason (eql 'ilayout)) sequencer)
(with-slots ((class %class) chain-head chain-tail) ichain
(sequence-output (stream sequencer)
((class :ilayout :slots)
(ichain-union-tag chain-tail chain-head)
(sod-class-nickname chain-head))))))
-(defmethod hook-output progn ((vtptr vtable-pointer)
- (reason (eql :h))
- sequencer)
+(defmethod hook-output ((vtptr vtable-pointer) (reason (eql :h)) sequencer)
(with-slots ((class %class) chain-head chain-tail) vtptr
(when (eq class chain-tail)
(sequence-output (stream sequencer)
(format stream " const struct ~A *_vt;~%"
(vtable-struct-tag chain-tail chain-head)))))))
-(defmethod hook-output progn ((islots islots) (reason (eql :h)) sequencer)
+(defmethod hook-output ((islots islots) (reason (eql :h)) sequencer)
(with-slots ((class %class) subclass slots) islots
(let ((head (sod-class-chain-head class)))
(when (eq head (sod-class-chain-head subclass))
;;;--------------------------------------------------------------------------
;;; Vtable structure.
-(defmethod hook-output progn
- ((method sod-method) (reason (eql :h)) sequencer)
+(defmethod hook-output ((method sod-method) (reason (eql :h)) sequencer)
(with-slots ((class %class)) method
(sequence-output (stream sequencer)
((class :methods)
(c-function-keywords type))))
(when keys
(format stream "struct ~A {~%~
- ~{ unsigned ~A : 1;~%~}~
+ ~{ unsigned ~A: 1;~%~}~
};~2%"
(direct-method-suppliedp-struct-tag method)
(mapcar #'argument-name keys))))))))
-(defmethod hook-output progn ((vtable vtable) (reason (eql :h)) sequencer)
+(defmethod hook-output ((vtable vtable) (reason (eql :h)) sequencer)
(with-slots ((class %class) chain-head chain-tail) vtable
(when (eq class chain-tail)
(sequence-output (stream sequencer)
(vtable-union-tag chain-tail chain-head)
(vtable-name class chain-head))))))
-(defmethod hook-output progn ((vtmsgs vtmsgs) (reason (eql :h)) sequencer)
+(defmethod hook-output ((vtmsgs vtmsgs) (reason (eql :h)) sequencer)
(with-slots ((class %class) subclass chain-head chain-tail) vtmsgs
(when (eq subclass chain-tail)
(sequence-output (stream sequencer)
(vtmsgs-struct-tag subclass class)
(sod-class-nickname class)))))))
-(defmethod hook-output progn
- ((vtmsgs vtmsgs) (reason (eql 'vtmsgs)) sequencer)
+(defmethod hook-output ((vtmsgs vtmsgs) (reason (eql 'vtmsgs)) sequencer)
(when (vtmsgs-entries vtmsgs)
(with-slots ((class %class) subclass) vtmsgs
(sequence-output (stream sequencer)
((subclass :vtmsgs class :end)
(format stream "};~2%"))))))
-(defmethod hook-output progn
- ((entry method-entry) (reason (eql 'vtmsgs)) sequencer)
+(defmethod hook-output ((entry method-entry)
+ (reason (eql 'vtmsgs)) sequencer)
(let* ((method (method-entry-effective-method entry))
(message (effective-method-message method))
(class (effective-method-class method))
(pprint-c-type pointer-type stream (method-entry-slot-name entry)))
(terpri stream)))))
-(defmethod hook-output progn
- ((cptr class-pointer) (reason (eql :h)) sequencer)
+(defmethod hook-output ((cptr class-pointer) (reason (eql :h)) sequencer)
(with-slots ((class %class) chain-head metaclass meta-chain-head) cptr
(when (eq chain-head (sod-class-chain-head class))
(sequence-output (stream sequencer)
(and (sod-class-direct-superclasses meta-chain-head)
(sod-class-nickname meta-chain-head))))))))
-(defmethod hook-output progn ((boff base-offset) (reason (eql :h)) sequencer)
+(defmethod hook-output ((boff base-offset) (reason (eql :h)) sequencer)
(with-slots ((class %class) chain-head) boff
(when (eq chain-head (sod-class-chain-head class))
(sequence-output (stream sequencer)
((class :vtable chain-head :slots)
(write-line " size_t _base;" stream))))))
-(defmethod hook-output progn
- ((choff chain-offset) (reason (eql :h)) sequencer)
+(defmethod hook-output ((choff chain-offset) (reason (eql :h)) sequencer)
(with-slots ((class %class) chain-head target-head) choff
(when (eq chain-head (sod-class-chain-head class))
(sequence-output (stream sequencer)
It may be bound at other times.")
-(defmethod hook-output progn ((class sod-class) (reason (eql :c)) sequencer)
+(defmethod hook-output ((class sod-class) (reason (eql :c)) sequencer)
(sequence-output (stream sequencer)
:constraint
(ilayout-struct-tag (sod-class-metaclass class))
class))
((class :object :end)
- (format stream "};~2%")))
+ (format stream "};~2%"))))
+(defmethod hook-output :after ((class sod-class) (reason (eql :c)) sequencer)
(let ((*instance-class* class))
(hook-output (sod-class-ilayout (sod-class-metaclass class))
'class sequencer)))
;;;--------------------------------------------------------------------------
;;; Direct and effective methods.
-(defmethod hook-output progn
- ((method delegating-direct-method) (reason (eql :c)) sequencer)
+(defmethod hook-output ((method delegating-direct-method)
+ (reason (eql :c)) sequencer)
(with-slots ((class %class) body) method
(unless body
(return-from hook-output))
(c-function-arguments (sod-method-next-method-type
method)))))
((class :direct-method method :end)
- (format stream "#undef CALL_NEXT_METHOD~%")))))
+ (format stream "#undef CALL_NEXT_METHOD~%"))))
+ (call-next-method))
-(defmethod hook-output progn
- ((method sod-method) (reason (eql :c)) sequencer)
+(defmethod hook-output ((method sod-method) (reason (eql :c)) sequencer)
(with-slots ((class %class) role body message) method
(unless body
(return-from hook-output))
((class :direct-method method :end)
(terpri stream)))))
-(defmethod hook-output progn
- ((method basic-effective-method) (reason (eql :c)) sequencer)
+(defmethod hook-output ((method basic-effective-method)
+ (reason (eql :c)) sequencer)
(with-slots ((class %class) functions) method
(sequence-output (stream sequencer)
((class :effective-methods)
class)
(format stream "~&struct ~A {~%"
(effective-method-keyword-struct-tag method))
- (format stream "~{ unsigned ~A__suppliedp : 1;~%~}"
+ (format stream "~{ unsigned ~A__suppliedp: 1;~%~}"
(mapcar #'argument-name keys))
(dolist (key keys)
(write-string " " stream)
;;;--------------------------------------------------------------------------
;;; Vtables.
-(defmethod hook-output progn ((vtable vtable) (reason (eql :c)) sequencer)
+(defmethod hook-output ((vtable vtable) (reason (eql :c)) sequencer)
(with-slots ((class %class) chain-head chain-tail) vtable
(sequence-output (stream sequencer)
:constraint ((class :vtables :start)
((class :vtable chain-head :end)
(format stream "} };~2%")))))
-(defmethod hook-output progn
- ((cptr class-pointer) (reason (eql :c)) sequencer)
+(defmethod hook-output ((cptr class-pointer) (reason (eql :c)) sequencer)
(with-slots ((class %class) chain-head metaclass meta-chain-head) cptr
(sequence-output (stream sequencer)
:constraint ((class :vtable chain-head :start)
(sod-class-nickname meta-chain-head)
(sod-class-nickname metaclass))))))
-(defmethod hook-output progn ((boff base-offset) (reason (eql :c)) sequencer)
+(defmethod hook-output ((boff base-offset) (reason (eql :c)) sequencer)
(with-slots ((class %class) chain-head) boff
(sequence-output (stream sequencer)
:constraint ((class :vtable chain-head :start)
(ilayout-struct-tag class)
(sod-class-nickname chain-head))))))
-(defmethod hook-output progn
- ((choff chain-offset) (reason (eql :c)) sequencer)
+(defmethod hook-output ((choff chain-offset) (reason (eql :c)) sequencer)
(with-slots ((class %class) chain-head target-head) choff
(sequence-output (stream sequencer)
:constraint ((class :vtable chain-head :start)
(sod-class-nickname chain-head)
(sod-class-nickname target-head))))))
-(defmethod hook-output progn ((vtmsgs vtmsgs) (reason (eql :c)) sequencer)
+(defmethod hook-output ((vtmsgs vtmsgs) (reason (eql :c)) sequencer)
(with-slots ((class %class) subclass chain-head) vtmsgs
(sequence-output (stream sequencer)
:constraint ((subclass :vtable chain-head :start)
((subclass :vtable chain-head :vtmsgs class :end)
(format stream " },~%")))))
-(defmethod hook-output progn
- ((entry method-entry) (reason (eql :c)) sequencer)
+(defmethod hook-output ((entry method-entry) (reason (eql :c)) sequencer)
(with-slots ((method %method) chain-head chain-tail role) entry
(let* ((message (effective-method-message method))
(class (effective-method-class method))
;;;--------------------------------------------------------------------------
;;; Filling in the class object.
-(defmethod hook-output progn
- ((ichain ichain) (reason (eql 'class)) sequencer)
+(defmethod hook-output ((ichain ichain) (reason (eql 'class)) sequencer)
(with-slots ((class %class) chain-head) ichain
(sequence-output (stream sequencer)
:constraint ((*instance-class* :object :start)
((*instance-class* :object chain-head :ichain :end)
(format stream " } },~%")))))
-(defmethod hook-output progn
- ((islots islots) (reason (eql 'class)) sequencer)
+(defmethod hook-output ((islots islots) (reason (eql 'class)) sequencer)
(with-slots ((class %class)) islots
(let ((chain-head (sod-class-chain-head class)))
(sequence-output (stream sequencer)
((*instance-class* :object class :slots :end)
(format stream " },~%"))))))
-(defmethod hook-output progn
- ((vtptr vtable-pointer) (reason (eql 'class)) sequencer)
+(defmethod hook-output ((vtptr vtable-pointer)
+ (reason (eql 'class)) sequencer)
(with-slots ((class %class) chain-head chain-tail) vtptr
(sequence-output (stream sequencer)
:constraint ((*instance-class* :object chain-head :ichain :start)
(vtable-name class chain-head)
(sod-class-nickname chain-tail))))))
-(defgeneric find-class-initializer (slot class)
- (:method ((slot effective-slot) (class sod-class))
- (let ((dslot (effective-slot-direct-slot slot)))
- (or (some (lambda (super)
- (find dslot (sod-class-class-initializers super)
- :test #'sod-initializer-slot))
- (sod-class-precedence-list class))
- (effective-slot-initializer slot)))))
-
(defgeneric output-class-initializer (slot instance stream)
(:method ((slot sod-class-effective-slot) (instance sod-class) stream)
(let ((func (effective-slot-initializer-function slot))
(sod-slot-name direct-slot)
(sod-initializer-value init)))))
-(defmethod hook-output progn
- ((slot sod-class-effective-slot) (reason (eql 'class)) sequencer)
+(defmethod hook-output ((slot sod-class-effective-slot)
+ (reason (eql 'class)) sequencer)
(let ((instance *instance-class*)
(func (effective-slot-prepare-function slot)))
(when func
(sequence-output (stream sequencer)
((instance :object :prepare)
- (funcall func instance stream))))))
+ (funcall func instance stream)))))
+ (call-next-method))
-(defmethod hook-output progn
- ((slot effective-slot) (reason (eql 'class)) sequencer)
+(defmethod hook-output ((slot effective-slot)
+ (reason (eql 'class)) sequencer)
(with-slots ((class %class) (dslot slot)) slot
(let ((instance *instance-class*)
(super (sod-slot-class dslot)))