Skip to content

Commit

Permalink
Add basic part of array-buffer
Browse files Browse the repository at this point in the history
  • Loading branch information
Ancker-0 committed Feb 25, 2025
1 parent ea4c65b commit f0dc652
Show file tree
Hide file tree
Showing 3 changed files with 446 additions and 2 deletions.
338 changes: 337 additions & 1 deletion GoldfishLang.tmu
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@

\ \ rich-list range stack

\ \ rich-vector array rich-hash-table
\ \ rich-vector array rich-hash-table array-buffer

\ \ box $

Expand Down Expand Up @@ -3725,6 +3725,342 @@
\;
</scm-chunk>

<section|array-buffer>

<scm|array-buffer> 是大小可变的数组,支持随机读写,均摊 <math|O<around*|(|1|)>> 时间在末尾插入和删除元素。成员 <scm|size> 表示数组的大小,<scm|capacity> 表示内存中预留的空间。

<\goldfish-chunk|goldfish/liii/lang.scm|true|true>
(define-case-class array-buffer ((data vector?) (size integer?) (capacity integer?))

\;
</goldfish-chunk>

<subsection|静态方法>

<paragraph|array-buffer@from-vector>

<\goldfish-chunk|goldfish/liii/lang.scm|true|true>
(chained-define (@from-vector vec)

\ \ (let ((len (vector-length vec)))

\ \ \ \ (array-buffer (copy vec) len len)))

\;
</goldfish-chunk>

<paragraph|array-buffer@from-list>

<\goldfish-chunk|goldfish/liii/lang.scm|true|true>
(chained-define (@from-list lst)

\ \ (let ((len (length lst)))

\ \ \ \ (array-buffer (copy lst (make-vector len)) len len)))

\;
</goldfish-chunk>

<subsection|内部方法>

<\goldfish-chunk|goldfish/liii/lang.scm|true|true>
(define (check-bound n)

\ \ (when (or (not (integer? n)) (\<less\> n 0) (\<gtr\>= n size))

\ \ \ \ (key-error "array-buffer out of bound")))

\;
</goldfish-chunk>

<subsection|选择器>

<paragraph|array-buffer%get>

<\goldfish-chunk|goldfish/liii/lang.scm|true|true>
(chained-define (%get) data)

\;
</goldfish-chunk>

<paragraph|array-buffer%collect>

<\goldfish-chunk|goldfish/liii/lang.scm|true|true>
(chained-define (%collect) data)

\;
</goldfish-chunk>

<paragraph|array-buffer%to-rich-vector>

<\goldfish-chunk|goldfish/liii/lang.scm|true|true>
(chained-define (%to-rich-vector) (rich-vector (copy data (make-vector size))))

\;
</goldfish-chunk>

<paragraph|array-buffer%to-rich-list>

<\goldfish-chunk|goldfish/liii/lang.scm|true|true>
(chained-define (%to-rich-list) (rich-list (vector-\<gtr\>list (copy data (make-vector size)))))

\;
</goldfish-chunk>

<paragraph|array-buffer%length>

<\goldfish-chunk|goldfish/liii/lang.scm|true|true>
(define (%length) size)

\;
</goldfish-chunk>

<paragraph|array-buffer%apply>

<\goldfish-chunk|goldfish/liii/lang.scm|true|true>
(chained-define (%apply n)

\ \ (check-bound n)

\ \ (vector-ref data n))

\;
</goldfish-chunk>

<subsection|修改器>

<paragraph|array-buffer%set!>

<\goldfish-chunk|goldfish/liii/lang.scm|true|true>
(chained-define (%set! n v)

\ \ (check-bound n)

\ \ (vector-set! data n v))

\;
</goldfish-chunk>

<paragraph|array-buffer%update!>

同 <scm|%set!>,兼容 Scala。

<\goldfish-chunk|goldfish/liii/lang.scm|true|true>
(define (%update! . args)

\ \ (apply %set! args))

\;
</goldfish-chunk>

<paragraph|array-buffer%extend!>

将内部存储预留至少大小为 <scm|n> 的空间。

<\goldfish-chunk|goldfish/liii/lang.scm|true|true>
(chained-define (%extend! n)

\ \ (when (\<less\> capacity n)

\ \ \ \ (if (= capacity 0)

\ \ \ \ \ \ (set! capacity n)

\ \ \ \ \ \ (let loop ()

\ \ \ \ \ \ \ \ (when (\<less\> capacity n)

\ \ \ \ \ \ \ \ \ \ (set! capacity (* 2 capacity))

\ \ \ \ \ \ \ \ \ \ (loop))))

\ \ \ \ (set! data (copy data (make-vector capacity) 0 size)))

\ \ (%this))

\;
</goldfish-chunk>

<paragraph|array-buffer%size-hint!>

同 <scm|%extend!>,兼容 Scala。

<\goldfish-chunk|goldfish/liii/lang.scm|true|true>
(define (%size-hint! . args) (apply %extend! args))

\;
</goldfish-chunk>

<paragraph|array-buffer%resize!>

修改数组大小为 <scm|n>。

<\goldfish-chunk|goldfish/liii/lang.scm|true|true>
(chained-define (%resize! n)

\ \ (%extend! n)

\ \ (set! size n)

\ \ (%this))

\;
</goldfish-chunk>

<paragraph|array-buffer%add-one!>

在数组末尾添加一个元素。

<\goldfish-chunk|goldfish/liii/lang.scm|true|true>
(chained-define (%add-one! x)

\ \ (%extend! (+ size 1))

\ \ (vector-set! data size x)

\ \ (set! size (+ size 1))

\ \ (%this))

\;
</goldfish-chunk>

<paragraph|array-buffer%clear!>

清除数组,即 <scm|(%resize! 0)>。注意该操作并不会修改内部存储的空间。

<\goldfish-chunk|goldfish/liii/lang.scm|true|true>
(chained-define (%clear!)

\ \ (set! size 0)

\ \ (%this))

\;
</goldfish-chunk>

<paragraph|array-buffer%clear/shrink!>

清除数组并回收所用空间。

<\goldfish-chunk|goldfish/liii/lang.scm|true|true>
(chained-define (%clear/shrink!)

\ \ (set! size 0)

\ \ (set! capacity 1)

\ \ (set! data (make-vector 1))

\ \ (%this))

\;
</goldfish-chunk>

<paragraph|array-buffer%insert!>

在指定位置插入元素。

<\goldfish-chunk|goldfish/liii/lang.scm|true|true>
(chained-define (%insert! index elem)

\ \ (%extend! (+ size 1))

\ \ (set! size (+ size 1))

\ \ (check-bound index)

\ \ (let loop ((p (- size 1)))

\ \ \ \ (when (\<gtr\> p index)

\ \ \ \ \ \ (vector-set! data p (vector-ref data (- p 1)))

\ \ \ \ \ \ (loop (- p 1))))

\ \ (vector-set! data index elem)

\ \ (%this))

\;
</goldfish-chunk>

<subsection|谓词>

<paragraph|array-buffer%equals>

<\goldfish-chunk|goldfish/liii/lang.scm|true|true>
(typed-define (%equals (that case-class?))

\ \ (and (that :is-instance-of 'array-buffer)

\ \ \ \ \ \ \ ((%this :to-rich-vector) :equals (that :to-rich-vector))))

\;
</goldfish-chunk>

<\goldfish-chunk|tests/goldfish/liii/lang-test.scm|true|true>
(check-true (== (array-buffer :from-list '(1 2 3))

\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (array-buffer :from-list '(1 2) :add-one! 3)))

(check-true (== (array-buffer :from-list '(1 2 3))

\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (array-buffer :from-list '(1 2 3) :extend! 10)))

\;
</goldfish-chunk>

<subsection|高阶函数>

<subsection|转换器>

<subsection|结尾>

<\scm-chunk|goldfish/liii/lang.scm|true|true>
) ; end of array-buffer

\;
</scm-chunk>

综合测试。

<\goldfish-chunk|tests/goldfish/liii/lang-test.scm|true|true>
(let ((arb (array-buffer :from-list '(3 1 2 5 4))))

\ \ (check (arb :get) =\<gtr\> #(3 1 2 5 4))

\ \ (check (arb :to-rich-vector) =\<gtr\> (rich-vector #(3 1 2 5 4)))

\ \ (check (arb :to-rich-list) =\<gtr\> (rich-list '(3 1 2 5 4)))

\ \ (arb :add-one! 0)

\ \ (check (arb :to-rich-vector) =\<gtr\> (rich-vector #(3 1 2 5 4 0)))

\ \ (check (arb :to-rich-list) =\<gtr\> (rich-list '(3 1 2 5 4 0)))

\ \ (arb :insert! 0 0)

\ \ (check (arb :to-rich-vector) =\<gtr\> (rich-vector #(0 3 1 2 5 4 0)))

\ \ (check (arb :to-rich-list) =\<gtr\> (rich-list '(0 3 1 2 5 4 0)))

\ \ (check (arb :resize! 4 :to-rich-list :collect) =\<gtr\> '(0 3 1 2))

\ \ (check (arb :resize! 3 :to-rich-vector :collect) =\<gtr\> #(0 3 1))

\ \ (check (arb :insert! 1 2 :to-rich-list :collect) =\<gtr\> '(0 2 3 1))

\ \ (check (arb 0) =\<gtr\> 0)

\ \ (check (arb 1) =\<gtr\> 2)

\ \ (check-catch 'key-error (arb 5)))

\;
</goldfish-chunk>

<section|range>

<\goldfish-chunk|goldfish/liii/lang.scm|true|true>
Expand Down
Loading

0 comments on commit f0dc652

Please sign in to comment.