describe.scm 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. ;;; installed-scm-file
  2. ;;;; Copyright (C) 1998, 1999, 2001, 2006, 2008, 2009, 2015 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. ;;;
  127. ;;; Describe for generic functions
  128. ;;;
  129. (define-method (describe (x <generic>))
  130. (let ((name (generic-function-name x))
  131. (methods (generic-function-methods x)))
  132. ;; Title
  133. (format #t "~S is a generic function. It's an instance of ~A.~%"
  134. name (safe-class-name (class-of x)))
  135. ;; Methods
  136. (if (null? methods)
  137. (format #t "(No method defined for ~S)~%" name)
  138. (begin
  139. (format #t "Methods defined for ~S~%" name)
  140. (for-each (lambda (x) (describe x #t)) methods)))))
  141. ;;;
  142. ;;; Describe for methods
  143. ;;;
  144. (define-method (describe (x <method>) . omit-generic)
  145. (letrec ((print-args (lambda (args)
  146. ;; take care of dotted arg lists
  147. (cond ((null? args) (newline))
  148. ((pair? args)
  149. (display #\space)
  150. (display (safe-class-name (car args)))
  151. (print-args (cdr args)))
  152. (else
  153. (display #\space)
  154. (display (safe-class-name args))
  155. (newline))))))
  156. ;; Title
  157. (format #t " Method ~A~%" x)
  158. ;; Associated generic
  159. (if (null? omit-generic)
  160. (let ((gf (method-generic-function x)))
  161. (if gf
  162. (format #t "\t Generic: ~A~%" (generic-function-name gf))
  163. (format #t "\t(No generic)~%"))))
  164. ;; GF specializers
  165. (format #t "\tSpecializers:")
  166. (print-args (method-specializers x))))
  167. (provide 'describe)