schemify.scm 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Richard Kelsey, Jonathan Rees, Martin Gasbichler, Mike Sperber
  3. ; schemify
  4. ; This is only used for producing error and warning messages.
  5. ; Flush nodes and generated names in favor of something a little more
  6. ; readable. Eventually, (schemify node env) ought to produce an
  7. ; s-expression that has the same semantics as node, when node is fully
  8. ; expanded.
  9. (define (schemify node . maybe-env)
  10. (if (node? node)
  11. (schemify-node node
  12. (if (null? maybe-env)
  13. #f
  14. (car maybe-env)))
  15. (schemify-sexp node)))
  16. (define schemifiers
  17. (make-operator-table (lambda (node env)
  18. (let ((form (node-form node)))
  19. (if (list? form)
  20. (let ((op (car form)))
  21. (cons (cond ((operator? op)
  22. (operator-name op))
  23. ((node? op)
  24. (schemify-node op env))
  25. (else
  26. (schemify-sexp op)))
  27. (schemify-nodes (cdr form) env)))
  28. form)))))
  29. ; We cache the no-env version because that's the one used to generate the
  30. ; sources in the debugging info (which takes up a lot of space).
  31. (define (schemify-node node env)
  32. (or (and (not env)
  33. (node-ref node 'schemify))
  34. (let ((form ((operator-table-ref schemifiers (node-operator-id node))
  35. node
  36. env)))
  37. (if (not env)
  38. (node-set! node 'schemify form))
  39. form)))
  40. (define (schemify-nodes nodes env)
  41. (map (lambda (node)
  42. (schemify-node node env))
  43. nodes))
  44. (define (define-schemifier name type proc)
  45. (operator-define! schemifiers name type proc))
  46. (define-schemifier 'name 'leaf
  47. (lambda (node env)
  48. (if env
  49. (name->qualified (node-form node)
  50. env)
  51. (let ((form (node-form node)))
  52. (if (or #f (node? form))
  53. (schemify-node form env)
  54. (desyntaxify form))))))
  55. ; Convert an alias (generated name) to S-expression form ("qualified name").
  56. (define (name->qualified name env)
  57. (cond ((not (generated? name))
  58. name)
  59. ((let ((d0 (lookup env name))
  60. (d1 (lookup env (generated-name name))))
  61. (and d0 d1 (same-denotation? d0 d1)))
  62. (generated-name name)) ;+++
  63. (else
  64. (make-qualified (qualify-parent (generated-parent-name name)
  65. env)
  66. (generated-name name)
  67. (generated-uid name)))))
  68. ; As an optimization, we elide intermediate steps in the lookup path
  69. ; when possible. E.g.
  70. ; #(>> #(>> #(>> define-record-type define-accessors)
  71. ; define-accessor)
  72. ; record-ref)
  73. ; is replaced with
  74. ; #(>> define-record-type record-ref)
  75. (define (qualify-parent name env)
  76. (let recur ((name name) (env env))
  77. (if (generated? name)
  78. (let ((parent (generated-parent-name name)))
  79. (if (and (environment-stable? env)
  80. (let ((b1 (generic-lookup env name))
  81. (b2 (generic-lookup env parent)))
  82. (and b1
  83. b2
  84. (or (same-denotation? b1 b2)
  85. (and (binding? b1)
  86. (binding? b2)
  87. (let ((s1 (binding-static b1))
  88. (s2 (binding-static b2)))
  89. (and (transform? s1)
  90. (transform? s2)
  91. (eq? (transform-env s1)
  92. (transform-env s2)))))))))
  93. (recur parent env) ;+++
  94. (make-qualified (recur parent (generated-env name))
  95. (generated-name name)
  96. (generated-uid name))))
  97. name)))
  98. (define-schemifier 'quote syntax-type
  99. (lambda (node env)
  100. (let ((form (node-form node)))
  101. `(quote ,(cadr form)))))
  102. (define-schemifier 'call 'internal
  103. (lambda (node env)
  104. (map (lambda (node)
  105. (schemify-node node env))
  106. (node-form node))))
  107. ; We ignore the list of free variables in flat lambdas.
  108. (define (schemify-lambda node env)
  109. (let ((form (node-form node)))
  110. `(lambda ,(schemify-formals (cadr form) env)
  111. ,(schemify-node (last form) env))))
  112. (define-schemifier 'lambda syntax-type schemify-lambda)
  113. (define-schemifier 'flat-lambda syntax-type schemify-lambda)
  114. (define (schemify-formals formals env)
  115. (cond ((node? formals)
  116. (schemify-node formals env))
  117. ((pair? formals)
  118. (cons (schemify-node (car formals) env)
  119. (schemify-formals (cdr formals) env)))
  120. (else
  121. (schemify-sexp formals)))) ; anything besides '() ?
  122. ; let-syntax, letrec-syntax...
  123. (define-schemifier 'letrec syntax-type
  124. (lambda (node env)
  125. (let ((form (node-form node)))
  126. (schemify-letrec 'letrec (cadr form) (caddr form) env))))
  127. (define-schemifier 'letrec* syntax-type
  128. (lambda (node env)
  129. (let ((form (node-form node)))
  130. (schemify-letrec 'letrec* (cadr form) (caddr form) env))))
  131. (define-schemifier 'pure-letrec syntax-type
  132. (lambda (node env)
  133. (let ((form (node-form node)))
  134. (schemify-letrec 'letrec (cadr form) (cadddr form) env))))
  135. (define (schemify-letrec op specs body env)
  136. `(,op ,(map (lambda (spec)
  137. (schemify-nodes spec env))
  138. specs)
  139. ,(schemify-node body env)))
  140. (define-schemifier 'loophole syntax-type
  141. (lambda (node env)
  142. (let ((form (node-form node)))
  143. (list 'loophole
  144. (type->sexp (cadr form) #t)
  145. (schemify-node (caddr form) env)))))
  146. (define-schemifier 'lap syntax-type
  147. (lambda (node env)
  148. (let ((form (node-form node)))
  149. `(lap
  150. ,(cadr form)
  151. ,(schemify-nodes (caddr form) env)
  152. . ,(cdddr form)))))
  153. ;----------------
  154. (define (schemify-sexp thing)
  155. (cond ((name? thing)
  156. (desyntaxify thing))
  157. ((pair? thing)
  158. (let ((x (schemify-sexp (car thing)))
  159. (y (schemify-sexp (cdr thing))))
  160. (if (and (eq? x (car thing))
  161. (eq? y (cdr thing)))
  162. thing ;+++
  163. (cons x y))))
  164. ((vector? thing)
  165. (let ((new (make-vector (vector-length thing) #f)))
  166. (let loop ((i 0) (same? #t))
  167. (if (>= i (vector-length thing))
  168. (if same? thing new) ;+++
  169. (let ((x (schemify-sexp (vector-ref thing i))))
  170. (vector-set! new i x)
  171. (loop (+ i 1)
  172. (and same? (eq? x (vector-ref thing i)))))))))
  173. (else thing)))