Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

150 lines
5.6 KiB

  1. # This patch is against chicken 1.92, but it should work just fine
  2. # with older versions of chicken. It adds support for mulit-argument
  3. # generics, that is, generics now correctly handle adding methods
  4. # with different lengths of specializer lists
  5. # This patch has been committed into the CHICKEN darcs repository,
  6. # so chicken versions above 1.92 work fine.
  7. # Comments, bugs, suggestions send to [email protected]
  8. # Patch written by John Lenz <[email protected]>
  9. --- tinyclos.scm.old 2005-04-05 01:13:56.000000000 -0500
  10. +++ tinyclos.scm 2005-04-11 16:37:23.746181489 -0500
  11. @@ -37,8 +37,10 @@
  12. (include "parameters")
  13. +(cond-expand [(not chicken-compile-shared) (declare (unit tinyclos))]
  14. + [else] )
  15. +
  16. (declare
  17. - (unit tinyclos)
  18. (uses extras)
  19. (usual-integrations)
  20. (fixnum)
  21. @@ -234,7 +236,10 @@
  22. y = C_block_item(y, 1);
  23. }
  24. }
  25. - return(C_block_item(v, i + 1));
  26. + if (x == C_SCHEME_END_OF_LIST && y == C_SCHEME_END_OF_LIST)
  27. + return(C_block_item(v, i + 1));
  28. + else
  29. + goto mismatch;
  30. }
  31. else if(free_index == -1) free_index = i;
  32. mismatch:
  33. @@ -438,7 +443,7 @@
  34. (define hash-arg-list
  35. (foreign-lambda* unsigned-int ((scheme-object args) (scheme-object svector)) "
  36. C_word tag, h, x;
  37. - int n, i, j;
  38. + int n, i, j, len = 0;
  39. for(i = 0; args != C_SCHEME_END_OF_LIST; args = C_block_item(args, 1)) {
  40. x = C_block_item(args, 0);
  41. if(C_immediatep(x)) {
  42. @@ -481,8 +486,9 @@
  43. default: i += 255;
  44. }
  45. }
  46. + ++len;
  47. }
  48. - return(i & (C_METHOD_CACHE_SIZE - 1));") )
  49. + return((i + len) & (C_METHOD_CACHE_SIZE - 1));") )
  50. ;
  51. @@ -868,13 +874,27 @@
  52. (##tinyclos#slot-set!
  53. generic
  54. 'methods
  55. - (cons method
  56. - (filter-in
  57. - (lambda (m)
  58. - (let ([ms1 (method-specializers m)]
  59. - [ms2 (method-specializers method)] )
  60. - (not (every2 (lambda (x y) (eq? x y)) ms1 ms2) ) ) )
  61. - (##tinyclos#slot-ref generic 'methods))))
  62. + (let* ([ms1 (method-specializers method)]
  63. + [l1 (length ms1)] )
  64. + (let filter-in-method ([methods (##tinyclos#slot-ref generic 'methods)])
  65. + (if (null? methods)
  66. + (list method)
  67. + (let* ([mm (##sys#slot methods 0)]
  68. + [ms2 (method-specializers mm)]
  69. + [l2 (length ms2)])
  70. + (cond ((> l1 l2)
  71. + (cons mm (filter-in-method (##sys#slot methods 1))))
  72. + ((< l1 l2)
  73. + (cons method methods))
  74. + (else
  75. + (let check-method ([ms1 ms1]
  76. + [ms2 ms2])
  77. + (cond ((and (null? ms1) (null? ms2))
  78. + (cons method (##sys#slot methods 1))) ;; skip the method already in the generic
  79. + ((eq? (##sys#slot ms1 0) (##sys#slot ms2 0))
  80. + (check-method (##sys#slot ms1 1) (##sys#slot ms2 1)))
  81. + (else
  82. + (cons mm (filter-in-method (##sys#slot methods 1)))))))))))))
  83. (if (memq generic generic-invocation-generics)
  84. (set! method-cache-tag (vector))
  85. (%entity-cache-set! generic #f) )
  86. @@ -925,11 +945,13 @@
  87. (memq (car args) generic-invocation-generics))
  88. (let ([proc
  89. (method-procedure
  90. + ; select the first method of one argument
  91. (let lp ([lis (generic-methods generic)])
  92. - (let ([tail (##sys#slot lis 1)])
  93. - (if (null? tail)
  94. - (##sys#slot lis 0)
  95. - (lp tail)) ) ) ) ] )
  96. + (if (null? lis)
  97. + (##sys#error "Unable to find original compute-apply-generic")
  98. + (if (= (length (method-specializers (##sys#slot lis 0))) 1)
  99. + (##sys#slot lis 0)
  100. + (lp (##sys#slot lis 1)))))) ] )
  101. (lambda (args) (apply proc #f args)) )
  102. (let ([x (compute-apply-methods generic)]
  103. [y ((compute-methods generic) args)] )
  104. @@ -946,9 +968,13 @@
  105. (lambda (args)
  106. (let ([applicable
  107. (filter-in (lambda (method)
  108. - (every2 applicable?
  109. - (method-specializers method)
  110. - args))
  111. + (let check-applicable ([list1 (method-specializers method)]
  112. + [list2 args])
  113. + (cond ((null? list1) #t)
  114. + ((null? list2) #f)
  115. + (else
  116. + (and (applicable? (##sys#slot list1 0) (##sys#slot list2 0))
  117. + (check-applicable (##sys#slot list1 1) (##sys#slot list2 1)))))))
  118. (generic-methods generic) ) ] )
  119. (if (or (null? applicable) (null? (##sys#slot applicable 1)))
  120. applicable
  121. @@ -975,8 +1001,10 @@
  122. [else
  123. (cond ((and (null? specls1) (null? specls2))
  124. (##sys#error "two methods are equally specific" generic))
  125. - ((or (null? specls1) (null? specls2))
  126. - (##sys#error "two methods have different number of specializers" generic))
  127. + ;((or (null? specls1) (null? specls2))
  128. + ; (##sys#error "two methods have different number of specializers" generic))
  129. + ((null? specls1) #f)
  130. + ((null? specls2) #t)
  131. ((null? args)
  132. (##sys#error "fewer arguments than specializers" generic))
  133. (else
  134. @@ -1210,7 +1238,7 @@
  135. (define <structure> (make-primitive-class "structure"))
  136. (define <procedure> (make-primitive-class "procedure" <procedure-class>))
  137. (define <end-of-file> (make-primitive-class "end-of-file"))
  138. -(define <environment> (make-primitive-class "environment" <structure>)) ; (Benedikt insisted on this)
  139. +(define <environment> (make-primitive-class "environment" <structure>))
  140. (define <hash-table> (make-primitive-class "hash-table" <structure>))
  141. (define <promise> (make-primitive-class "promise" <structure>))
  142. (define <queue> (make-primitive-class "queue" <structure>))