weak-vectors.scm 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. ;;; Hoot weak vectors module
  2. ;;; Copyright (C) 2024 Vivianne Langdon <puttabutta@gmail.com>
  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. ;;; Hoot weak vectors module.
  18. ;;;
  19. ;;; Code:
  20. (library (hoot weak-vectors)
  21. (export make-weak-vector
  22. weak-vector
  23. list->weak-vector
  24. weak-vector?
  25. weak-vector-ref
  26. weak-vector-set!
  27. weak-vector-length)
  28. (import (hoot inline-wasm)
  29. (hoot lists)
  30. (hoot match)
  31. (hoot numbers)
  32. (hoot not)
  33. (hoot pairs)
  34. (hoot ports)
  35. (hoot records)
  36. (hoot syntax)
  37. (hoot vectors)
  38. (hoot weak-refs)
  39. (hoot write)
  40. (only (guile)
  41. *unspecified*))
  42. (define (immediate? x)
  43. (%inline-wasm
  44. '(func (param $x (ref eq)) (result (ref eq))
  45. (if (ref eq)
  46. (ref.test i31 (local.get $x))
  47. (then (ref.i31 (i32.const 17)))
  48. (else (ref.i31 (i32.const 1)))))
  49. x))
  50. (define-record-type <weak-vector>
  51. #:printer (lambda (wvec port)
  52. (let ((len (weak-vector-length wvec)))
  53. (write-string "#<weak-vector" port)
  54. (do ((i 0 (1+ i)))
  55. ((= i len))
  56. (write-char #\space port)
  57. (write (weak-vector-ref wvec i) port)))
  58. (write-string ">" port))
  59. (%make-weak-vector vec)
  60. weak-vector?
  61. (vec weak-vector-vec))
  62. (define (maybe-make-weak-ref x)
  63. ;; immediates are simply stored as-is and not wrapped in a weak ref
  64. (if (immediate? x) x (make-weak-ref x)))
  65. (define* (make-weak-vector size #:optional (fill *unspecified*))
  66. (%make-weak-vector (make-vector size (maybe-make-weak-ref fill))))
  67. (define (weak-vector . elems) (list->weak-vector elems))
  68. (define (list->weak-vector l)
  69. (define vec (make-weak-vector (length l)))
  70. (let lp ((i 0) (l l))
  71. (match l
  72. (() vec)
  73. ((x . rest)
  74. (weak-vector-set! vec i x)
  75. (lp (1+ i) rest)))))
  76. (define (weak-vector-ref wvect k)
  77. (let ((ref (vector-ref (weak-vector-vec wvect) k)))
  78. (if (weak-ref? ref)
  79. (let ((item (weak-ref-deref ref)))
  80. (and (not (weak-ref-null? item)) item))
  81. ref)))
  82. (define (weak-vector-set! wvect k elt)
  83. (vector-set! (weak-vector-vec wvect) k (maybe-make-weak-ref elt)))
  84. (define (weak-vector-length wvect)
  85. (vector-length (weak-vector-vec wvect))))