sort.scm 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Richard Kelsey, Jonathan Rees, Mike Sperber
  3. ; Topological sort on forms.
  4. ; Puts top-level forms in the following order:
  5. ;
  6. ; (DEFINE X <literal>)
  7. ; (DEFINE Z (LAMBDA ...))
  8. ; ...everything else...
  9. ;
  10. ; Every (DEFINE W ...) for which W is never SET! is followed by all forms
  11. ; (DEFINE V W).
  12. ;
  13. ; The procedure definitions are topologically sorted; whenever possible no
  14. ; use of a variable occurs before its definition.
  15. ;
  16. ; This uses the FREE-VARIABLES field set by usage.scm.
  17. (define (sort-forms nodes)
  18. (let ((table (make-name-table))
  19. (procs '())
  20. (literals '())
  21. (aliases '())
  22. (rest '()))
  23. (for-each (lambda (node)
  24. (let ((form (make-form node)))
  25. (if (define-node? node)
  26. (let ((name (node-form (cadr (node-form node))))
  27. (value (caddr (node-form node))))
  28. (table-set! table name form)
  29. (cond ((lambda-node? value)
  30. (set! procs (cons form procs)))
  31. ((name-node? value)
  32. (set! aliases (cons form aliases))
  33. (set! rest (cons form rest)))
  34. ((or (quote-node? value)
  35. (literal-node? value))
  36. (set! literals (cons form literals)))
  37. (else
  38. (set! rest (cons form rest)))))
  39. (set! rest (cons form rest)))))
  40. (reverse nodes))
  41. (for-each (lambda (form)
  42. (maybe-make-aliased form table))
  43. aliases)
  44. (insert-aliases
  45. (append literals
  46. (topologically-sort procs table)
  47. (filter form-unaliased? rest)))))
  48. (define (stuff-count s)
  49. (apply + (map (lambda (s) (length (cdr s))) s)))
  50. ; For (DEFINE A B) add the form to the list of B's aliases if B is defined
  51. ; in the current package and never SET!.
  52. (define (maybe-make-aliased form table)
  53. (let* ((value (caddr (node-form (form-node form))))
  54. (maker (table-ref table (node-form value))))
  55. (if (and (node-ref value 'binding)
  56. maker
  57. (= 0 (usage-assignment-count
  58. (node-ref (cadr (node-form (form-node maker))) 'usage))))
  59. (begin
  60. (set-form-aliases! maker (cons form (form-aliases maker)))
  61. (set-form-unaliased?! form #f)))))
  62. (define (topologically-sort forms table)
  63. (apply append
  64. (strongly-connected-components
  65. forms
  66. (lambda (form)
  67. (filter (lambda (f)
  68. (and f
  69. (lambda-node? (caddr (node-form (form-node f))))))
  70. (map (lambda (name)
  71. (table-ref table (node-form name)))
  72. (form-free form))))
  73. form-temp
  74. set-form-temp!)))
  75. (define-record-type form :form
  76. (really-make-form node free aliases unaliased?)
  77. form?
  78. (node form-node)
  79. (aliases form-aliases set-form-aliases!)
  80. (unaliased? form-unaliased? set-form-unaliased?!)
  81. (free form-free set-form-free!)
  82. (temp form-temp set-form-temp!))
  83. (define-record-discloser :form
  84. (lambda (form)
  85. (list 'form
  86. (let ((node (form-node form)))
  87. (if (define-node? node)
  88. (node-form (cadr (node-form node)))
  89. node)))))
  90. (define (make-form node)
  91. (really-make-form node
  92. (map usage-name-node
  93. (node-ref node 'free-variables))
  94. '() ; aliases
  95. #t)) ; unaliased?
  96. ; (DEFINE A ...) is followed by all forms (DEFINE X A).
  97. (define (insert-aliases forms)
  98. (let loop ((forms forms) (done '()))
  99. (if (null? forms)
  100. (reverse done)
  101. (let ((form (car forms)))
  102. (loop (append (form-aliases form) (cdr forms))
  103. (cons (form-node form) done))))))