display.scm 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. ; Copyright (c) 1993-2008 by Richard Kelsey. See file COPYING.
  2. ; Data must be done last as it may contain references to the other stuff.
  3. (define (display-forms-as-scheme forms out)
  4. (receive (data other)
  5. (partition-list (lambda (f)
  6. (and (node? (form-value f))
  7. (literal-node? (form-value f))))
  8. forms)
  9. (for-each (lambda (f)
  10. (display-form-as-scheme f (schemify (form-value f)) out))
  11. other)
  12. (for-each (lambda (f)
  13. (display-data-form-as-scheme f out))
  14. data)))
  15. (define form-value (structure-ref forms form-value))
  16. (define form-var (structure-ref forms form-var))
  17. (define literal-node? (node-predicate 'literal #f))
  18. (define (display-form-as-scheme f value out)
  19. (cond ((unspecific? value)
  20. (p `(define ,(get-form-name f)) out)
  21. (newline out))
  22. ((or (external-value? value)
  23. (memq 'closed-compiled-primitive (variable-flags (form-var f))))
  24. (values))
  25. (else
  26. (p `(define ,(get-form-name f) ,value)
  27. out)
  28. (newline out))))
  29. (define (display-data-form-as-scheme f out)
  30. (let* ((value (clean-literal (node-form (form-value f))))
  31. (value (if (and (quoted? value)
  32. (not (or (list? (cadr value))
  33. (vector? (cadr value)))))
  34. (cadr value)
  35. value)))
  36. (display-form-as-scheme f value out)))
  37. (define (get-form-name form)
  38. (name->symbol (get-variable-name (form-var form))))
  39. (define (schemify node)
  40. (if (node? node)
  41. ((operator-table-ref schemifiers (node-operator-id node))
  42. node)
  43. (schemify-sexp node)))
  44. (define unspecific?
  45. (let ((x (if #f #t)))
  46. (lambda (y)
  47. (eq? x y))))
  48. (define schemifiers
  49. (make-operator-table (lambda (node)
  50. (let ((form (node-form node)))
  51. (if (list? form)
  52. (map schemify form)
  53. form)))))
  54. (define (define-schemifier name type proc)
  55. (operator-define! schemifiers name type proc))
  56. (define-schemifier 'name 'leaf
  57. (lambda (node)
  58. (cond ((node-ref node 'binding)
  59. => (lambda (binding)
  60. (let ((var (binding-place binding)))
  61. (if (variable? var)
  62. (get-variable-name var)
  63. (desyntaxify (node-form node))))))
  64. (else
  65. (name->symbol (node-form node))))))
  66. ; Rename things that have differ in Scheme and Pre-Scheme
  67. (define aliases
  68. (map (lambda (s)
  69. (cons s (string->symbol (string-append "ps-" (symbol->string s)))))
  70. '(read-char peek-char write-char newline
  71. open-input-file open-output-file
  72. close-input-port close-output-port)))
  73. (define (get-variable-name var)
  74. (cond ((and (generated-top-variable? var)
  75. (not (memq 'closed-compiled-primitive (variable-flags var))))
  76. (string->symbol (string-append (symbol->string
  77. (name->symbol (variable-name var)))
  78. "."
  79. (number->string (variable-id var)))))
  80. ((assq (variable-name var) aliases)
  81. => cdr)
  82. (else
  83. (variable-name var))))
  84. (define (name->symbol name)
  85. (if (symbol? name)
  86. name
  87. (string->symbol (string-append (symbol->string
  88. (name->symbol (generated-name name)))
  89. "."
  90. (number->string (generated-uid name))))))
  91. (define-schemifier 'quote #f
  92. (lambda (node)
  93. (list 'quote (cadr (node-form node)))))
  94. (define-schemifier 'literal #f
  95. (lambda (node)
  96. (let ((form (node-form node)))
  97. (cond ((primop? form)
  98. (primop-id form))
  99. ((external-value? form)
  100. (let ((string (external-value-string form)))
  101. (if (string=? string "(long(*)())")
  102. 'integer->procedure
  103. (string->symbol (external-value-string form)))))
  104. ((external-constant? form)
  105. `(enum ,(external-constant-enum-name form)
  106. ,(external-constant-name form)))
  107. (else
  108. (schemify-sexp form))))))
  109. (define-schemifier 'unspecific #f
  110. (lambda (node)
  111. ''unspecific))
  112. ; Used for primitives in non-call position. The CDR of the form is a
  113. ; variable that will be bound to the primitive's closed-compiled value.
  114. (define-schemifier 'primitive #f
  115. (lambda (node)
  116. (let ((form (node-form node)))
  117. (cond ((pair? form)
  118. (get-variable-name (cdr form))) ; non-call position
  119. ((assq (primitive-id form) aliases)
  120. => cdr)
  121. (else
  122. (primitive-id form))))))
  123. ; lambda, let-syntax, letrec-syntax...
  124. (define-schemifier 'letrec #f
  125. (lambda (node)
  126. (let ((form (node-form node)))
  127. `(letrec ,(map (lambda (spec)
  128. `(,(schemify (car spec)) ,(schemify (cadr spec))))
  129. (cadr form))
  130. ,@(map (lambda (f) (schemify f))
  131. (cddr form))))))
  132. (define-schemifier 'lambda #f
  133. (lambda (node)
  134. (let ((form (node-form node)))
  135. `(lambda ,(let label ((vars (cadr form)))
  136. (cond ((pair? vars)
  137. (cons (schemify (car vars))
  138. (label (cdr vars))))
  139. ((null? vars)
  140. '())
  141. (else
  142. (schemify vars))))
  143. ,@(map schemify (cddr form))))))
  144. (define-schemifier 'goto #f
  145. (lambda (node)
  146. (map schemify (cdr (node-form node)))))
  147. (define (schemify-sexp thing)
  148. (cond ((name? thing)
  149. (desyntaxify thing))
  150. ((primop? thing)
  151. (primop-id thing))
  152. ((primitive? thing)
  153. (primitive-id thing))
  154. ((variable? thing)
  155. (get-variable-name thing))
  156. ((pair? thing)
  157. (let ((x (schemify-sexp (car thing)))
  158. (y (schemify-sexp (cdr thing))))
  159. (if (and (eq? x (car thing))
  160. (eq? y (cdr thing)))
  161. thing ;+++
  162. (cons x y))))
  163. ((vector? thing)
  164. (let ((new (make-vector (vector-length thing) #f)))
  165. (let loop ((i 0) (same? #t))
  166. (if (>= i (vector-length thing))
  167. (if same? thing new) ;+++
  168. (let ((x (schemify-sexp (vector-ref thing i))))
  169. (vector-set! new i x)
  170. (loop (+ i 1)
  171. (and same? (eq? x (vector-ref thing i)))))))))
  172. (else thing)))
  173. (define (clean-literal thing)
  174. (cond ((name? thing)
  175. (desyntaxify thing))
  176. ((variable? thing)
  177. (get-variable-name thing))
  178. ((external-constant? thing)
  179. `(enum ,(external-constant-enum-name thing)
  180. ,(external-constant-name thing)))
  181. ((pair? thing)
  182. (let ((x (clean-literal (car thing)))
  183. (y (clean-literal (cdr thing))))
  184. (if (and (quoted? x) (quoted? y))
  185. `(quote (,(cadr x) . ,(cadr y)))
  186. `(cons ,x ,y))))
  187. ((vector? thing)
  188. (let ((elts (map clean-literal (vector->list thing))))
  189. (if (every? quoted? elts)
  190. `(quote ,(list->vector (map cadr elts)))
  191. `(vector . ,elts))))
  192. (else
  193. `(quote ,thing))))
  194. (define (quoted? x)
  195. (and (pair? x)
  196. (eq? (car x) 'quote)))