display.scm 6.2 KB

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