describe.scm 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. ;;; installed-scm-file
  2. ;;;; Copyright (C) 1998, 1999, 2001, 2006, 2008, 2009 Free Software Foundation, Inc.
  3. ;;;; Copyright (C) 1993-1998 Erick Gallesio - I3S-CNRS/ESSI <eg@unice.fr>
  4. ;;;;
  5. ;;;; This library is free software; you can redistribute it and/or
  6. ;;;; modify it under the terms of the GNU Lesser General Public
  7. ;;;; License as published by the Free Software Foundation; either
  8. ;;;; version 3 of the License, or (at your option) any later version.
  9. ;;;;
  10. ;;;; This library is distributed in the hope that it will be useful,
  11. ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. ;;;; Lesser General Public License for more details.
  14. ;;;;
  15. ;;;; You should have received a copy of the GNU Lesser General Public
  16. ;;;; License along with this library; if not, write to the Free Software
  17. ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  18. ;;;;
  19. ;;;;
  20. ;;;; This file was based upon describe.stklos from the STk distribution
  21. ;;;; version 4.0.1 by Erick Gallesio <eg@unice.fr>.
  22. ;;;;
  23. (define-module (oop goops describe)
  24. :use-module (oop goops)
  25. :use-module (ice-9 session)
  26. :use-module (ice-9 format)
  27. :export (describe)) ; Export the describe generic function
  28. ;;;
  29. ;;; describe for simple objects
  30. ;;;
  31. (define-method (describe (x <top>))
  32. (format #t "~s is " x)
  33. (cond
  34. ((integer? x) (format #t "an integer"))
  35. ((real? x) (format #t "a real"))
  36. ((complex? x) (format #t "a complex number"))
  37. ((null? x) (format #t "an empty list"))
  38. ((boolean? x) (format #t "a boolean value (~s)" (if x 'true 'false)))
  39. ((char? x) (format #t "a character, ascii value is ~s"
  40. (char->integer x)))
  41. ((symbol? x) (format #t "a symbol"))
  42. ((list? x) (format #t "a list"))
  43. ((pair? x) (if (pair? (cdr x))
  44. (format #t "an improper list")
  45. (format #t "a pair")))
  46. ((string? x) (if (eqv? x "")
  47. (format #t "an empty string")
  48. (format #t "a string of length ~s" (string-length x))))
  49. ((vector? x) (if (eqv? x '#())
  50. (format #t "an empty vector")
  51. (format #t "a vector of length ~s" (vector-length x))))
  52. ((eof-object? x) (format #t "the end-of-file object"))
  53. (else (format #t "an unknown object (~s)" x)))
  54. (format #t ".~%")
  55. *unspecified*)
  56. (define-method (describe (x <procedure>))
  57. (let ((name (procedure-name x)))
  58. (if name
  59. (format #t "`~s'" name)
  60. (display x))
  61. (display " is ")
  62. (display (if name #\a "an anonymous"))
  63. (display " procedure")
  64. (display " with ")
  65. (arity x)))
  66. ;;;
  67. ;;; describe for GOOPS instances
  68. ;;;
  69. (define (safe-class-name class)
  70. (if (slot-bound? class 'name)
  71. (class-name class)
  72. class))
  73. (define-method (describe (x <object>))
  74. (format #t "~S is an instance of class ~A~%"
  75. x (safe-class-name (class-of x)))
  76. ;; print all the instance slots
  77. (format #t "Slots are: ~%")
  78. (for-each (lambda (slot)
  79. (let ((name (slot-definition-name slot)))
  80. (format #t " ~S = ~A~%"
  81. name
  82. (if (slot-bound? x name)
  83. (format #f "~S" (slot-ref x name))
  84. "#<unbound>"))))
  85. (class-slots (class-of x)))
  86. *unspecified*)
  87. ;;;
  88. ;;; Describe for classes
  89. ;;;
  90. (define-method (describe (x <class>))
  91. (format #t "~S is a class. It's an instance of ~A~%"
  92. (safe-class-name x) (safe-class-name (class-of x)))
  93. ;; Super classes
  94. (format #t "Superclasses are:~%")
  95. (for-each (lambda (class) (format #t " ~A~%" (safe-class-name class)))
  96. (class-direct-supers x))
  97. ;; Direct slots
  98. (let ((slots (class-direct-slots x)))
  99. (if (null? slots)
  100. (format #t "(No direct slot)~%")
  101. (begin
  102. (format #t "Directs slots are:~%")
  103. (for-each (lambda (s)
  104. (format #t " ~A~%" (slot-definition-name s)))
  105. slots))))
  106. ;; Direct subclasses
  107. (let ((classes (class-direct-subclasses x)))
  108. (if (null? classes)
  109. (format #t "(No direct subclass)~%")
  110. (begin
  111. (format #t "Directs subclasses are:~%")
  112. (for-each (lambda (s)
  113. (format #t " ~A~%" (safe-class-name s)))
  114. classes))))
  115. ;; CPL
  116. (format #t "Class Precedence List is:~%")
  117. (for-each (lambda (s) (format #t " ~A~%" (safe-class-name s)))
  118. (class-precedence-list x))
  119. ;; Direct Methods
  120. (let ((methods (class-direct-methods x)))
  121. (if (null? methods)
  122. (format #t "(No direct method)~%")
  123. (begin
  124. (format #t "Class direct methods are:~%")
  125. (for-each describe methods))))
  126. ; (format #t "~%Field Initializers ~% ")
  127. ; (write (slot-ref x 'initializers)) (newline)
  128. ; (format #t "~%Getters and Setters~% ")
  129. ; (write (slot-ref x 'getters-n-setters)) (newline)
  130. )
  131. ;;;
  132. ;;; Describe for generic functions
  133. ;;;
  134. (define-method (describe (x <generic>))
  135. (let ((name (generic-function-name x))
  136. (methods (generic-function-methods x)))
  137. ;; Title
  138. (format #t "~S is a generic function. It's an instance of ~A.~%"
  139. name (safe-class-name (class-of x)))
  140. ;; Methods
  141. (if (null? methods)
  142. (format #t "(No method defined for ~S)~%" name)
  143. (begin
  144. (format #t "Methods defined for ~S~%" name)
  145. (for-each (lambda (x) (describe x #t)) methods)))))
  146. ;;;
  147. ;;; Describe for methods
  148. ;;;
  149. (define-method (describe (x <method>) . omit-generic)
  150. (letrec ((print-args (lambda (args)
  151. ;; take care of dotted arg lists
  152. (cond ((null? args) (newline))
  153. ((pair? args)
  154. (display #\space)
  155. (display (safe-class-name (car args)))
  156. (print-args (cdr args)))
  157. (else
  158. (display #\space)
  159. (display (safe-class-name args))
  160. (newline))))))
  161. ;; Title
  162. (format #t " Method ~A~%" x)
  163. ;; Associated generic
  164. (if (null? omit-generic)
  165. (let ((gf (method-generic-function x)))
  166. (if gf
  167. (format #t "\t Generic: ~A~%" (generic-function-name gf))
  168. (format #t "\t(No generic)~%"))))
  169. ;; GF specializers
  170. (format #t "\tSpecializers:")
  171. (print-args (method-specializers x))))
  172. (provide 'describe)