bitvectors.scm 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. ;;; Bitvectors
  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. ;;; Bitvectors.
  18. ;;;
  19. ;;; Code:
  20. (library (hoot bitvectors)
  21. (export bitvector?
  22. make-bitvector
  23. bitvector-length
  24. bitvector-ref
  25. bitvector-set-bit!)
  26. (import (rename (hoot primitives)
  27. (%<= <=)
  28. (%< <)
  29. (%- -)
  30. (%exact-integer? exact-integer?))
  31. (hoot errors)
  32. (hoot match)
  33. (hoot bitwise))
  34. (define (1- x) (- x 1))
  35. (define (bitvector? x) (%bitvector? x))
  36. (define* (make-bitvector len #:optional (fill #f))
  37. (check-size len (1- (ash 1 29)) 'make-bitvector)
  38. (%inline-wasm
  39. '(func (param $len i32) (param $init i32) (result (ref eq))
  40. (struct.new $mutable-bitvector
  41. (i32.const 0)
  42. (local.get $len)
  43. (array.new $raw-bitvector
  44. (local.get $init)
  45. (i32.add (i32.shr_u (i32.sub (local.get $len)
  46. (i32.const 1))
  47. (i32.const 5))
  48. (i32.const 1)))))
  49. len
  50. (match fill (#f 0) (#t -1))))
  51. (define (bitvector-length bv)
  52. (check-type bv bitvector? 'bitvector-length)
  53. (%inline-wasm
  54. '(func (param $bv (ref $bitvector))
  55. (result (ref eq))
  56. (ref.i31
  57. (i32.shl (struct.get $bitvector $len (local.get $bv))
  58. (i32.const 1))))
  59. bv))
  60. (define (bitvector-ref bv i)
  61. (check-type bv bitvector? 'bitvector-ref)
  62. (check-index i (bitvector-length bv) 'bitvector-ref)
  63. (%inline-wasm
  64. '(func (param $bv (ref $bitvector))
  65. (param $i i32)
  66. (result (ref eq))
  67. (if (ref eq)
  68. (i32.and
  69. (array.get $raw-bitvector
  70. (struct.get $bitvector $vals (local.get $bv))
  71. (i32.shr_s (local.get $i) (i32.const 5)))
  72. (i32.shl (i32.const 1) (local.get $i)))
  73. (then (ref.i31 (i32.const 17)))
  74. (else (ref.i31 (i32.const 1)))))
  75. bv i))
  76. (define (bitvector-set-bit! bv i)
  77. (define (mutable-bitvector? x)
  78. (%inline-wasm
  79. '(func (param $bv (ref eq)) (result (ref eq))
  80. (if (ref eq)
  81. (ref.test $mutable-bitvector (local.get $bv))
  82. (then (ref.i31 (i32.const 17)))
  83. (else (ref.i31 (i32.const 1)))))
  84. x))
  85. (check-type bv mutable-bitvector? 'bitvector-set-bit!)
  86. (check-index i (bitvector-length bv) 'bitvector-set-bit!)
  87. (%inline-wasm
  88. '(func (param $bv (ref $mutable-bitvector))
  89. (param $i i32)
  90. (local $i0 i32)
  91. (local.set $i0 (i32.shr_s (local.get $i) (i32.const 5)))
  92. (array.set $raw-bitvector
  93. (struct.get $bitvector $vals (local.get $bv))
  94. (local.get $i0)
  95. (i32.or
  96. (array.get $raw-bitvector
  97. (struct.get $bitvector $vals (local.get $bv))
  98. (i32.shr_s (local.get $i) (i32.const 5)))
  99. (i32.shl (i32.const 1) (local.get $i)))))
  100. bv i))
  101. ;; bitvector-set!, list->bitvector etc not yet implemented
  102. )