describe.scm 6.0 KB

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