diff options
-rw-r--r-- | implementation/flexvectors-body2.scm | 10 | ||||
-rw-r--r-- | implementation/flexvectors.sld | 2 | ||||
-rw-r--r-- | implementation/tests.scm | 18 | ||||
-rw-r--r-- | srfi-214.html | 10 |
4 files changed, 37 insertions, 3 deletions
diff --git a/implementation/flexvectors-body2.scm b/implementation/flexvectors-body2.scm index ba3e2f5..6f37efe 100644 --- a/implementation/flexvectors-body2.scm +++ b/implementation/flexvectors-body2.scm @@ -389,3 +389,13 @@ (define (generator->flexvector g) (assume (procedure? g)) (flexvector-unfold eof-object? (lambda (x) x) (lambda (_) (g)) (g))) + +(define (flexvector->generator fv) + (assume (flexvector? fv)) + (let ((i 0)) + (lambda () + (if (< i (flexvector-length fv)) + (let ((element (flexvector-ref fv i))) + (set! i (+ i 1)) + element) + (eof-object))))) diff --git a/implementation/flexvectors.sld b/implementation/flexvectors.sld index 25e1543..4bc7da3 100644 --- a/implementation/flexvectors.sld +++ b/implementation/flexvectors.sld @@ -38,7 +38,7 @@ flexvector->vector flexvector->list flexvector->string vector->flexvector list->flexvector string->flexvector reverse-flexvector->list reverse-list->flexvector - generator->flexvector) + generator->flexvector flexvector->generator) (import (scheme base) (scheme case-lambda) diff --git a/implementation/tests.scm b/implementation/tests.scm index 329a8d6..e41f19c 100644 --- a/implementation/tests.scm +++ b/implementation/tests.scm @@ -64,6 +64,24 @@ (flexvector->vector (string->flexvector "abc"))) (test-equal "flexvector->string" "abc" (flexvector->string (flexvector #\a #\b #\c))) +(define genlist '(a b c)) +(define (mock-generator) + (if (pair? genlist) + (let ((value (car genlist))) + (set! genlist (cdr genlist)) + value) + (eof-object))) + +(test-equal "generator->flexvector" #(a b c) + (flexvector->vector (generator->flexvector mock-generator))) +(test-equal "flexvector->generator" '(a b c #t) + (let* ((gen (flexvector->generator (flexvector 'a 'b 'c))) + (one (gen)) + (two (gen)) + (three (gen)) + (four (eof-object? (gen)))) + (list one two three four))) + ; Nondestructive operations on one vector (let ((fv (flexvector 10 20 30))) (test-equal "flexvector->vector" #(10 20 30) (flexvector->vector fv)) diff --git a/srfi-214.html b/srfi-214.html index 93d2fc0..2341c60 100644 --- a/srfi-214.html +++ b/srfi-214.html @@ -153,6 +153,7 @@ <li><a href="#list-flexvector-reverse-list-flexvector"><code>reverse-list->flexvector</code></a></li> <li><a href="#flexvector-string"><code>flexvector->string</code></a></li> <li><a href="#string-flexvector"><code>string->flexvector</code></a></li> +<li><a href="#flexvector-generator"><code>flexvector->generator</code></a></li> <li><a href="#generator-flexvector"><code>generator->flexvector</code></a></li> </ul> </li> @@ -336,18 +337,20 @@ zot <div class="copy-wrapper"><pre><code class="language-scheme"><span><span class="mtk1">(flexvector-count even? (flexvector </span><span class="mtk21">3</span><span class="mtk1"> </span><span class="mtk21">1</span><span class="mtk1"> </span><span class="mtk21">4</span><span class="mtk1"> </span><span class="mtk21">1</span><span class="mtk1"> </span><span class="mtk21">5</span><span class="mtk1"> </span><span class="mtk21">9</span><span class="mtk1"> </span><span class="mtk21">2</span><span class="mtk1"> </span><span class="mtk21">5</span><span class="mtk1"> </span><span class="mtk21">6</span><span class="mtk1">))</span></span><br><span><span class="mtk4">;=> 3</span></span><br><span><span> </span></span><br><span><span class="mtk1">(flexvector-count < (flexvector </span><span class="mtk21">1</span><span class="mtk1"> </span><span class="mtk21">3</span><span class="mtk1"> </span><span class="mtk21">6</span><span class="mtk1"> </span><span class="mtk21">9</span><span class="mtk1">) (flexvector </span><span class="mtk21">2</span><span class="mtk1"> </span><span class="mtk21">4</span><span class="mtk1"> </span><span class="mtk21">6</span><span class="mtk1"> </span><span class="mtk21">8</span><span class="mtk1"> </span><span class="mtk21">10</span><span class="mtk1"> </span><span class="mtk21">12</span><span class="mtk1">))</span></span><br><span><span class="mtk4">;=> 2</span></span><br></code></pre></div> <h4 id="flexvector-cumulate"><code>flexvector-cumulate</code></h4> <p><code>(flexvector-cumulate f knil fv)</code></p> -<p>Returns a newly-allocated flexvector <code>new</code> with the same length as <code>fv</code>. Each element <code>i</code> of <code>new</code> is set to the result of <code>(f (flexvector-ref new (- i 1)) (flexvector-ref vec i))</code>, except that, for the first call on <code>f</code>, the first argument is <code>knil</code>. The <code>new</code> flexvector is returned.</p> +<p>Returns a newly-allocated flexvector <code>new</code> with the same length as <code>fv</code>. Each element <code>i</code> of <code>new</code> is set to the result of <code>(f (flexvector-ref new (- i 1)) (flexvector-ref fv i))</code>, except that, for the first call on <code>f</code>, the first argument is <code>knil</code>. The <code>new</code> flexvector is returned.</p> <div class="copy-wrapper"><pre><code class="language-scheme"><span><span class="mtk1">(flexvector-cumulate + </span><span class="mtk21">0</span><span class="mtk1"> (flexvector </span><span class="mtk21">3</span><span class="mtk1"> </span><span class="mtk21">1</span><span class="mtk1"> </span><span class="mtk21">4</span><span class="mtk1"> </span><span class="mtk21">1</span><span class="mtk1"> </span><span class="mtk21">5</span><span class="mtk1"> </span><span class="mtk21">9</span><span class="mtk1"> </span><span class="mtk21">2</span><span class="mtk1"> </span><span class="mtk21">5</span><span class="mtk1"> </span><span class="mtk21">6</span><span class="mtk1">))</span></span><br><span><span class="mtk4">;=> #<flexvector 3 4 8 9 14 23 25 30 36></span></span><br></code></pre></div> <h3 id="searching">Searching</h3> <h4 id="flexvector-index-flexvector-index-right"><code>flexvector-index</code>, <code>flexvector-index-right</code></h4> <p><code>(flexvector-index pred? fv1 fv2 ...)</code></p> <p>Finds and returns the index of the first elements in <code>fv1 fv2 ...</code> that satisfy <code>pred?</code>. If no matching element is found by the end of the shortest flexvector, <code>#f</code> is returned.</p> <p><code>flexvector-index-right</code> is similar, but returns the index of the <em>last</em> elements that satisfy <code>pred?</code>, and requires all flexvector arguments to have the same length.</p> +<p>Given <em>n</em> arguments <code>fv1 fv2...</code>, <code>pred?</code> should be a function that takes <em>n</em> arguments and returns a single value, interpreted as a boolean.</p> <div class="copy-wrapper"><pre><code class="language-scheme"><span><span class="mtk1">(flexvector-index even? (flexvector </span><span class="mtk21">3</span><span class="mtk1"> </span><span class="mtk21">1</span><span class="mtk1"> </span><span class="mtk21">4</span><span class="mtk1"> </span><span class="mtk21">1</span><span class="mtk1"> </span><span class="mtk21">5</span><span class="mtk1"> </span><span class="mtk21">9</span><span class="mtk1">))</span></span><br><span><span class="mtk4">;=> 2</span></span><br><span><span> </span></span><br><span><span class="mtk1">(flexvector-index < (flexvector </span><span class="mtk21">3</span><span class="mtk1"> </span><span class="mtk21">1</span><span class="mtk1"> </span><span class="mtk21">4</span><span class="mtk1"> </span><span class="mtk21">1</span><span class="mtk1"> </span><span class="mtk21">5</span><span class="mtk1"> </span><span class="mtk21">9</span><span class="mtk1"> </span><span class="mtk21">2</span><span class="mtk1"> </span><span class="mtk21">5</span><span class="mtk1"> </span><span class="mtk21">6</span><span class="mtk1">) (flexvector </span><span class="mtk21">2</span><span class="mtk1"> </span><span class="mtk21">7</span><span class="mtk1"> </span><span class="mtk21">1</span><span class="mtk1"> </span><span class="mtk21">8</span><span class="mtk1"> </span><span class="mtk21">2</span><span class="mtk1">))</span></span><br><span><span class="mtk4">;=> 1</span></span><br><span><span> </span></span><br><span><span class="mtk1">(flexvector-index = (flexvector </span><span class="mtk21">3</span><span class="mtk1"> </span><span class="mtk21">1</span><span class="mtk1"> </span><span class="mtk21">4</span><span class="mtk1"> </span><span class="mtk21">1</span><span class="mtk1"> </span><span class="mtk21">5</span><span class="mtk1"> </span><span class="mtk21">9</span><span class="mtk1"> </span><span class="mtk21">2</span><span class="mtk1"> </span><span class="mtk21">5</span><span class="mtk1"> </span><span class="mtk21">6</span><span class="mtk1">) (flexvector </span><span class="mtk21">2</span><span class="mtk1"> </span><span class="mtk21">7</span><span class="mtk1"> </span><span class="mtk21">1</span><span class="mtk1"> </span><span class="mtk21">8</span><span class="mtk1"> </span><span class="mtk21">2</span><span class="mtk1">))</span></span><br><span><span class="mtk4">;=> #f</span></span><br><span><span> </span></span><br><span><span class="mtk1">(flexvector-index-right < (flexvector </span><span class="mtk21">3</span><span class="mtk1"> </span><span class="mtk21">1</span><span class="mtk1"> </span><span class="mtk21">4</span><span class="mtk1"> </span><span class="mtk21">1</span><span class="mtk1"> </span><span class="mtk21">5</span><span class="mtk1">) (flexvector </span><span class="mtk21">2</span><span class="mtk1"> </span><span class="mtk21">7</span><span class="mtk1"> </span><span class="mtk21">1</span><span class="mtk1"> </span><span class="mtk21">8</span><span class="mtk1"> </span><span class="mtk21">2</span><span class="mtk1">))</span></span><br><span><span class="mtk4">;=> 3</span></span><br></code></pre></div> <h4 id="flexvector-skip-flexvector-skip-right"><code>flexvector-skip</code>, <code>flexvector-skip-right</code></h4> <p><code>(flexvector-skip pred? fv1 fv2 ...)</code></p> <p>Finds and returns the index of the first elements in <code>fv1 fv2 ...</code> that do <em>not</em> satisfy <code>pred?</code>. If all the values in the flexvectors satisfy <code>pred?</code> until the end of the shortest flexvector, this returns <code>#f</code>.</p> <p><code>flexvector-skip-right</code> is similar, but returns the index of the <em>last</em> elements that do not satisfy <code>pred?</code>, and requires all flexvector arguments to have the same length.</p> +<p>Given <em>n</em> arguments <code>fv1 fv2...</code>, <code>pred?</code> should be a function that takes <em>n</em> arguments and returns a single value, interpreted as a boolean.</p> <div class="copy-wrapper"><pre><code class="language-scheme"><span><span class="mtk1">(flexvector-skip number? (flexvector </span><span class="mtk21">1</span><span class="mtk1"> </span><span class="mtk21">2</span><span class="mtk1"> 'a 'b </span><span class="mtk21">3</span><span class="mtk1"> </span><span class="mtk21">4</span><span class="mtk1"> 'c 'd))</span></span><br><span><span class="mtk4">;=> 2</span></span><br><span><span> </span></span><br><span><span class="mtk1">(flexvector-skip-right number? (flexvector </span><span class="mtk21">1</span><span class="mtk1"> </span><span class="mtk21">2</span><span class="mtk1"> 'a 'b </span><span class="mtk21">3</span><span class="mtk1"> </span><span class="mtk21">4</span><span class="mtk1"> 'c 'd))</span></span><br><span><span class="mtk4">;=> 4</span></span><br></code></pre></div> <h4 id="flexvector-binary-search"><code>flexvector-binary-search</code></h4> <p><code>(flexvector-binary-search fv value cmp [start [end]])</code></p> @@ -388,8 +391,11 @@ zot <p>Both <code>start</code> and <code>end</code> are clamped to the range [0, <code>(flexvector-length fv)</code>). It is an error if <code>end</code> is less than <code>start</code>.</p> <h4 id="string-flexvector"><code>string->flexvector</code></h4> <p><code>(string->flexvector string [start [end]])</code></p> -<p>Creates a flexvector containing the elements in <code>string</code> between <code>start</code>, which defaults to -1, and <code>end</code>, which defaults to the length of <code>string</code>.</p> +<p>Creates a flexvector containing the elements in <code>string</code> between <code>start</code>, which defaults to 0, and <code>end</code>, which defaults to the length of <code>string</code>.</p> <p>Both <code>start</code> and <code>end</code> are clamped to the range [0, <code>(string-length string)</code>). It is an error if <code>end</code> is less than <code>start</code>.</p> +<h4 id="flexvector-generator"><code>flexvector->generator</code></h4> +<p><code>(flexvector->generator fv)</code></p> +<p>Returns a <a target="_blank" href="https://srfi.schemers.org/srfi-158/srfi-158.html">SRFI 158</a> generator that emits the elements of the flexvector <code>fv</code>, in order. If <code>fv</code> is mutated before the generator is exhausted, the generator's remaining return values are undefined.</p> <h4 id="generator-flexvector"><code>generator->flexvector</code></h4> <p><code>(generator->flexvector gen)</code></p> <p>Creates a flexvector containing all elements produced by the <a target="_blank" href="https://srfi.schemers.org/srfi-158/srfi-158.html">SRFI 158</a> generator <code>gen</code>.</p> |