display.scm 8.2 KB

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