123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- ;;; Vectors
- ;;; Copyright (C) 2024 Igalia, S.L.
- ;;;
- ;;; Licensed under the Apache License, Version 2.0 (the "License");
- ;;; you may not use this file except in compliance with the License.
- ;;; You may obtain a copy of the License at
- ;;;
- ;;; http://www.apache.org/licenses/LICENSE-2.0
- ;;;
- ;;; Unless required by applicable law or agreed to in writing, software
- ;;; distributed under the License is distributed on an "AS IS" BASIS,
- ;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ;;; See the License for the specific language governing permissions and
- ;;; limitations under the License.
- ;;; Commentary:
- ;;;
- ;;; Vectors.
- ;;;
- ;;; Code:
- (library (hoot vectors)
- (export vector
- make-vector
- vector?
- vector-length
- vector-ref
- vector-set!
- vector-copy
- vector-copy!
- vector-fill!
- vector->list
- list->vector
- vector-concatenate
- vector-append
- vector-for-each
- vector-map)
- (import (hoot primitives)
- (hoot pairs)
- (hoot numbers)
- (hoot lists)
- (hoot errors)
- (hoot match))
- (define (%generic-vector . args) (list->vector args))
- (define-syntax vector
- (lambda (stx)
- (syntax-case stx ()
- ((_ . x) #'(%vector . x))
- (f (identifier? #'f) #'%generic-vector))))
- (define* (make-vector n #:optional init) (%make-vector n init))
- (define (vector? x) (%vector? x))
- (define (vector-length x) (%vector-length x))
- (define (vector-ref x i) (%vector-ref x i))
- (define (vector-set! x i v) (%vector-set! x i v))
- (define* (vector-copy v #:optional (start 0) (end (vector-length v)))
- (check-type v vector? 'vector-copy)
- (check-range start 0 (vector-length v) 'vector-copy)
- (check-range end start (vector-length v) 'vector-copy)
- (%inline-wasm
- '(func (param $src (ref $vector)) (param $start i32) (param $end i32)
- (result (ref eq))
- (local $i0 i32)
- (local $v0 (ref $raw-scmvector))
- (local.set $i0 (i32.sub (local.get $end)
- (local.get $start)))
- (local.set $v0 (array.new $raw-scmvector (ref.i31 (i32.const 0))
- (local.get $i0)))
- (array.copy $raw-scmvector $raw-scmvector
- (local.get $v0) (i32.const 0)
- (struct.get $vector $vals (local.get $src))
- (local.get $start) (local.get $i0))
- (struct.new $mutable-vector (i32.const 0) (local.get $v0)))
- v start end))
- (define* (vector-copy! to at from #:optional (start 0) (end (vector-length from)))
- (check-type to vector? 'vector-copy!)
- (check-range at 0 (vector-length to) 'vector-copy!)
- (check-type from vector? 'vector-copy!)
- (check-range start 0 (vector-length from) 'vector-copy!)
- (check-range end start (vector-length from) 'vector-copy!)
- (%inline-wasm
- '(func (param $to (ref $mutable-vector)) (param $at i32)
- (param $from (ref $vector)) (param $start i32) (param $end i32)
- (array.copy $raw-scmvector $raw-scmvector
- (struct.get $mutable-vector $vals (local.get $to))
- (local.get $at)
- (struct.get $vector $vals (local.get $from))
- (local.get $start)
- (i32.sub (local.get $end) (local.get $start))))
- to at from start end))
- (define* (vector-fill! v fill #:optional (start 0) (end (vector-length v)))
- ;; FIXME: check for mutability
- (check-type v vector? 'vector-fill!)
- (check-range start 0 (vector-length v) 'vector-fill!)
- (check-range end start (vector-length v) 'vector-fill!)
- (%inline-wasm
- '(func (param $dst (ref $mutable-vector)) (param $fill (ref eq))
- (param $start i32) (param $end i32)
- (array.fill $raw-scmvector
- (struct.get $mutable-vector $vals (local.get $dst))
- (local.get $start)
- (local.get $fill)
- (i32.sub (local.get $end) (local.get $start))))
- v fill start end))
- (define* (vector->list v #:optional (start 0) (end (vector-length v)))
- (let lp ((i start))
- (if (< i end)
- (cons (vector-ref v i) (lp (1+ i)))
- '())))
- (define (list->vector elts)
- (define (length l)
- (let lp ((len 0) (l l))
- (if (null? l) len (lp (1+ len) (cdr l)))))
- (let* ((len (length elts))
- (v (make-vector len #f)))
- (let lp ((i 0) (elts elts))
- (match elts
- (() v)
- ((elt . elts)
- (vector-set! v i elt)
- (lp (1+ i) elts))))))
- (define (vector-concatenate v*)
- (match v*
- (() #())
- ((v) v)
- (v*
- (let* ((len (fold (lambda (v len) (+ (vector-length v) len)) 0 v*))
- (flattened (make-vector len 0)))
- (let lp ((v* v*) (cur 0))
- (match v*
- (() flattened)
- ((v . v*)
- (vector-copy! flattened cur v)
- (lp v* (+ cur (vector-length v))))))))))
- (define (vector-append . vectors)
- (vector-concatenate vectors))
- (define (vector-for-each f v . v*)
- (apply for-each f (vector->list v) (map vector->list v*)))
- (define (vector-map f v . v*)
- (list->vector (apply map f (vector->list v) (map vector->list v*)))))
|