ps-vector.scm 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. ;;; ps-vector: vector utilities for Pre-Scheme
  2. ;;;
  3. ;;; These routines are based on SRFI-43 for Scheme, with some
  4. ;;; adjustments to account for the limitations of Pre-Scheme.
  5. ;;;
  6. ;;; Pre-Scheme's native vectors don't support vector-length at runtime,
  7. ;;; so we take an additional length argument, as is common practice in C.
  8. ;;;
  9. ;;; Pre-Scheme doesn't support variadic functions, so we have a variant
  10. ;;; for each arity, as you might do in C. It should be possible to
  11. ;;; generate these with a macro, but that's not yet implemented.
  12. ;;; vector-unfold
  13. (define-syntax vector-unfold
  14. (syntax-rules ()
  15. ((_ proc len)
  16. (vector-unfold0 proc len))
  17. ((_ proc len seed)
  18. (vector-unfold1 proc len seed))
  19. ((_ proc len seed1 seed2)
  20. (vector-unfold2 proc len seed1 seed2))
  21. ((_ proc len seed1 seed2 seed3)
  22. (vector-unfold3 proc len seed1 seed2 seed3))))
  23. (define (vector-unfold0 proc len)
  24. ;; FIXME get proc's return type without calling it
  25. (let ((result (make-vector len (proc 0))))
  26. (let loop ((i 0))
  27. (if (= i len)
  28. result
  29. (begin
  30. (vector-set! result i (proc i))
  31. (loop (+ i 1)))))))
  32. (define (vector-unfold1 proc len seed)
  33. (let ((result (receive (val next)
  34. (proc 0 seed)
  35. (make-vector len val))))
  36. (let loop ((i 0) (seed seed))
  37. (if (= i len)
  38. result
  39. (receive (val next)
  40. (proc i seed)
  41. (vector-set! result i val)
  42. (loop (+ i 1) next))))))
  43. (define (vector-unfold2 proc len seed1 seed2)
  44. (let ((result (receive (val next1 next2)
  45. (proc 0 seed1 seed2)
  46. (make-vector len val))))
  47. (let loop ((i 0) (seed1 seed1) (seed2 seed2))
  48. (if (= i len)
  49. result
  50. (receive (val next1 next2)
  51. (proc i seed1 seed2)
  52. (vector-set! result i val)
  53. (loop (+ i 1) next1 next2))))))
  54. (define (vector-unfold3 proc len seed1 seed2 seed3)
  55. (let ((result (receive (val next1 next2 next3)
  56. (proc 0 seed1 seed2 seed3)
  57. (make-vector len val))))
  58. (let loop ((i 0) (seed1 seed1) (seed2 seed2) (seed3 seed3))
  59. (if (= i len)
  60. result
  61. (receive (val next1 next2 next3)
  62. (proc i seed1 seed2 seed3)
  63. (vector-set! result i val)
  64. (loop (+ i 1) next1 next2 next3))))))
  65. ;;; vector-fold
  66. (define-syntax vector-fold
  67. (syntax-rules ()
  68. ((_ proc init vec len)
  69. (vector-fold1 proc init vec len))
  70. ((_ proc init vec1 len1 vec2 len2)
  71. (vector-fold2 proc init vec1 len1 vec2 len2))
  72. ((_ proc init vec1 len1 vec2 len2 vec3 len3)
  73. (vector-fold3 proc init vec1 len1 vec2 len2 vec3 len3))))
  74. (define (vector-fold1 proc init vec len)
  75. (let loop ((i 0) (result init))
  76. (if (= i len)
  77. result
  78. (loop (+ i 1) (proc i result (vector-ref vec i))))))
  79. (define (vector-fold2 proc init vec1 len1 vec2 len2)
  80. (let ((len (min len1 len2)))
  81. (let loop ((i 0) (result init))
  82. (if (= i len)
  83. result
  84. (loop (+ i 1) (proc i result
  85. (vector-ref vec1 i)
  86. (vector-ref vec2 i)))))))
  87. (define (vector-fold3 proc init vec1 len1 vec2 len2 vec3 len3)
  88. (let ((len (min len1 len2 len3)))
  89. (let loop ((i 0) (result init))
  90. (if (= i len)
  91. result
  92. (loop (+ i 1) (proc i result
  93. (vector-ref vec1 i)
  94. (vector-ref vec2 i)
  95. (vector-ref vec3 i)))))))
  96. ;;; vector-map!
  97. (define-syntax vector-map!
  98. (syntax-rules ()
  99. ((_ proc vec len)
  100. (vector-map1! proc vec len))
  101. ((_ proc vec1 len1 vec2 len2)
  102. (vector-map2! proc vec1 len1 vec2 len2))
  103. ((_ proc vec1 len1 vec2 len2 vec3 len3)
  104. (vector-map3! proc vec1 len1 vec2 len2 vec3 len3))))
  105. (define (vector-map1! proc vec len)
  106. (vector-fold (lambda (i vec val)
  107. (vector-set! vec i (proc i val))
  108. vec)
  109. vec vec len))
  110. (define (vector-map2! proc vec1 len1 vec2 len2)
  111. (vector-fold (lambda (i vec val1 val2)
  112. (vector-set! vec i (proc i val1 val2))
  113. vec)
  114. vec1 vec1 len1 vec2 len2))
  115. (define (vector-map3! proc vec1 len1 vec2 len2 vec3 len3)
  116. (vector-fold (lambda (i vec val1 val2 val3)
  117. (vector-set! vec i (proc i val1 val2 val3))
  118. vec)
  119. vec1 vec1 len1 vec2 len2 vec3 len3))
  120. ;;; vector-map1
  121. (define-syntax vector-map
  122. (syntax-rules ()
  123. ((_ proc vec len)
  124. (vector-map1 proc vec len))
  125. ((_ proc vec1 len1 vec2 len2)
  126. (vector-map2 proc vec1 len1 vec2 len2))
  127. ((_ proc vec1 len1 vec2 len2 vec3 len3)
  128. (vector-map3 proc vec1 len1 vec2 len2 vec3 len3))))
  129. (define (vector-map1 proc vec len)
  130. ;; FIXME get proc's return type without calling it
  131. (let ((res (make-vector len (proc 0 (vector-ref vec 0)))))
  132. (vector-fold (lambda (i res val)
  133. (vector-set! res i (proc i val))
  134. res)
  135. res vec len)))
  136. (define (vector-map2 proc vec1 len1 vec2 len2)
  137. (let* ((len (min len1 len2))
  138. (res (make-vector len (proc 0
  139. (vector-ref vec1 0)
  140. (vector-ref vec2 0)))))
  141. (vector-fold (lambda (i res val1 val2)
  142. (vector-set! res i (proc i val1 val2))
  143. res)
  144. res vec1 len1 vec2 len2)))
  145. (define (vector-map3 proc vec1 len1 vec2 len2 vec3 len3)
  146. (let* ((len (min len1 len2 len3))
  147. (res (make-vector len (proc 0
  148. (vector-ref vec1 0)
  149. (vector-ref vec2 0)
  150. (vector-ref vec3 0)))))
  151. (vector-fold (lambda (i res val1 val2 val3)
  152. (vector-set! res i (proc i val1 val2 val3))
  153. res)
  154. res vec1 len1 vec2 len2 vec3 len3)))
  155. ;;; vector-for-each
  156. (define-syntax vector-for-each
  157. (syntax-rules ()
  158. ((_ proc vec len)
  159. (vector-for-each1 proc vec len))
  160. ((_ proc vec1 len1 vec2 len2)
  161. (vector-for-each2 proc vec1 len1 vec2 len2))
  162. ((_ proc vec1 len1 vec2 len2 vec3 len3)
  163. (vector-for-each3 proc vec1 len1 vec2 len2 vec3 len3))))
  164. (define (vector-for-each1 proc vec len)
  165. (vector-fold (lambda (i res val)
  166. (proc i val)
  167. res)
  168. (unspecific) vec len))
  169. (define (vector-for-each2 proc vec1 len1 vec2 len2)
  170. (vector-fold (lambda (i res val1 val2)
  171. (proc i val1 val2)
  172. res)
  173. (unspecific) vec1 len1 vec2 len2))
  174. (define (vector-for-each3 proc vec1 len1 vec2 len2 vec3 len3)
  175. (vector-fold (lambda (i res val1 val2 val3)
  176. (proc i val1 val2 val3)
  177. res)
  178. (unspecific) vec1 len1 vec2 len2 vec3 len3))