weak.scm 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. #| -*-Scheme-*-
  2. Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
  3. 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
  4. 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Massachusetts
  5. Institute of Technology
  6. This file is part of MIT/GNU Scheme.
  7. MIT/GNU Scheme is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or (at
  10. your option) any later version.
  11. MIT/GNU Scheme is distributed in the hope that it will be useful, but
  12. WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. General Public License for more details.
  15. You should have received a copy of the GNU General Public License
  16. along with MIT/GNU Scheme; if not, write to the Free Software
  17. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,
  18. USA.
  19. |#
  20. ;;;; Weak list utilities
  21. (declare (usual-integrations))
  22. ;;; FBE
  23. ;; We use fake weak pairs because we do not have a generaic weak
  24. ;; hashtable constructor.
  25. ;;; Fake weak pairs.
  26. (define weak-pair? pair?)
  27. (define weak-cons cons)
  28. (define weak-car car)
  29. (define weak-cdr cdr)
  30. (define weak-pair/car? pair?)
  31. (define (list->weak-list l) l)
  32. (define weak-set-cdr! set-cdr!)
  33. ;;; Use Chez Scheme weak pairs
  34. ;; ;;(define weak-pair? pair?)
  35. ;; ;;(define weak-cons cons)
  36. ;; (define weak-car car)
  37. ;; (define weak-cdr cdr)
  38. ;; (define (weak-pair/car? p)
  39. ;; (bwp-object? (car p)))
  40. ;; ;; from MIT-Scheme
  41. ;; (define (list->weak-list items)
  42. ;; (let loop ((items* (reverse items)) (result '()))
  43. ;; (if (pair? items*)
  44. ;; (loop (cdr items*)
  45. ;; (weak-cons (car items*) result))
  46. ;; (begin
  47. ;; (if (not (null? items*))
  48. ;; (error ":not-list" items 'LIST->WEAK-LIST))
  49. ;; result))))
  50. ;; (define weak-set-cdr! set-cdr!)
  51. ;;; FBE end
  52. (define (get-weak-member obj weak-list)
  53. (if (null? weak-list)
  54. #f
  55. (let ((a (weak-car weak-list)))
  56. (if (equal? obj a)
  57. a
  58. (get-weak-member obj (weak-cdr weak-list))))))
  59. (define (weak-find obj weak-alist)
  60. (if (null? weak-alist)
  61. #f
  62. (let ((pair (car weak-alist)))
  63. (if pair
  64. (let ((a (weak-car pair)))
  65. (if a
  66. (if (equal? obj a)
  67. a
  68. (weak-find obj (cdr weak-alist)))
  69. (begin (set-car! weak-alist #f)
  70. #f)))
  71. (weak-find obj (cdr weak-alist))))))
  72. (define (weak-length weak-list)
  73. (if (weak-pair? weak-list)
  74. (fix:+ (weak-length (weak-cdr weak-list)) 1)
  75. 0))
  76. ;;; Weak-alist searches. These scan a weak alist for an object,
  77. ;;; returning the associated value if found. They also clean up the
  78. ;;; alist by clobbering out value cells that have lost their key.
  79. ;;; These also work for strong alists, but strong alists are not
  80. ;;; modified.
  81. (define (weak-finder same?)
  82. (define (the-finder obj weak-alist)
  83. (if (null? weak-alist)
  84. #f
  85. (let ((pair (car weak-alist)))
  86. (cond ((weak-pair? pair)
  87. (let ((a (weak-car pair)))
  88. (if a ; assumes no key is #f
  89. (if (same? obj a)
  90. (weak-cdr pair)
  91. (the-finder obj (cdr weak-alist)))
  92. (begin (set-car! weak-alist #f)
  93. #f))))
  94. ((pair? pair)
  95. (let ((a (car pair)))
  96. (if (same? obj a)
  97. (cdr pair)
  98. (the-finder obj (cdr weak-alist)))))
  99. (else
  100. (the-finder obj (cdr weak-alist)))))))
  101. the-finder)
  102. (define weak-find-equal? (weak-finder equal?))
  103. (define weak-find-eqv? (weak-finder eqv?))
  104. (define weak-find-eq? (weak-finder eq?))
  105. ;;; The following clips out dead linkages that have been clobbered by
  106. ;;; a weak finder (above). It also limits the size of the alist to
  107. ;;; the maximum size specified, by chopping off the tail. max-size
  108. ;;; must be a positive integer larger than 1.
  109. (define (purge-list list max-size)
  110. (let ((ans (delq! #f list)))
  111. (let loop ((ans ans) (i 1))
  112. (if (pair? ans)
  113. (if (fix:= i max-size)
  114. (set-cdr! ans '())
  115. (loop (cdr ans) (fix:+ i 1)))))
  116. ans))
  117. ;;; Weak list cleanups
  118. (define (clean-weak-list weak-list)
  119. (let clean-head ((this weak-list))
  120. (if (weak-pair? this)
  121. (let ((next (weak-cdr this)))
  122. (if (weak-pair/car? this)
  123. (begin
  124. (let clean-tail ((this next) (prev this))
  125. (if (weak-pair? this)
  126. (let ((next (weak-cdr this)))
  127. (if (weak-pair/car? this)
  128. (clean-tail next this)
  129. (begin
  130. (weak-set-cdr! prev next)
  131. (clean-tail next prev))))))
  132. this)
  133. (clean-head next)))
  134. this)))
  135. (define (clean-weak-alist weak-alist)
  136. (clean-alist weak-alist
  137. (lambda (p)
  138. (if (not (weak-pair? p))
  139. (error ":bad-range-argument" weak-alist #f))
  140. (weak-pair/car? p))))
  141. (define (clean-subtable-alist alist)
  142. (clean-alist alist
  143. (lambda (p)
  144. (if (not (pair? p))
  145. (error ":bad-range-argument" alist #f))
  146. (clean-expression-table (cdr p)))))
  147. ;;; FBE: from general/canonicalizer.scm which is not loaded??
  148. (define (clean-expression-table table)
  149. (set-car! table (clean-weak-list (car table)))
  150. (set-car! (cdr table) (clean-weak-alist (cadr table)))
  151. (set-cdr! (cdr table) (clean-subtable-alist (cddr table)))
  152. (or (not (null? (car table)))
  153. (not (null? (cadr table)))
  154. (not (null? (cddr table)))))
  155. ;;; FBE end
  156. (define (clean-alist alist clean-association)
  157. (let clean-head ((this alist))
  158. (if (pair? this)
  159. (let ((next (cdr this)))
  160. (if (clean-association (car this))
  161. (begin
  162. (let clean-tail ((this next) (prev this))
  163. (if (pair? this)
  164. (let ((next (cdr this)))
  165. (if (clean-association (car this))
  166. (clean-tail next this)
  167. (begin
  168. (set-cdr! prev next)
  169. (clean-tail next prev))))))
  170. this)
  171. (clean-head next)))
  172. this)))