PageRenderTime 56ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/guile-1.8.8/ice-9/debugger/utils.scm

#
Scheme | 203 lines | 143 code | 19 blank | 41 comment | 0 complexity | 030c8a6e81dbeb1290a8ffd40185a3a0 MD5 | raw file
Possible License(s): LGPL-2.1
  1. (define-module (ice-9 debugger utils)
  2. #:use-module (ice-9 debugger state)
  3. #:export (display-position
  4. source-position
  5. write-frame-args-long
  6. write-frame-index-long
  7. write-frame-short/expression
  8. write-frame-short/application
  9. write-frame-long
  10. write-state-long
  11. write-state-short))
  12. ;;; Procedures in this module print information about a stack frame.
  13. ;;; The available information is as follows.
  14. ;;;
  15. ;;; * Source code location.
  16. ;;;
  17. ;;; For an evaluation frame, this is the location recorded at the time
  18. ;;; that the expression being evaluated was read, if the 'positions
  19. ;;; read option was enabled at that time.
  20. ;;;
  21. ;;; For an application frame, I'm not yet sure. Some applications
  22. ;;; seem to have associated source expressions.
  23. ;;;
  24. ;;; * Whether frame is still evaluating its arguments.
  25. ;;;
  26. ;;; Only applies to an application frame. For example, an expression
  27. ;;; like `(+ (* 2 3) 4)' goes through the following stages of
  28. ;;; evaluation.
  29. ;;;
  30. ;;; (+ (* 2 3) 4) -- evaluation
  31. ;;; [+ ... -- application; the car of the evaluation
  32. ;;; has been evaluated and found to be a
  33. ;;; procedure; before this procedure can
  34. ;;; be applied, its arguments must be evaluated
  35. ;;; [+ 6 ... -- same application after evaluating the
  36. ;;; first argument
  37. ;;; [+ 6 4] -- same application after evaluating all
  38. ;;; arguments
  39. ;;; 10 -- result
  40. ;;;
  41. ;;; * Whether frame is real or tail-recursive.
  42. ;;;
  43. ;;; If a frame is tail-recursive, its containing frame as shown by the
  44. ;;; debugger backtrace doesn't really exist as far as the Guile
  45. ;;; evaluator is concerned. The effect of this is that when a
  46. ;;; tail-recursive frame returns, it looks as though its containing
  47. ;;; frame returns at the same time. (And if the containing frame is
  48. ;;; also tail-recursive, _its_ containing frame returns at that time
  49. ;;; also, and so on ...)
  50. ;;;
  51. ;;; A `real' frame is one that is not tail-recursive.
  52. (define (write-state-short state)
  53. (let* ((frame (stack-ref (state-stack state) (state-index state)))
  54. (source (frame-source frame))
  55. (position (and source (source-position source))))
  56. (format #t "Frame ~A at " (frame-number frame))
  57. (if position
  58. (display-position position)
  59. (display "unknown source location"))
  60. (newline)
  61. (write-char #\tab)
  62. (write-frame-short frame)
  63. (newline)))
  64. (define (write-state-short* stack index)
  65. (write-frame-index-short stack index)
  66. (write-char #\space)
  67. (write-frame-short (stack-ref stack index))
  68. (newline))
  69. (define (write-frame-index-short stack index)
  70. (let ((s (number->string (frame-number (stack-ref stack index)))))
  71. (display s)
  72. (write-char #\:)
  73. (write-chars #\space (- 4 (string-length s)))))
  74. (define (write-frame-short frame)
  75. (if (frame-procedure? frame)
  76. (write-frame-short/application frame)
  77. (write-frame-short/expression frame)))
  78. (define (write-frame-short/application frame)
  79. (write-char #\[)
  80. (write (let ((procedure (frame-procedure frame)))
  81. (or (and (procedure? procedure)
  82. (procedure-name procedure))
  83. procedure)))
  84. (if (frame-evaluating-args? frame)
  85. (display " ...")
  86. (begin
  87. (for-each (lambda (argument)
  88. (write-char #\space)
  89. (write argument))
  90. (frame-arguments frame))
  91. (write-char #\]))))
  92. ;;; Use builtin function instead:
  93. (set! write-frame-short/application
  94. (lambda (frame)
  95. (display-application frame (current-output-port) 12)))
  96. (define (write-frame-short/expression frame)
  97. (write (let* ((source (frame-source frame))
  98. (copy (source-property source 'copy)))
  99. (if (pair? copy)
  100. copy
  101. (unmemoize-expr source)))))
  102. (define (write-state-long state)
  103. (let ((index (state-index state)))
  104. (let ((frame (stack-ref (state-stack state) index)))
  105. (write-frame-index-long frame)
  106. (write-frame-long frame))))
  107. (define (write-frame-index-long frame)
  108. (display "Stack frame: ")
  109. (write (frame-number frame))
  110. (if (frame-real? frame)
  111. (display " (real)"))
  112. (newline))
  113. (define (write-frame-long frame)
  114. (if (frame-procedure? frame)
  115. (write-frame-long/application frame)
  116. (write-frame-long/expression frame)))
  117. (define (write-frame-long/application frame)
  118. (display "This frame is an application.")
  119. (newline)
  120. (if (frame-source frame)
  121. (begin
  122. (display "The corresponding expression is:")
  123. (newline)
  124. (display-source frame)
  125. (newline)))
  126. (display "The procedure being applied is: ")
  127. (write (let ((procedure (frame-procedure frame)))
  128. (or (and (procedure? procedure)
  129. (procedure-name procedure))
  130. procedure)))
  131. (newline)
  132. (display "The procedure's arguments are")
  133. (if (frame-evaluating-args? frame)
  134. (display " being evaluated.")
  135. (begin
  136. (display ": ")
  137. (write (frame-arguments frame))))
  138. (newline))
  139. (define (display-source frame)
  140. (let* ((source (frame-source frame))
  141. (copy (source-property source 'copy)))
  142. (cond ((source-position source)
  143. => (lambda (p) (display-position p) (display ":\n"))))
  144. (display " ")
  145. (write (or copy (unmemoize-expr source)))))
  146. (define (source-position source)
  147. (let ((fname (source-property source 'filename))
  148. (line (source-property source 'line))
  149. (column (source-property source 'column)))
  150. (and fname
  151. (list fname line column))))
  152. (define (display-position pos)
  153. (format #t "~A:~D:~D" (car pos) (+ 1 (cadr pos)) (+ 1 (caddr pos))))
  154. (define (write-frame-long/expression frame)
  155. (display "This frame is an evaluation.")
  156. (newline)
  157. (display "The expression being evaluated is:")
  158. (newline)
  159. (display-source frame)
  160. (newline))
  161. (define (write-frame-args-long frame)
  162. (if (frame-procedure? frame)
  163. (let ((arguments (frame-arguments frame)))
  164. (let ((n (length arguments)))
  165. (display "This frame has ")
  166. (write n)
  167. (display " argument")
  168. (if (not (= n 1))
  169. (display "s"))
  170. (write-char (if (null? arguments) #\. #\:))
  171. (newline))
  172. (for-each (lambda (argument)
  173. (display " ")
  174. (write argument)
  175. (newline))
  176. arguments))
  177. (begin
  178. (display "This frame is an evaluation frame; it has no arguments.")
  179. (newline))))
  180. (define (write-chars char n)
  181. (do ((i 0 (+ i 1)))
  182. ((>= i n))
  183. (write-char char)))