core: make subarry/substring slice

This commit is contained in:
hellerve 2020-02-11 09:09:30 +01:00
parent f63f4c54ad
commit ee812b37e6
17 changed files with 119 additions and 118 deletions

View File

@ -8,7 +8,7 @@
(defn some-subarray []
(let-do [a (replicate n &1)
b (subarray &a 0 (/ n 2))]
b (slice &a 0 (/ n 2))]
(assert (= (/ n 2) (length &b)))))
(defn perform-bench [new-n]

View File

@ -138,20 +138,20 @@ If the array is empty, returns `Nothing`")
(defn sum [xs]
(Array.reduce &(fn [x y] (+ x @y)) (zero) xs))
(doc subarray "gets a subarray from `start-index` to `end-index`.")
(defn subarray [xs start-index end-index]
(doc slice "gets a subarray from `start-index` to `end-index`.")
(defn slice [xs start-index end-index]
(let-do [result []]
(for [i start-index end-index]
(set! result (push-back result @(unsafe-nth xs i))))
result))
(doc prefix-array "gets a prefix array to `end-index`.")
(defn prefix-array [xs end-index]
(subarray xs 0 end-index))
(doc prefix "gets a prefix array to `end-index`.")
(defn prefix [xs end-index]
(slice xs 0 end-index))
(doc suffix-array "gets a suffix array from `start-index`.")
(defn suffix-array [xs start-index]
(subarray xs start-index (length xs)))
(doc suffix "gets a suffix array from `start-index`.")
(defn suffix [xs start-index]
(slice xs start-index (length xs)))
(doc reverse "reverses an array.")
(defn reverse [a]

View File

@ -17,14 +17,14 @@
(Project.config "echo-compiler-cmd" false))))
(defmodule String
(defndynamic prefix-string [s to]
(String.substring s 0 to))
(defndynamic prefix [s to]
(String.slice s 0 to))
(defndynamic suffix-string [s from]
(String.substring s from (String.length s)))
(defndynamic suffix [s from]
(String.slice s from (String.length s)))
(defndynamic tail [s ]
(String.suffix-string s 1))
(String.suffix s 1))
)
)

View File

@ -6,7 +6,7 @@
(defn dir-from-path [path]
(let [segments (split-by path &[\/])
n (dec (length &segments))
without-last (prefix-array &segments n)]
without-last (prefix &segments n)]
(concat &(copy-map &(fn [s] (str* s "/")) &without-last))))
(doc file-from-path "removes the base name part of a path to a file, similar to the `filename` utility in Shell scripting.")

View File

@ -11,15 +11,15 @@
(list 'ref
(list 'String.append
"%"
(fmt-internal (String.substring s (+ idx 2) len) args)))
(fmt-internal (String.slice s (+ idx 2) len) args)))
(if (= 0 (length args)) ; we need to insert something, but have nothing
(macro-error
(str "error in format string: not enough arguments to format string (missing argument for '%"
(String.substring s (inc idx) (inc (inc idx)))
(String.slice s (inc idx) (inc (inc idx)))
"')"))
; okay, this is the meat:
; get the next % after our escaper
(let [next (String.index-of (String.substring s (inc idx) len) \%)]
(let [next (String.index-of (String.slice s (inc idx) len) \%)]
(if (= -1 next)
(if (< 1 (length args))
(macro-error
@ -27,11 +27,11 @@
(cadr args)
"')"))
(list 'ref (list 'format s (car args))))
(let [slice (String.substring s 0 (+ (inc idx) next))]
(let [slice (String.slice s 0 (+ (inc idx) next))]
(list 'ref
(list 'String.append
(list 'ref (list 'format slice (car args)))
(fmt-internal (String.substring s (+ (inc idx) next) len)
(fmt-internal (String.slice s (+ (inc idx) next) len)
(cdr args)))))))))))))
(doc fmt "formats a string. It supports all of the string interpolations defined in format of the type that should be interpolated (e.g. %d and %x on integers).")

View File

@ -58,3 +58,5 @@
(definterface sqrt (λ [a] a))
(definterface tan (λ [a] a))
(definterface tanh (λ [a] a))
(definterface slice (Fn [&a Int Int] a))

View File

@ -50,16 +50,16 @@ If you want to replace all occurrences of the pattern, use `-1`.")
lidx (Array.length &idx)
result (Array.allocate (Int.inc lidx))]
(Array.aset-uninitialized! &result 0
(substring s 0 (if (> lidx 0) @(Array.unsafe-nth &idx 0) (length s))))
(slice s 0 (if (> lidx 0) @(Array.unsafe-nth &idx 0) (length s))))
(for [i 0 (Int.dec (Array.length &idx))]
(let [plen (length (Array.unsafe-nth &strs i))]
(Array.aset-uninitialized! &result (Int.inc i)
(substring s (+ @(Array.unsafe-nth &idx i) plen)
@(Array.unsafe-nth &idx (Int.inc i))))))
(slice s (+ @(Array.unsafe-nth &idx i) plen)
@(Array.unsafe-nth &idx (Int.inc i))))))
(when (> lidx 0)
(let [plen (length (Array.unsafe-nth &strs (Int.dec lidx)))]
(Array.aset-uninitialized! &result lidx
(suffix-string s (+ @(Array.unsafe-nth &idx (Int.dec lidx))
(suffix s (+ @(Array.unsafe-nth &idx (Int.dec lidx))
plen)))))
result))
@ -121,13 +121,13 @@ If you want to replace all occurrences of the pattern, use `-1`.")
lidx (Array.length &idx)
result (Array.allocate (Int.inc lidx))]
(Array.aset-uninitialized! &result 0
(substring s 0 (if (> lidx 0) @(Array.unsafe-nth &idx 0) (length s))))
(slice s 0 (if (> lidx 0) @(Array.unsafe-nth &idx 0) (length s))))
(for [i 0 (Int.dec (Array.length &idx))]
(Array.aset-uninitialized! &result (Int.inc i)
(substring s (Int.inc @(Array.unsafe-nth &idx i)) @(Array.unsafe-nth &idx (Int.inc i)))))
(slice s (Int.inc @(Array.unsafe-nth &idx i)) @(Array.unsafe-nth &idx (Int.inc i)))))
(when (> lidx 0)
(Array.aset-uninitialized! &result lidx
(suffix-string s (Int.inc @(Array.unsafe-nth &idx (Int.dec lidx))))))
(suffix s (Int.inc @(Array.unsafe-nth &idx (Int.dec lidx))))))
result))
(doc words "splits a string into words.")

View File

@ -63,24 +63,24 @@
(defn empty? [s]
(Int.= (length s) 0))
(defn substring [s a b]
(from-chars &(Array.subarray &(chars s) a b)))
(defn slice [s a b]
(from-chars &(Array.slice &(chars s) a b)))
(doc prefix-string "Return the first `a` characters of the string `s`.")
(defn prefix-string [s a]
(from-chars &(Array.subarray &(chars s) 0 a)))
(doc prefix "Return the first `a` characters of the string `s`.")
(defn prefix [s a]
(from-chars &(Array.slice &(chars s) 0 a)))
(doc suffix-string "Return the last `b` characters of the string `s`.")
(defn suffix-string [s b]
(from-chars &(Array.subarray &(chars s) b (length s))))
(doc suffix "Return the last `b` characters of the string `s`.")
(defn suffix [s b]
(from-chars &(Array.slice &(chars s) b (length s))))
(doc starts-with? "Check if the string `s` begins with the string `sub`.")
(defn starts-with? [s sub]
(= sub &(prefix-string s (length sub))))
(= sub &(prefix s (length sub))))
(doc ends-with? "Check if the string `s` ends with the string `sub`.")
(defn ends-with? [s sub]
(= sub &(suffix-string s (- (length s) (length sub)))))
(= sub &(suffix s (- (length s) (length sub)))))
(doc zero "The empty string.")
(defn zero [] @"")

View File

@ -81,8 +81,8 @@ String String_append(const String *a, const String *b) {
int total = la + lb + 1;
String buffer = CARP_MALLOC(total);
memcpy(buffer, *a, la);
memcpy(buffer+la, *b, lb);
buffer[la+lb] = '\0';
memcpy(buffer + la, *b, lb);
buffer[la + lb] = '\0';
return buffer;
}

View File

@ -802,19 +802,19 @@
</p>
</div>
<div class="binder">
<a class="anchor" href="#prefix-array">
<h3 id="prefix-array">
prefix-array
<a class="anchor" href="#prefix">
<h3 id="prefix">
prefix
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [(Ref (Array a) b), Int] (Array a))
(λ [(Ref a b), Int] a)
</p>
<pre class="args">
(prefix-array xs end-index)
(prefix xs end-index)
</pre>
<p class="doc">
<p>gets a prefix array to <code>end-index</code>.</p>
@ -1066,6 +1066,26 @@
</p>
</div>
<div class="binder">
<a class="anchor" href="#slice">
<h3 id="slice">
slice
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [(Ref (Array a) b), Int, Int] (Array a))
</p>
<pre class="args">
(slice xs start-index end-index)
</pre>
<p class="doc">
<p>gets a subarray from <code>start-index</code> to <code>end-index</code>.</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#sort">
<h3 id="sort">
@ -1207,29 +1227,9 @@
</p>
</div>
<div class="binder">
<a class="anchor" href="#subarray">
<h3 id="subarray">
subarray
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [(Ref (Array a) b), Int, Int] (Array a))
</p>
<pre class="args">
(subarray xs start-index end-index)
</pre>
<p class="doc">
<p>gets a subarray from <code>start-index</code> to <code>end-index</code>.</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#suffix-array">
<h3 id="suffix-array">
suffix-array
<a class="anchor" href="#suffix">
<h3 id="suffix">
suffix
</h3>
</a>
<div class="description">
@ -1239,7 +1239,7 @@
(λ [(Ref (Array a) b), Int] (Array a))
</p>
<pre class="args">
(suffix-array xs start-index)
(suffix xs start-index)
</pre>
<p class="doc">
<p>gets a suffix array from <code>start-index</code>.</p>

View File

@ -817,9 +817,9 @@
</p>
</div>
<div class="binder">
<a class="anchor" href="#prefix-string">
<h3 id="prefix-string">
prefix-string
<a class="anchor" href="#prefix">
<h3 id="prefix">
prefix
</h3>
</a>
<div class="description">
@ -829,7 +829,7 @@
(λ [(Ref String a), Int] String)
</p>
<pre class="args">
(prefix-string s a)
(prefix s a)
</pre>
<p class="doc">
<p>Return the first <code>a</code> characters of the string <code>s</code>.</p>
@ -914,6 +914,25 @@
</p>
</div>
<div class="binder">
<a class="anchor" href="#slice">
<h3 id="slice">
slice
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [(Ref String a), Int, Int] String)
</p>
<pre class="args">
(slice s a b)
</pre>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#split-by">
<h3 id="split-by">
@ -1012,28 +1031,9 @@
</p>
</div>
<div class="binder">
<a class="anchor" href="#substring">
<h3 id="substring">
substring
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [(Ref String a), Int, Int] String)
</p>
<pre class="args">
(substring s a b)
</pre>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#suffix-string">
<h3 id="suffix-string">
suffix-string
<a class="anchor" href="#suffix">
<h3 id="suffix">
suffix
</h3>
</a>
<div class="description">
@ -1043,7 +1043,7 @@
(λ [(Ref String a), Int] String)
</p>
<pre class="args">
(suffix-string s b)
(suffix s b)
</pre>
<p class="doc">
<p>Return the last <code>b</code> characters of the string <code>s</code>.</p>

View File

@ -183,8 +183,8 @@
(defn two-lengths-in-same-func []
(let [a [[1]]
b [1 2 3]
c1 (length &a)
c2 (length &b)]
c1 (Array.length &a)
c2 (Array.length &b)]
(println* (+ c1 c2))))
(defn changing-target-of-ref []

View File

@ -1 +0,0 @@
Keep this directory.

View File

@ -321,7 +321,7 @@ dynamicStringModule = Env { envBindings = bindings
, envFunctionNestingLevel = 0 }
where bindings = Map.fromList [ addCommand "char-at" 2 commandCharAt
, addCommand "index-of" 2 commandIndexOf
, addCommand "substring" 3 commandSubstring
, addCommand "slice" 3 commandSubstring
, addCommand "length" 1 commandStringLength
, addCommand "join" 1 commandStringJoin
, addCommand "directory" 1 commandStringDirectory

View File

@ -105,16 +105,16 @@
"sum works as expected")
(assert-equal test
&[2 3]
&(subarray &(range 1 10 1) 1 3)
"subarray works as expected")
&(slice &(range 1 10 1) 1 3)
"slice works as expected")
(assert-equal test
&[1 2 3]
&(prefix-array &(range 1 10 1) 3)
"prefix-array works as expected")
&(prefix &(range 1 10 1) 3)
"prefix works as expected")
(assert-equal test
&[8 9 10]
&(suffix-array &(range 1 10 1) 7)
"suffix-array works as expected")
&(suffix &(range 1 10 1) 7)
"suffix works as expected")
(assert-equal test
&(Maybe.Nothing)
&(nth &a 100)

View File

@ -181,9 +181,9 @@
(defn if-6 []
(branch-in-let false))
(defn string-substring []
(defn string-slice []
(let [s1 @"abcde"
s2 (String.substring &s1 0 3)]
s2 (String.slice &s1 0 3)]
(assert (= "abc" &s2))))
(defn array-aset []
@ -241,9 +241,9 @@
(let [xs [10 20 30 40 50]]
(assert (= 150 (sum &xs)))))
(defn array-subarray []
(defn array-slice []
(let [xs [@"a" @"b" @"c" @"d" @"e"]]
(assert (= &[@"c" @"d"] &(Array.subarray &xs 2 4)))))
(assert (= &[@"c" @"d"] &(Array.slice &xs 2 4)))))
(defn array-reverse-1 []
(let [xs [@"a" @"b" @"c" @"d" @"e"]]
@ -259,7 +259,7 @@
(assert (= 3 (Array.element-count &xs "a")))))
(defn first-letter [s]
(String.substring s 0 1))
(String.slice s 0 1))
(defn array-aupdate []
(let [xs [@"abc" @"xyz"]
@ -458,7 +458,7 @@
(assert-no-leak test if-4 "if-4 does not leak")
(assert-no-leak test if-5 "if-5 does not leak")
(assert-no-leak test if-6 "if-6 does not leak")
(assert-no-leak test string-substring "string-substring does not leak")
(assert-no-leak test string-slice "string-slice does not leak")
(assert-no-leak test array-aset "array-aset does not leak")
(assert-no-leak test array-reduce "array-reduce does not leak")
(assert-no-leak test array-endo-filter "array-endo-filter does not leak")
@ -470,7 +470,7 @@
(assert-no-leak test array-maximum "array-maximum does not leak")
(assert-no-leak test array-minimum "array-minimum does not leak")
(assert-no-leak test array-sum "array-sum does not leak")
(assert-no-leak test array-subarray "array-subarray does not leak")
(assert-no-leak test array-slice "array-slice does not leak")
(assert-no-leak test array-reverse-1 "array-reverse-2 does not leak")
(assert-no-leak test array-index-of "array-index-of does not leak")
(assert-no-leak test array-element-count "array-element-count does not leak")

View File

@ -84,16 +84,16 @@
"from-chars works as expected")
(assert-equal test
"edan"
&(substring "svedang" 2 6)
"substring works as expected")
&(slice "svedang" 2 6)
"slice works as expected")
(assert-equal test
"sved"
&(prefix-string "svedang" 4)
"prefix-string works as expected")
&(prefix "svedang" 4)
"prefix works as expected")
(assert-equal test
"dang"
&(suffix-string "svedang" 3)
"suffix-string works as expected")
&(suffix "svedang" 3)
"suffix works as expected")
(assert-true test
(ends-with? "heller" "ler")
"ends-with? works as expected")