vectors.scm 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. ;;; Vectors
  2. ;;; Copyright (C) 2024 Igalia, S.L.
  3. ;;;
  4. ;;; Licensed under the Apache License, Version 2.0 (the "License");
  5. ;;; you may not use this file except in compliance with the License.
  6. ;;; You may obtain a copy of the License at
  7. ;;;
  8. ;;; http://www.apache.org/licenses/LICENSE-2.0
  9. ;;;
  10. ;;; Unless required by applicable law or agreed to in writing, software
  11. ;;; distributed under the License is distributed on an "AS IS" BASIS,
  12. ;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. ;;; See the License for the specific language governing permissions and
  14. ;;; limitations under the License.
  15. ;;; Commentary:
  16. ;;;
  17. ;;; Vectors.
  18. ;;;
  19. ;;; Code:
  20. (library (hoot vectors)
  21. (export vector
  22. make-vector
  23. vector?
  24. vector-length
  25. vector-ref
  26. vector-set!
  27. vector-copy
  28. vector-copy!
  29. vector-fill!
  30. vector->list
  31. list->vector
  32. vector-concatenate
  33. vector-append
  34. vector-for-each
  35. vector-map)
  36. (import (hoot primitives)
  37. (hoot pairs)
  38. (hoot numbers)
  39. (hoot lists)
  40. (hoot errors)
  41. (hoot match))
  42. (define (%generic-vector . args) (list->vector args))
  43. (define-syntax vector
  44. (lambda (stx)
  45. (syntax-case stx ()
  46. ((_ . x) #'(%vector . x))
  47. (f (identifier? #'f) #'%generic-vector))))
  48. (define* (make-vector n #:optional init) (%make-vector n init))
  49. (define (vector? x) (%vector? x))
  50. (define (vector-length x) (%vector-length x))
  51. (define (vector-ref x i) (%vector-ref x i))
  52. (define (vector-set! x i v) (%vector-set! x i v))
  53. (define* (vector-copy v #:optional (start 0) (end (vector-length v)))
  54. (check-type v vector? 'vector-copy)
  55. (check-range start 0 (vector-length v) 'vector-copy)
  56. (check-range end start (vector-length v) 'vector-copy)
  57. (%inline-wasm
  58. '(func (param $src (ref $vector)) (param $start i32) (param $end i32)
  59. (result (ref eq))
  60. (local $i0 i32)
  61. (local $v0 (ref $raw-scmvector))
  62. (local.set $i0 (i32.sub (local.get $end)
  63. (local.get $start)))
  64. (local.set $v0 (array.new $raw-scmvector (ref.i31 (i32.const 0))
  65. (local.get $i0)))
  66. (array.copy $raw-scmvector $raw-scmvector
  67. (local.get $v0) (i32.const 0)
  68. (struct.get $vector $vals (local.get $src))
  69. (local.get $start) (local.get $i0))
  70. (struct.new $mutable-vector (i32.const 0) (local.get $v0)))
  71. v start end))
  72. (define* (vector-copy! to at from #:optional (start 0) (end (vector-length from)))
  73. (check-type to vector? 'vector-copy!)
  74. (check-range at 0 (vector-length to) 'vector-copy!)
  75. (check-type from vector? 'vector-copy!)
  76. (check-range start 0 (vector-length from) 'vector-copy!)
  77. (check-range end start (vector-length from) 'vector-copy!)
  78. (%inline-wasm
  79. '(func (param $to (ref $mutable-vector)) (param $at i32)
  80. (param $from (ref $vector)) (param $start i32) (param $end i32)
  81. (array.copy $raw-scmvector $raw-scmvector
  82. (struct.get $mutable-vector $vals (local.get $to))
  83. (local.get $at)
  84. (struct.get $vector $vals (local.get $from))
  85. (local.get $start)
  86. (i32.sub (local.get $end) (local.get $start))))
  87. to at from start end))
  88. (define* (vector-fill! v fill #:optional (start 0) (end (vector-length v)))
  89. ;; FIXME: check for mutability
  90. (check-type v vector? 'vector-fill!)
  91. (check-range start 0 (vector-length v) 'vector-fill!)
  92. (check-range end start (vector-length v) 'vector-fill!)
  93. (%inline-wasm
  94. '(func (param $dst (ref $mutable-vector)) (param $fill (ref eq))
  95. (param $start i32) (param $end i32)
  96. (array.fill $raw-scmvector
  97. (struct.get $mutable-vector $vals (local.get $dst))
  98. (local.get $start)
  99. (local.get $fill)
  100. (i32.sub (local.get $end) (local.get $start))))
  101. v fill start end))
  102. (define* (vector->list v #:optional (start 0) (end (vector-length v)))
  103. (let lp ((i start))
  104. (if (< i end)
  105. (cons (vector-ref v i) (lp (1+ i)))
  106. '())))
  107. (define (list->vector elts)
  108. (define (length l)
  109. (let lp ((len 0) (l l))
  110. (if (null? l) len (lp (1+ len) (cdr l)))))
  111. (let* ((len (length elts))
  112. (v (make-vector len #f)))
  113. (let lp ((i 0) (elts elts))
  114. (match elts
  115. (() v)
  116. ((elt . elts)
  117. (vector-set! v i elt)
  118. (lp (1+ i) elts))))))
  119. (define (vector-concatenate v*)
  120. (match v*
  121. (() #())
  122. ((v) v)
  123. (v*
  124. (let* ((len (fold (lambda (v len) (+ (vector-length v) len)) 0 v*))
  125. (flattened (make-vector len 0)))
  126. (let lp ((v* v*) (cur 0))
  127. (match v*
  128. (() flattened)
  129. ((v . v*)
  130. (vector-copy! flattened cur v)
  131. (lp v* (+ cur (vector-length v))))))))))
  132. (define (vector-append . vectors)
  133. (vector-concatenate vectors))
  134. (define (vector-for-each f v . v*)
  135. (apply for-each f (vector->list v) (map vector->list v*)))
  136. (define (vector-map f v . v*)
  137. (list->vector (apply map f (vector->list v) (map vector->list v*)))))